/* * A checksum error has been encountered. Go to the start of this log file * and read forward until the lower side of the corrupted area has been * found. */ @Override protected boolean resyncReader(long nextGoodRecordPostCorruption, boolean showCorruptedBounds) throws DatabaseException { LastFileReader reader = null; long tryReadBufferFileNum = DbLsn.getFileNumber(nextGoodRecordPostCorruption); while (tryReadBufferFileNum >= 0) { try { reader = new LastFileReader(envImpl, readBufferSize, Long.valueOf(tryReadBufferFileNum)); break; } catch (ChecksumException e) { /* * We encountered a problem opening this file so skip to an * earlier file. */ tryReadBufferFileNum--; continue; } } boolean switchedFiles = tryReadBufferFileNum != DbLsn.getFileNumber(nextGoodRecordPostCorruption); if (!switchedFiles) { /* * Read forward until a checksum fails. This reader will not throw * an exception if a checksum error is hit -- it will just return * false. */ while (reader.readNextEntry()) {} } long lastUsedLsn = reader.getLastValidLsn(); long nextAvailableLsn = reader.getEndOfLog(); if (showCorruptedBounds) { System.err.println("A checksum error was found in the log."); System.err.println("Corruption begins at LSN:\n " + DbLsn.toString(nextAvailableLsn)); System.err.println( "Last known good record before corruption is at LSN:\n " + DbLsn.toString(lastUsedLsn)); System.err.println( "Next known good record after corruption is at LSN:\n " + DbLsn.toString(nextGoodRecordPostCorruption)); } startLsn = lastUsedLsn; initStartingPosition(nextAvailableLsn, null); if (switchedFiles) { currentEntryPrevOffset = 0; } /* Indicate resync is permitted so don't throw exception. */ return true; }
/** * readNextEntry will stop at a bad entry. * * @return true if an element has been read. */ public boolean readNextEntry() throws DatabaseException, IOException { boolean foundEntry = false; try { /* * At this point, * currentEntryOffset is the entry we just read. * nextEntryOffset is the entry we're about to read. * currentEntryPrevOffset is 2 entries ago. * Note that readNextEntry() moves all the offset pointers up. */ foundEntry = super.readNextEntry(); /* * Note that initStartingPosition() makes sure that the file header * entry is valid. So by the time we get to this method, we know * we're at a file with a valid file header entry. */ lastValidOffset = currentEntryOffset; nextUnprovenOffset = nextEntryOffset; } catch (DbChecksumException e) { Tracer.trace( Level.INFO, envImpl, "Found checksum exception while searching " + " for end of log. Last valid entry is at " + DbLsn.toString(DbLsn.makeLsn(readBufferFileNum, lastValidOffset)) + " Bad entry is at " + DbLsn.makeLsn(readBufferFileNum, nextUnprovenOffset)); } return foundEntry; }
/** * readNextEntry will stop at a bad entry. * * @return true if an element has been read. */ @Override public boolean readNextEntry() { boolean foundEntry = false; try { /* * At this point, * currentEntryOffset is the entry we just read. * nextEntryOffset is the entry we're about to read. * currentEntryPrevOffset is 2 entries ago. * Note that readNextEntry() moves all the offset pointers up. */ foundEntry = super.readNextEntryAllowExceptions(); /* * Note that initStartingPosition() makes sure that the file header * entry is valid. So by the time we get to this method, we know * we're at a file with a valid file header entry. */ lastValidOffset = currentEntryOffset; nextUnprovenOffset = nextEntryOffset; } catch (FileNotFoundException e) { throw new EnvironmentFailureException( envImpl, EnvironmentFailureReason.LOG_FILE_NOT_FOUND, e); } catch (ChecksumException e) { LoggerUtils.fine( logger, envImpl, "Found checksum exception while searching for end of log. " + "Last valid entry is at " + DbLsn.toString(DbLsn.makeLsn(window.currentFileNum(), lastValidOffset)) + " Bad entry is at " + DbLsn.makeLsn(window.currentFileNum(), nextUnprovenOffset)); } return foundEntry; }