#At file:///home/os136802/mysql/develop/repo/falcon-seriallog2/
2877 Olav Sandstaa 2008-10-23
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-23 07:58:38 +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-23 07:58:38 +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-23 07:58:38 +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-23 07:58:38 +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-22 12:01:16 +0000
+++ b/storage/falcon/ha_falcon.cpp 2008-10-23 07:58:38 +0000
@@ -1203,20 +1203,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);
@@ -1245,20 +1251,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);
@@ -1928,10 +1940,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();
@@ -1940,6 +1954,9 @@
storageTable->clearStatement();
storageTable->clearCurrentIndex();
}
+
+ if (ret)
+ DBUG_RETURN(error(ret));
}
else
{
| Thread |
|---|
| • bzr commit into mysql-6.0-falcon-team branch (olav:2877) Bug#39912 | Olav Sandstaa | 23 Oct |