From: Date: October 14 2008 3:00pm Subject: bzr commit into mysql-6.0-falcon-team branch (olav:2863) Bug#39912 List-Archive: http://lists.mysql.com/commits/56178 X-Bug: 39912 Message-Id: <20081014130040.1903.qmail@khepri11> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #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);