From: Date: October 21 2008 9:02pm Subject: bzr commit into mysql-6.0-falcon-team branch (olav:2875) Bug#39912 List-Archive: http://lists.mysql.com/commits/56745 X-Bug: 39912 Message-Id: <20081021190212.3301.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-seriallog2/ 2875 Olav Sandstaa 2008-10-21 Bug#39912 Falcon can crash after hitting problems with the serial log Implements handling of previously uncaught exceptions thrown by the serial log after it has gotten into a "writeError" state. The following code has been extended to handle exceptions: -rollback to savepoint -rollback of transactions -commit -commit of implicite transactions -Scavenger updating cardinalities -IO-threads writing the checkpoint record modified: storage/falcon/Cache.cpp storage/falcon/Database.cpp storage/falcon/StorageConnection.cpp storage/falcon/StorageConnection.h storage/falcon/ha_falcon.cpp per-file messages: storage/falcon/Cache.cpp Handle (by ignoring) exception if committing the checkpoint log record fails. storage/falcon/Database.cpp Handle (by ignoring) exception if commit of updates to cardinalites fails. storage/falcon/StorageConnection.cpp Handle exceptions that may occur during commit, rollback to savepoint and rollback of transactions. storage/falcon/StorageConnection.h Extend methods to return error values storage/falcon/ha_falcon.cpp Return error codes to the server when commit, rollback to savepoint, and rollback of transactions fail. === modified file 'storage/falcon/Cache.cpp' === modified file 'storage/falcon/Cache.cpp' --- a/storage/falcon/Cache.cpp 2008-10-02 23:06:04 +0000 +++ b/storage/falcon/Cache.cpp 2008-10-21 19:02:02 +0000 @@ -934,7 +934,15 @@ Log::log(LogInfo, "%d: Cache flush: %d pages, %d writes in %d seconds (%d pps)\n", database->deltaTime, pages, writes, delta, pages / MAX(delta, 1)); - database->pageCacheFlushed(flushArg); + try + { + database->pageCacheFlushed(flushArg); + } + catch (...) + { + // Ignores any errors from writing the checkpoint + // log record (ie. if we have issues with the serial log) + } } else flushLock.unlock(); === modified file 'storage/falcon/Database.cpp' --- a/storage/falcon/Database.cpp 2008-10-16 02:40:08 +0000 +++ b/storage/falcon/Database.cpp 2008-10-21 19:02:02 +0000 @@ -2434,7 +2434,16 @@ syncTbl.unlock(); syncDDL.unlock(); - commitSystemTransaction(); + try + { + commitSystemTransaction(); + } + catch (...) + { + // Ignores any errors from committing the updates of the cardinalities + // Situations where this might happen can be due to problems with + // writing to the serial log + } } void Database::sync() === modified file 'storage/falcon/StorageConnection.cpp' --- a/storage/falcon/StorageConnection.cpp 2008-03-11 16:15:47 +0000 +++ b/storage/falcon/StorageConnection.cpp 2008-10-21 19:02:02 +0000 @@ -133,6 +133,8 @@ int StorageConnection::commit(void) { + int errorCode = 0; + if (connection) { if (traceStream) @@ -142,15 +144,22 @@ traceStream->clear(); } - - connection->commit(); + + try + { + connection->commit(); + } + catch (SQLException& exception) + { + errorCode = translateError(exception, StorageErrorIOErrorSerialLog); + } } transactionActive = false; implicitTransactionCount = 0; verbMark = 0; - return 0; + return errorCode; } int StorageConnection::prepare(int xidLength, const UCHAR *xid) @@ -165,6 +174,8 @@ int StorageConnection::rollback(void) { + int errorCode = 0; + if (connection) { if (traceStream) @@ -174,14 +185,22 @@ traceStream->clear(); } - connection->rollback(); + + try + { + connection->rollback(); + } + catch (SQLException& exception) + { + errorCode = translateError(exception, StorageErrorIOErrorSerialLog); + } } transactionActive = false; implicitTransactionCount = 0; verbMark = 0; - return 0; + return errorCode; } int StorageConnection::startTransaction(int isolationLevel) @@ -321,10 +340,16 @@ return false; } -void StorageConnection::endImplicitTransaction(void) +int StorageConnection::endImplicitTransaction(void) { + int errorCode = 0; + if (implicitTransactionCount > 0 && --implicitTransactionCount == 0) - commit(); + { + errorCode = commit(); + } + + return errorCode; } int StorageConnection::markVerb(void) @@ -339,13 +364,22 @@ return false; } -void StorageConnection::rollbackVerb(void) +int StorageConnection::rollbackVerb(void) { if (verbMark) { - savepointRollback(verbMark); - verbMark = 0; + try + { + savepointRollback(verbMark); + verbMark = 0; + } + catch (SQLException& exception) + { + return translateError(exception, StorageErrorIOErrorSerialLog); + } } + + return 0; } void StorageConnection::releaseVerb(void) @@ -416,3 +450,26 @@ connection->validate(flags); } + +int StorageConnection::translateError(SQLException& exception, int defaultStorageError) +{ + // This method is inspired by the corresponding method in + // StorageTable::translateError. + + int errorCode; + int sqlCode = exception.getSqlcode(); + + switch (sqlCode) + { + case IO_ERROR_SERIALLOG: + errorCode = StorageErrorIOErrorSerialLog; + break; + + default: + errorCode = defaultStorageError; + } + + setErrorText(&exception); + + return errorCode; +} === modified file 'storage/falcon/StorageConnection.h' --- a/storage/falcon/StorageConnection.h 2008-03-11 16:15:47 +0000 +++ b/storage/falcon/StorageConnection.h 2008-10-21 19:02:02 +0000 @@ -54,12 +54,12 @@ virtual int rollback(void); virtual int startTransaction(int isolationLevel); virtual int startImplicitTransaction(int isolationLevel); - virtual void endImplicitTransaction(void); + virtual int endImplicitTransaction(void); virtual int savepointSet(); virtual int savepointRelease(int savePoint); virtual int savepointRollback(int savePoint); virtual int markVerb(); - virtual void rollbackVerb(); + virtual int rollbackVerb(); virtual void releaseVerb(); virtual void addRef(void); virtual void release(void); @@ -81,6 +81,7 @@ void setMySqlThread(THD* thd); void setCurrentStatement(const char* text); Transaction* getTransaction(void); + int translateError(SQLException& exception, int defaultStorageError); Connection *connection; Database *database; === modified file 'storage/falcon/ha_falcon.cpp' --- a/storage/falcon/ha_falcon.cpp 2008-10-16 02:53:35 +0000 +++ b/storage/falcon/ha_falcon.cpp 2008-10-21 19:02:02 +0000 @@ -1198,20 +1198,26 @@ { DBUG_ENTER("StorageInterface::commit"); StorageConnection *storageConnection = getStorageConnection(thd); + int ret = 0; if (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { if (storageConnection) - storageConnection->commit(); + ret = storageConnection->commit(); else - storageHandler->commit(thd); + ret = storageHandler->commit(thd); } else { if (storageConnection) storageConnection->releaseVerb(); else - storageHandler->releaseVerb(thd); + ret = storageHandler->releaseVerb(thd); + } + + if (ret != 0) + { + DBUG_RETURN(getMySqlError(ret)); } DBUG_RETURN(0); @@ -1240,20 +1246,26 @@ { DBUG_ENTER("StorageInterface::rollback"); StorageConnection *storageConnection = getStorageConnection(thd); + int ret = 0; if (all || !thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) { if (storageConnection) - storageConnection->rollback(); + ret = storageConnection->rollback(); else - storageHandler->rollback(thd); + ret = storageHandler->rollback(thd); } else { if (storageConnection) - storageConnection->rollbackVerb(); + ret = storageConnection->rollbackVerb(); else - storageHandler->rollbackVerb(thd); + ret = storageHandler->rollbackVerb(thd); + } + + if (ret != 0) + { + DBUG_RETURN(getMySqlError(ret)); } DBUG_RETURN(0); @@ -1923,10 +1935,12 @@ if (lock_type == F_UNLCK) { + int ret = 0; + storageConnection->setCurrentStatement(NULL); if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) - storageConnection->endImplicitTransaction(); + ret = storageConnection->endImplicitTransaction(); else storageConnection->releaseVerb(); @@ -1935,6 +1949,9 @@ storageTable->clearStatement(); storageTable->clearCurrentIndex(); } + + if (ret) + DBUG_RETURN(error(ret)); } else {