⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
			else // no need to decrypt, only get the group and tid if we filter 			{				if (groupmask == 0 && tranId == null)				{					// no filter, get the whole thing					scan.readFully(data, 0, recordLength);					input.setLimit(0, recordLength);				}				else				{					// Read only enough so that group and the tran id is in					// the data buffer.  Group is stored as compressed int					// and tran id is stored as who knows what.  read min					// of peekAmount or recordLength					readAmount = (recordLength > peekAmount) ?						peekAmount : recordLength; 					// in the data buffer, we now have enough to peek					scan.readFully(data, 0, readAmount);					input.setLimit(0, readAmount);				}			}			lr = (LogRecord) input.readObject();			if (groupmask != 0 || tranId != null)			{				if (groupmask != 0 && (groupmask & lr.group()) == 0)					candidate = false; // no match, throw this log record out 				if (candidate && tranId != null)				{					TransactionId tid = lr.getTransactionId();					if (!tid.equals(tranId)) // nomatch						candidate = false; // throw this log record out				}				// if this log record is not filtered out, we need to read				// in the rest of the log record to the input buffer.				// Except if it is an encrypted database, in which case the				// entire log record have already be read in for				// decryption.				if (candidate && !logFactory.databaseEncrypted())				{					// read the rest of the log into the buffer					if (SanityManager.DEBUG)						SanityManager.ASSERT(readAmount > 0);					if (readAmount < recordLength)					{						// Need to remember where we are because the log						// record may have read part of it off the input						// stream already and that position is lost when we						// set limit again.						int inputPosition = input.getPosition();						scan.readFully(data, readAmount,									   recordLength-readAmount); 						input.setLimit(0, recordLength);						input.setPosition(inputPosition);					}				}			}			/*check if the logrecord length written before and after the 			 *log record are equal, if not the end of of the log is reached.			 *This can happen if system crashed before writing the length field 			 *in the end of the records completely. If the length is partially			 *written or not written at all  it will not match with length written 			 *in the beginning of the log record. Currentlt preallocated files			 *are filled with zeros, log record length can never be zero; 			 *if the lengths are not matching, end of the properly written log			 *is reached.			 *Note: In case of Non-preallocated files earlier fuzzy case check with log			 * file lengths should have found the end. But in prellocated files, log file			 *length is not sufficiant to find the log end. This check 			 *is must to find the end in preallocated log files. 			 */			// read the length after the log record and check it against the			// length before the log record, make sure we go to the correct			// place for skipped log record.			if (!candidate)				scan.seek(recordStartPosition - 4);			int checkLength = scan.readInt();			if (checkLength != recordLength && checkLength < recordLength)			{				//lengh written in the end of the log record should be always				//less then the length written in the beginning if the log				//record was half written before the crash.				if(checkLength < recordLength)				{					fuzzyLogEnd = true ;					return null;				}else				{									//If checklength > recordLength then it can be not be a partial write					//probablly it is corrupted for some reason , this should never					//happen throw error in debug mode. In non debug case , let's					//hope it's only is wrong and system can proceed. 											if (SanityManager.DEBUG)					{							throw logFactory.markCorrupt						(StandardException.newException(							SQLState.LOG_RECORD_CORRUPTED,                             new Long(checkLength),                            new Long(recordLength),                            new Long(currentInstant),                            new Long(currentLogFileNumber)));					}										//In non debug case, do nothing , let's hope it's only					//length part that is incorrect and system can proceed. 				}			}			// next record start position is right after this record			recordStartPosition += recordLength + LogToFile.LOG_RECORD_OVERHEAD;			knownGoodLogEnd = LogCounter.makeLogInstantAsLong								(currentLogFileNumber, recordStartPosition);									if (SanityManager.DEBUG)			{				if (recordStartPosition != scan.getFilePointer())					SanityManager.THROWASSERT(									 "calculated end " + recordStartPosition + 									 " != real end " + scan.getFilePointer());			}			else			{				// seek to the start of the next log record				scan.seek(recordStartPosition);			}			// the scan is now positioned just past this log record and right			// at the beginning of the next log record			/** if the current log record is a checksum log record then			 * using the information available in this record validate			 * that data in the log file by matching the checksum in 			 * checksum log record and by recalculating the checksum for the 			 * specified length of the data in the log file. cheksum values			 * should match unless the right was incomplete before the crash.			 */			if(lr.isChecksum())			{				// checksum log record should not be returned to the logger recovery redo				// routines, it is just used to identify the incomplete log writes.				candidate = false;				Loggable op = lr.getLoggable(); 				if (SanityManager.DEBUG)                {                    if (SanityManager.DEBUG_ON(LogToFile.DUMP_LOG_ONLY) ||                        SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))						SanityManager.DEBUG(LogToFile.DBG_FLAG, 											"scanned " + "Null" + " : " + op + 											" instant = " + 											LogCounter.toDebugString(currentInstant) + 											" logEnd = " +  LogCounter.toDebugString(knownGoodLogEnd));				}				ChecksumOperation clop = (ChecksumOperation) op;				int ckDataLength =  clop.getDataLength(); 				// resize the buffer to be size of checksum data length if required.				if (data.length < ckDataLength)				{					// make a new array of sufficient size and reset the arrary					// in the input stream					data = new byte[ckDataLength];					input.setData(data);					input.setLimit(0, ckDataLength);				}								boolean validChecksum = false;				// check if the expected number of bytes by the checksum log				// record actually exist in the file and then verify if checksum				// is valid to identify any incomplete out of order writes.				if((recordStartPosition + ckDataLength) <= currentLogFileLength)				{					// read the data into the buffer					scan.readFully(data, 0, ckDataLength);					// verify the checksum 					if(clop.isChecksumValid(data, 0 , ckDataLength))						validChecksum = true;				}				if(!validChecksum)				{					// declare that the end of the transaction log is fuzzy, checksum is invalid					// only when the writes are incomplete; this can happen					// only when writes at the end of the log were partially					// written before the crash. 					if (SanityManager.DEBUG)                    {                        if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                        {                            SanityManager.DEBUG(                                LogToFile.DBG_FLAG,                                 "detected fuzzy log end on log file while doing checksum checks " + 								currentLogFileNumber +                                 " checksum record start position " + recordStartPosition +                                 " file length " + currentLogFileLength + 								" checksumDataLength=" + ckDataLength);                        }											}										fuzzyLogEnd = true;					scan.close();					scan = null;					return null;				}				// reset the scan to the start of the next log record				scan.seek(recordStartPosition);			}		} while (candidate == false) ;		return lr;	}	/**		Reset the scan to the given LogInstant.		@param instant the position to reset to		@exception IOException scan cannot access the log at the new position.		@exception StandardException cloudscape standard error policy	*/	public void resetPosition(LogInstant instant) 		 throws IOException, StandardException	{		if (SanityManager.DEBUG)			SanityManager.ASSERT(instant != null);		long instant_long = ((LogCounter)instant).getValueAsLong();		if ((instant_long == LogCounter.INVALID_LOG_INSTANT) ||			(stopAt != LogCounter.INVALID_LOG_INSTANT &&			 (scanDirection == FORWARD && instant_long > stopAt) ||			 (scanDirection == FORWARD && instant_long < stopAt)))		{			close();			throw StandardException.newException(                    SQLState.LOG_RESET_BEYOND_SCAN_LIMIT,                     instant, new LogCounter(stopAt));		}		else		{			long fnum = ((LogCounter)instant).getLogFileNumber();			if (fnum != currentLogFileNumber)			{				if (SanityManager.DEBUG)                 {                    if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                    {                        SanityManager.DEBUG(LogToFile.DBG_FLAG, 										"Scan " + scanDirection +										" resetting to " + instant + 										" need to switch log from " + 										currentLogFileNumber + " to " + fnum);                    }				}				scan.close();				scan = logFactory.getLogFileAtPosition(instant_long);				currentLogFileNumber= fnum;				if (scanDirection == FORWARD)				{					// NOTE: 					//					// just get the length of the file without syncing.					// this only works because the only place forward scan is used					// right now is on recovery redo and nothing is being added to 					// the current log file.  When the forward scan is used for some					// other purpose, need to sync access to the end of the log					//					currentLogFileLength = scan.length();				}			}			else			{				long fpos = ((LogCounter)instant).getLogFilePosition();				scan.seek(fpos);				//				//RESOLVE: Can this be optimized? Does it belong here.				currentLogFileLength = scan.length();				if (SanityManager.DEBUG)                {                    if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                    {                        SanityManager.DEBUG(LogToFile.DBG_FLAG, 										"Scan reset to " + instant);                    }				}			}			currentInstant = instant_long;			//scan is being reset, it is possibly that, scan is doing a random 			//access of the log file. set the knownGoodLogEnd to  the instant			//scan 	is being reset to.			//Note: reset gets called with undo forward scan for CLR processing during 			//recovery, if this value is not reset checks to find the end of log 			//getNextRecordForward() will fail because undoscan scans log file			//back & forth to redo CLR's.			knownGoodLogEnd = currentInstant;			if (SanityManager.DEBUG)            {                if (SanityManager.DEBUG_ON(LogToFile.DBG_FLAG))                {                    SanityManager.DEBUG(LogToFile.DBG_FLAG,                         "Scan.getInstant reset to " + currentInstant +                         LogCounter.toDebugString(currentInstant));                }			}		}	}	/**		Return the log instant (as an integer) the scan is currently on - this is the log		instant of the log record that was returned by getNextRecord.	*/	public long getInstant()	{		return currentInstant;	}	/**		Return the log instant at the end of the log record on the current		LogFile in the form of a log instant	*/	public long getLogRecordEnd()	{		return knownGoodLogEnd;	}	/**	   returns true if there is partially writen log records before the crash 	   in the last log file. Partiall wrires are identified during forward 	   redo scans for log recovery.	*/	public boolean isLogEndFuzzy()	{		return fuzzyLogEnd;	}	/**		Return the log instant the scan is currently on - this is the log		instant of the log record that was returned by getNextRecord.	*/	public LogInstant getLogInstant()	{		if (currentInstant == LogCounter.INVALID_LOG_INSTANT)			return null;		else			return new LogCounter(currentInstant);	}	/**		Close the scan.	*/	public void close()	{		if (scan != null)		{			try 			{				scan.close();			}			catch (IOException ioe)			{}			scan = null;		}		logFactory = null;		currentLogFileNumber = -1;		currentLogFileLength = -1;		knownGoodLogEnd = LogCounter.INVALID_LOG_INSTANT;		currentInstant = LogCounter.INVALID_LOG_INSTANT;		stopAt = LogCounter.INVALID_LOG_INSTANT;		scanDirection = 0;	}}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -