db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mi...@apache.org
Subject svn commit: rev 53832 - incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log
Date Tue, 05 Oct 2004 23:10:16 GMT
Author: mikem
Date: Tue Oct  5 16:10:15 2004
New Revision: 53832

Modified:
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java
   incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/Scan.java
Log:
committed for tsuresh@Source-Zone.org

problem :  In multi-threaded application when lot of threads are executing 
commits in parallel, empty log files might be created. Recovery log scan
does not expect  empty log files while scanning log records to undo incomplete 
transactions..

Fix:
a)  prevent empty log switches by  rechecking the conditions that triggers the 
    log switches inside synchronized blocks.
b)  Make backward scans skip the empty log files.



Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java
(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/LogToFile.java
Tue Oct  5 16:10:15 2004
@@ -1819,24 +1819,12 @@
 		/////////////////////////////////////////////////////
 		synchronized (this)
 		{
-			// 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;
-			}
-
 
 			// 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). 
-			boolean waited = false;
 			while(logBeingFlushed | isFrozen)
 			{
 				try
@@ -1849,6 +1837,17 @@
 				}	
 			}
 
+			// 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);
@@ -3721,11 +3720,14 @@
 		if ((logWrittenFromLastCheckPoint + potentialLastFlush) > checkpointInterval &&
 					checkpointDaemon != null &&	!checkpointDaemonCalled && !inLogSwitch)
 		{
-			//following synchronized block is required to make
-			//sure only one checkpoint request get scheduled.
+			// following synchronized block is required to make 
+			// sure only one checkpoint request get scheduled.
 			synchronized(this)
 			{
-				if(!checkpointDaemonCalled)
+				// recheck if checkpoint is still required, it is possible some other
+				// thread might have already scheduled a checkpoint and completed it. 
+				if ((logWrittenFromLastCheckPoint + potentialLastFlush) > checkpointInterval &&
+					checkpointDaemon != null &&	!checkpointDaemonCalled && !inLogSwitch)
 				{
 					checkpointDaemonCalled = true;
 					checkpointDaemon.serviceNow(myClientNumber);
@@ -3741,11 +3743,14 @@
 			if (potentialLastFlush > logSwitchInterval &&
 				!checkpointDaemonCalled && !inLogSwitch)
 			{
-				//following synchronized block is required
-				//to make sure only one thread switches the log file at a time.
+				// following synchronized block is required to make sure only
+				// one thread switches the log file at a time.
 				synchronized(this)
 				{
-					if(!inLogSwitch)
+					// recheck if log switch is still required, it is possible some other
+					// thread might have already switched the log file. 
+					if (potentialLastFlush > logSwitchInterval &&
+						!checkpointDaemonCalled && !inLogSwitch)
 					{
 						inLogSwitch = true;
 						switchLogFile();

Modified: incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/Scan.java
==============================================================================
--- incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/Scan.java	(original)
+++ incubator/derby/code/trunk/java/engine/org/apache/derby/impl/store/raw/log/Scan.java	Tue
Oct  5 16:10:15 2004
@@ -328,6 +328,14 @@
 				// end of the file header, in other words, there is at least
 				// one log record in this log file.
 				curpos = scan.getFilePointer();
+
+				// if the log file happens to be empty skip and proceed. 
+				// ideally this case should never occur because log switch is
+				// not suppose to happen on an empty log file. 
+				// But it is safer to put following check incase if it ever
+				// happens to avoid any recovery issues. 
+				if (curpos == LogToFile.LOG_FILE_HEADER_SIZE)
+					continue;
 			}
 
 			scan.seek(curpos - 4);

Mime
View raw message