Olav,
To my knowledge, and after discussing briefly with you, this patch
looks good.
There is however some un-falcony whitespace placement in here ;)
Given that this is no problem (is it?), the patch is OK to push!
/Lars-Erik
On Oct 14, 2008, at 3:00 PM, Olav Sandstaa wrote:
> #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);
>
>
> --
> MySQL Code Commits Mailing List
> For list archives: http://lists.mysql.com/commits
> To unsubscribe: http://lists.mysql.com/commits?unsub=1
>