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

📄 logtofile.java

📁 derby database source code.good for you.
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	/**		Flush all unwritten log record to disk and sync.		Also check to see if database is frozen or corrupt.		<P>MT - not needed, wrapper method		@exception StandardException Standard Cloudscape error policy	*/	public void flushAll() throws StandardException	{		long fnum;		long whereTo;		synchronized(this)		{			fnum = logFileNumber;			whereTo = endPosition;		}		flush(fnum, whereTo);	}	/*	 * Private methods that helps to implement methods of LogFactory	 */	/**		Verify that we the log file is of the right format and of the right		version and log file number.		<P>MT - not needed, no global variables used		@param logFileName the name of the log file		@param number the log file number		@return true if the log file is of the current version and of the		correct format		@exception StandardException Standard Cloudscape error policy	*/	private boolean verifyLogFormat(StorageFile logFileName, long number)		 throws StandardException 	{		boolean ret = false;		try 		{			StorageRandomAccessFile log = privRandomAccessFile(logFileName, "r");			ret = verifyLogFormat(log, number);			log.close();		}		catch (IOException ioe)		{					}		return ret;	}	/**		Verify that we the log file is of the right format and of the right		version and log file number.  The log file position is set to the		beginning.		<P>MT - MT-unsafe, caller must synchronize		@param log the log file		@param number the log file number		@return true if the log file is of the current version and of the		correct format		@exception StandardException Standard Cloudscape error policy	*/	private boolean verifyLogFormat(StorageRandomAccessFile log, long number) 		 throws StandardException	{		try 		{			log.seek(0);			int logfid = log.readInt();			int obsoleteLogVersion = log.readInt(); // this value is useless, for								// backwards compatibility			long logNumber = log.readLong();			if (logfid != fid || logNumber != number)            {				throw StandardException.newException(                        SQLState.LOG_INCOMPATIBLE_FORMAT, dataDirectory);            }		}		catch (IOException ioe)		{			throw StandardException.newException(                    SQLState.LOG_CANNOT_VERIFY_LOG_FORMAT, ioe, dataDirectory);		}		return true;	}	/**		Initialize the log to the correct format with the given version and		log file number.  The new log file must be empty.  After initializing,		the file is synchronously written to disk.		<P>MT - synchornization provided by caller		@param newlog the new log file to be initialized		@param number the log file number		@param prevLogRecordEndInstant the end position of the  previous log record		@return true if the log file is empty, else false.		@exception IOException if new log file cannot be accessed or initialized	*/	private boolean initLogFile(StorageRandomAccessFile newlog, long number,								long prevLogRecordEndInstant)		 throws IOException, StandardException	{		if (newlog.length() != 0)			return false;		if (SanityManager.DEBUG)		{			if ( SanityManager.DEBUG_ON(TEST_LOG_FULL))				testLogFull();		}		if (SanityManager.DEBUG)		{			if (SanityManager.DEBUG_ON(TEST_SWITCH_LOG_FAIL1))				throw new IOException("TestLogSwitchFail1");		}		newlog.seek(0);		newlog.writeInt(fid);		newlog.writeInt(OBSOLETE_LOG_VERSION_NUMBER); // for silly backwards compatibility reason		newlog.writeLong(number);		newlog.writeLong(prevLogRecordEndInstant);		syncFile(newlog);		return true;	}	/**		Switch to the next log file if possible.		<P>MT - log factory is single threaded thru a log file switch, the log		is frozen for the duration of the switch	*/	private void switchLogFile() throws StandardException	{		boolean switchedOver = false;		/////////////////////////////////////////////////////		// Freeze the log for the switch over to a new log file.		// This blocks out any other threads from sending log		// record to the log stream.		// 		// The switching of the log file and checkpoint are really		// independent events, they are tied together just because a		// checkpoint is the natural place to switch the log and vice		// versa.  This could happen before the cache is flushed or		// after the checkpoint log record is written.		/////////////////////////////////////////////////////		synchronized (this)		{			// Make sure that this thread of control is guaranteed to complete            // it's work of switching the log file without having to give up            // the semaphore to a backup or another flusher.  Do this by looping            // until we have the semaphore, the log is not being flushed, and            // the log is not frozen for backup.  Track (2985). 			while(logBeingFlushed | isFrozen)			{				try				{					wait();				}				catch (InterruptedException ie)				{					throw StandardException.interrupt(ie);				}				}			// we have an empty log file here, refuse to switch.			if (endPosition == LOG_FILE_HEADER_SIZE)			{				if (SanityManager.DEBUG)				{					Monitor.logMessage("not switching from an empty log file (" +						   logFileNumber + ")");				}					return;			}			// log file isn't being flushed right now and logOut is not being			// used.			StorageFile newLogFile = getLogFileName(logFileNumber+1);			if (logFileNumber+1 >= maxLogFileNumber)            {				throw StandardException.newException(                        SQLState.LOG_EXCEED_MAX_LOG_FILE_NUMBER,                         new Long(maxLogFileNumber));             }			StorageRandomAccessFile newLog = null;	// the new log file			try 			{				// if the log file exist and cannot be deleted, cannot				// switch log right now                if (privExists(newLogFile) && !privDelete(newLogFile))				{					logErrMsg(MessageService.getTextMessage(                        MessageId.LOG_NEW_LOGFILE_EXIST,					    newLogFile.getPath()));					return;				}				try				{                    newLog =   privRandomAccessFile(newLogFile, "rw");				}				catch (IOException ioe)				{					newLog = null;				}                if (newLog == null || !privCanWrite(newLogFile))				{					if (newLog != null)						newLog.close();					newLog = null;					return;				}				if (initLogFile(newLog, logFileNumber+1,								LogCounter.makeLogInstantAsLong(logFileNumber, endPosition)))				{					// New log file init ok, close the old one and					// switch over, after this point, need to shutdown the					// database if any error crops up					switchedOver = true;					// write out an extra 0 at the end to mark the end of the log					// file.										logOut.writeEndMarker(0);					endPosition += 4;					//set that we are in log switch to prevent flusher 					//not requesting  to switch log again 					inLogSwitch = true; 					// flush everything including the int we just wrote					flush(logFileNumber, endPosition);															// simulate out of log error after the switch over					if (SanityManager.DEBUG)					{						if (SanityManager.DEBUG_ON(TEST_SWITCH_LOG_FAIL2))							throw new IOException("TestLogSwitchFail2");					}					logOut.close();		// close the old log file										logWrittenFromLastCheckPoint += endPosition;					endPosition = newLog.getFilePointer();					lastFlush = endPosition;										if(isWriteSynced)					{						//extend the file by wring zeros to it						preAllocateNewLogFile(newLog);						newLog.close();						newLog = openLogFileInWriteMode(newLogFile);						newLog.seek(endPosition);					}					logOut = new LogAccessFile(this, newLog, logBufferSize);					newLog = null;					if (SanityManager.DEBUG)					{						if (endPosition != LOG_FILE_HEADER_SIZE)							SanityManager.THROWASSERT(											"new log file has unexpected size" +											 + endPosition);					}					logFileNumber++;					if (SanityManager.DEBUG)					{						SanityManager.ASSERT(endPosition == LOG_FILE_HEADER_SIZE,											 "empty log file has wrong size");					}				}				else	// something went wrong, delete the half baked file				{					newLog.close();					newLog = null;					if (privExists(newLogFile))					    privDelete(newLogFile);					newLogFile = null;					logErrMsg(MessageService.getTextMessage(                        MessageId.LOG_CANNOT_CREATE_NEW,                        newLogFile.getPath())); 				}			}			catch (IOException ioe)			{				inLogSwitch = false;				// switching log file is an optional operation and there is no direct user				// control.  Just sends a warning message to whomever, if any,				// system adminstrator there may be                logErrMsg(MessageService.getTextMessage(                    MessageId.LOG_CANNOT_CREATE_NEW_DUETO,                    newLogFile.getPath(),                    ioe.toString()));				try				{					if (newLog != null)					{						newLog.close();						newLog = null;					}				}				catch (IOException ioe2) {}                if (newLogFile != null && privExists(newLogFile))				{                    privDelete(newLogFile);					newLogFile = null;				}				if (switchedOver)	// error occur after old log file has been closed!				{					logOut = null; // limit any damage					throw markCorrupt(                        StandardException.newException(                                SQLState.LOG_IO_ERROR, ioe));				}			}						inLogSwitch = false;		}		// unfreezes the log	}	/**		Flush all unwritten log record up to the log instance indicated to disk		without syncing.		<P>MT - not needed, wrapper method		@param wherePosition flush log up to here		@exception IOException Failed to flush to the log	*/	private void flushBuffer(long fileNumber, long wherePosition)		throws IOException, StandardException	{		synchronized (this) {			if (fileNumber < logFileNumber)	// history				return;			// A log instant indicates the start of a log record			// but not how long it is. Thus the amount of data in			// the logOut buffer is irrelevant. We can only			// not flush the buffer if the real synced flush			// included this required log instant. This is because			// we never flush & sync partial log records.			if (wherePosition < lastFlush) // already flushed				return;			// We don't update lastFlush here because lastFlush			// is the last position in the log file that has been			// flushed *and* synced to disk. Here we only flush.			// ie. lastFlush should be renamed lastSync.			//			// We could have another variable indicating to which			// point the log has been flushed which this routine			// could take advantage of. This would only help rollbacks though.			logOut.flushLogAccessFile();		}	}	/** Get rid of old and unnecessary log files		<P> MT- only one truncate log is allowed to be taking place at any		given time.  Sy

⌨️ 快捷键说明

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