#At file:///home/os136802/mysql/develop/repo/falcon-seriallog/
2863 Olav Sandstaa 2008-10-14
Partial fix for Bug#39912 Falcon can crash after hitting problems with the serial
log
Implements the following improvements when we have problems that prevent Falcon from
writing to the
serial log:
-introduces new exception: IO_ERROR_SERIALLOG to make it possible to distinguish IO
errors on the
serial log file from IO errors on the datafile
-writes an error message to the error log file when the serial log becomes
impossible to write to
-returns HA_ERR_LOGGING_IMPOSSIBLE to the server when insert/update operations fails
due to the
serial log is in state writeError
modified:
storage/falcon/SQLException.h
storage/falcon/SerialLog.cpp
storage/falcon/SerialLog.h
storage/falcon/SerialLogFile.cpp
storage/falcon/SerialLogWindow.cpp
storage/falcon/StorageTable.cpp
storage/falcon/StorageTableShare.h
storage/falcon/ha_falcon.cpp
per-file messages:
storage/falcon/SQLException.h
New Exception type for IO errors related to the serial log
storage/falcon/SerialLog.cpp
Writes error message to MySQL's error log when setting the state of the serial log to
writeError.
storage/falcon/SerialLog.h
Added method for writing to error log when setting the state of the serial log to
writeError.
storage/falcon/SerialLogFile.cpp
Replaced the general IO_ERROR exception with the new serial log specific
IO_ERROR_SERIALLOG exception
storage/falcon/SerialLogWindow.cpp
Replaced the general IO_ERROR exception with the new serial log specific
IO_ERROR_SERIALLOG exception
storage/falcon/StorageTable.cpp
Return new serial log error code if the exception is IO_ERROR_SERIALLOG.
storage/falcon/StorageTableShare.h
New error status for IO errors on the serial log (corresponds to IO_ERROR_SERIALLOG
exception)
storage/falcon/ha_falcon.cpp
Return HA_ERR_LOGGING_IMPOSSIBLE when the error is related to writing on the serial
log.
=== modified file 'storage/falcon/SQLException.h'
=== modified file 'storage/falcon/SQLException.h'
--- a/storage/falcon/SQLException.h 2008-09-11 10:56:00 +0000
+++ b/storage/falcon/SQLException.h 2008-10-14 13:00:31 +0000
@@ -71,7 +71,8 @@
FILE_ACCESS_ERROR = -37,
TABLESPACE_DATAFILE_EXIST_ERROR = -38,
RECOVERY_ERROR = -39,
- OPEN_MASTER_ERROR = -40
+ OPEN_MASTER_ERROR = -40,
+ IO_ERROR_SERIALLOG = -41
};
class DllExport SQLException {
=== modified file 'storage/falcon/SerialLog.cpp'
--- a/storage/falcon/SerialLog.cpp 2008-09-03 22:17:54 +0000
+++ b/storage/falcon/SerialLog.cpp 2008-10-14 13:00:31 +0000
@@ -445,9 +445,9 @@
flushWindow->write(flushBlock);
lastBlockWritten = flushBlock->blockNumber;
}
- catch (...)
+ catch (SQLException& exception)
{
- writeError = true;
+ setWriteError(exception.getSqlcode(), exception.getText());
mutex.unlock();
throw;
}
@@ -547,15 +547,15 @@
mutex.lock();
syncPtr->unlock();
//Log::debug("Flushing log block %d, read block %d\n", (int) flushBlock->blockNumber,
(int) flushBlock->readBlockNumber);
-
+
try
{
flushWindow->write(flushBlock);
lastBlockWritten = flushBlock->blockNumber;
}
- catch (...)
+ catch (SQLException& exception)
{
- writeError = true;
+ setWriteError(exception.getSqlcode(), exception.getText());
mutex.unlock();
throw;
}
@@ -706,7 +706,7 @@
ASSERT(!recovering);
if (writeError)
- throw SQLError(IO_ERROR, "Previous I/O error on serial log prevents further
processing");
+ throw SQLError(IO_ERROR_SERIALLOG, "Previous I/O error on serial log prevents further
processing");
if (writePtr == writeBlock->data)
putVersion();
@@ -1587,3 +1587,23 @@
return window;
}
+
+
+void SerialLog::setWriteError(int sqlCode, const char* errorText)
+{
+ // Logs an error message to the error log and sets the status of the
+ // serial log to "writeError"
+
+ char msgBuf[1024];
+
+ if (!errorText)
+ {
+ errorText = "Not provided";
+ }
+
+ sprintf(msgBuf, "SerialLog: Error during writing to serial log. Cause: %s
(sqlcode=%d)\n",
+ errorText, sqlCode);
+ Log::log(msgBuf);
+
+ writeError = true;
+}
=== modified file 'storage/falcon/SerialLog.h'
--- a/storage/falcon/SerialLog.h 2008-09-03 22:17:54 +0000
+++ b/storage/falcon/SerialLog.h 2008-10-14 13:00:31 +0000
@@ -154,6 +154,7 @@
void blockUpdates(void);
int getBlockSize(void);
SerialLogWindow* setWindowInterest(void);
+ void setWriteError(int sqlCode, const char* errorText);
TableSpaceManager *tableSpaceManager;
SerialLogFile *file1;
=== modified file 'storage/falcon/SerialLogFile.cpp'
--- a/storage/falcon/SerialLogFile.cpp 2008-10-09 14:07:09 +0000
+++ b/storage/falcon/SerialLogFile.cpp 2008-10-14 13:00:31 +0000
@@ -107,7 +107,7 @@
0);
if (handle == INVALID_HANDLE_VALUE)
- throw SQLError(IO_ERROR, "can't open serial log file \"%s\", error code %d", (const
char*) pathName, GetLastError());
+ throw SQLError(IO_ERROR_SERIALLOG, "can't open serial log file \"%s\", error code %d",
(const char*) pathName, GetLastError());
fileName = pathName;
char *p = strchr(pathName, '\\');
@@ -121,7 +121,7 @@
DWORD numberClusters;
if (!GetDiskFreeSpace(pathName, §orsPerCluster, &bytesPerSector,
&numberFreeClusters, &numberClusters))
- throw SQLError(IO_ERROR, "GetDiskFreeSpace failed for \"%s\"", (const char*) pathName);
+ throw SQLError(IO_ERROR_SERIALLOG, "GetDiskFreeSpace failed for \"%s\"", (const char*)
pathName);
sectorSize = MAX(bytesPerSector, database->serialLogBlockSize);
#else
@@ -134,7 +134,7 @@
if (handle <= 0)
- throw SQLEXCEPTION (IO_ERROR, "can't open file \"%s\": %s (%d)",
+ throw SQLEXCEPTION (IO_ERROR_SERIALLOG, "can't open file \"%s\": %s (%d)",
(const char*) filename, strerror (errno), errno);
IO::setWriteFlags(handle, &forceFsync);
@@ -176,7 +176,7 @@
Priority priority(database->ioScheduler);
if (!(position == writePoint || position == 0 || writePoint == 0))
- throw SQLError(IO_ERROR, "serial log left in inconsistent state");
+ throw SQLError(IO_ERROR_SERIALLOG, "serial log left in inconsistent state");
if (falcon_serial_log_priority)
priority.schedule(PRIORITY_HIGH);
@@ -197,7 +197,7 @@
if (lastError == ERROR_HANDLE_DISK_FULL)
throw SQLError(DEVICE_FULL, "device full error on serial log file %s\n", (const char*)
fileName);
- throw SQLError(IO_ERROR, "serial log WriteFile failed with %d", lastError);
+ throw SQLError(IO_ERROR_SERIALLOG, "serial log WriteFile failed with %d", lastError);
}
#else
@@ -213,7 +213,7 @@
off_t loc = lseek(handle, position, SEEK_SET);
if (loc != position)
- throw SQLEXCEPTION (IO_ERROR, "serial lseek error on \"%s\": %s (%d)",
+ throw SQLEXCEPTION (IO_ERROR_SERIALLOG, "serial lseek error on \"%s\": %s (%d)",
(const char*) fileName, strerror (errno), errno);
}
@@ -229,7 +229,7 @@
if (errno == ENOSPC)
throw SQLError(DEVICE_FULL, "device full error on serial log file %s\n", (const char*)
fileName);
- throw SQLEXCEPTION (IO_ERROR, "serial write error on \"%s\": %s (%d)",
+ throw SQLEXCEPTION (IO_ERROR_SERIALLOG, "serial write error on \"%s\": %s (%d)",
(const char*) fileName, strerror (errno), errno);
}
#endif
@@ -269,7 +269,7 @@
{
DWORD lastError = GetLastError();
if(lastError != ERROR_HANDLE_EOF)
- throw SQLError(IO_ERROR, "serial log ReadFile failed with %d",
+ throw SQLError(IO_ERROR_SERIALLOG, "serial log ReadFile failed with %d",
GetLastError());
else
n = 0; // reached end of file
@@ -291,14 +291,14 @@
off_t loc = lseek(handle, position, SEEK_SET);
if (loc != position)
- throw SQLEXCEPTION (IO_ERROR, "serial lseek error on \"%s\": %s (%d)",
+ throw SQLEXCEPTION (IO_ERROR_SERIALLOG, "serial lseek error on \"%s\": %s (%d)",
(const char*) fileName, strerror (errno), errno);
int n = ::read(handle, data, effectiveLength);
#endif
if (n < 0)
- throw SQLEXCEPTION (IO_ERROR, "serial read error on \"%s\": %s (%d)",
+ throw SQLEXCEPTION (IO_ERROR_SERIALLOG, "serial read error on \"%s\": %s (%d)",
(const char*) fileName, strerror (errno), errno);
offset = position + n;
@@ -316,27 +316,27 @@
// Get current position in file
if (!SetFilePointerEx(handle, distance ,&oldPos,FILE_CURRENT))
- throw SQLError(IO_ERROR, "SetFilePointerEx failed with %d",
+ throw SQLError(IO_ERROR_SERIALLOG, "SetFilePointerEx failed with %d",
GetLastError());
// Position to the new end of file , set EOF marker there
distance.QuadPart = size;
if (!SetFilePointerEx(handle, distance, 0, FILE_BEGIN))
- throw SQLError(IO_ERROR, "SetFilePointerEx failed with %d",
+ throw SQLError(IO_ERROR_SERIALLOG, "SetFilePointerEx failed with %d",
GetLastError());
if (!SetEndOfFile(handle))
- throw SQLError(IO_ERROR, "SetEndOfFile failed with %d",
+ throw SQLError(IO_ERROR_SERIALLOG, "SetEndOfFile failed with %d",
GetLastError());
// Restore file pointer
if (!SetFilePointerEx(handle, oldPos ,0,FILE_BEGIN))
- throw SQLError(IO_ERROR, "SetFilePointerEx failed with %d",
+ throw SQLError(IO_ERROR_SERIALLOG, "SetFilePointerEx failed with %d",
GetLastError());
#else
if (ftruncate(handle, size))
- throw SQLError(IO_ERROR, "ftruncate failed with %d",
+ throw SQLError(IO_ERROR_SERIALLOG, "ftruncate failed with %d",
errno);
#endif
}
@@ -347,14 +347,14 @@
LARGE_INTEGER size;
if (!GetFileSizeEx(handle, &size))
- throw SQLError(IO_ERROR, "GetFileSizeEx failed with %u",
+ throw SQLError(IO_ERROR_SERIALLOG, "GetFileSizeEx failed with %u",
GetLastError());
return size.QuadPart;
#else
struct stat buf;
if (fstat(handle, &buf))
- throw SQLError(IO_ERROR, "stat failed with %d",
+ throw SQLError(IO_ERROR_SERIALLOG, "stat failed with %d",
errno);
return buf.st_size;
#endif
=== modified file 'storage/falcon/SerialLogWindow.cpp'
--- a/storage/falcon/SerialLogWindow.cpp 2008-10-02 09:01:39 +0000
+++ b/storage/falcon/SerialLogWindow.cpp 2008-10-14 13:00:31 +0000
@@ -99,7 +99,7 @@
uint32 len = file->read(origin + sectorSize, block->length - sectorSize, buffer +
sectorSize);
if (len != length)
- throw SQLError(IO_ERROR, "truncated log file \"%s\"", (const char*)
file->fileName);
+ throw SQLError(IO_ERROR_SERIALLOG, "truncated log file \"%s\"", (const char*)
file->fileName);
currentLength += length;
}
=== modified file 'storage/falcon/StorageTable.cpp'
--- a/storage/falcon/StorageTable.cpp 2008-09-09 23:15:17 +0000
+++ b/storage/falcon/StorageTable.cpp 2008-10-14 13:00:31 +0000
@@ -550,6 +550,10 @@
errorCode = StorageErrorDeviceFull;
break;
+ case IO_ERROR_SERIALLOG:
+ errorCode = StorageErrorIOErrorSerialLog;
+ break;
+
default:
errorCode = defaultStorageError;
}
=== modified file 'storage/falcon/StorageTableShare.h'
--- a/storage/falcon/StorageTableShare.h 2008-09-10 04:02:07 +0000
+++ b/storage/falcon/StorageTableShare.h 2008-10-14 13:00:31 +0000
@@ -96,7 +96,8 @@
StorageErrorTableNotEmpty = -108,
StorageErrorTableSpaceNotExist = -109,
StorageErrorDeviceFull = -110,
- StorageErrorTableSpaceDataFileExist = -111
+ StorageErrorTableSpaceDataFileExist = -111,
+ StorageErrorIOErrorSerialLog = -112
};
static const int StoreErrorIndexShift = 10;
=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp 2008-10-03 05:15:40 +0000
+++ b/storage/falcon/ha_falcon.cpp 2008-10-14 13:00:31 +0000
@@ -1887,6 +1887,10 @@
DBUG_PRINT("info", ("StorageErrorTableSpaceDataFileExist"));
return (HA_ERR_TABLESPACE_DATAFILE_EXIST);
+ case StorageErrorIOErrorSerialLog:
+ DBUG_PRINT("info", ("StorageErrorIOErrorSerialLog"));
+ return (HA_ERR_LOGGING_IMPOSSIBLE);
+
default:
DBUG_PRINT("info", ("Unknown Falcon Error"));
return (200 - storageError);