From: Date: November 5 2008 6:59pm Subject: bzr commit into mysql-6.0-falcon-team branch (vvaintroub:2904) Bug#40302 List-Archive: http://lists.mysql.com/commits/57926 X-Bug: 40302 Message-Id: <0K9V005C6GN2F330@fe-emea-09.sun.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7BIT #At file:///G:/bzr/ft2/ 2904 Vladislav Vaintroub 2008-11-05 Bug #40302 error on tablespace creation is not handled cleanly Problem: If tablespace.create() fails, system transaction that updates tablespace info is not rolled back. It can be possibly commited with the next system transaction, that will add a tablespace to system tables even if datafile does not exist. Additionally, createTableSpace log record (indicating creation of datafile) that logically belongs to the same transaction as system tables and has the same transaction id was wrongly written after "commit". With this patch, - there is a rollback in case of error and appropriate cleanup in the filesystem - createTableSpace now belongs to the same transaction that changes system tables. modified: storage/falcon/TableSpaceManager.cpp === modified file 'storage/falcon/TableSpaceManager.cpp' --- a/storage/falcon/TableSpaceManager.cpp 2008-10-31 00:29:13 +0000 +++ b/storage/falcon/TableSpaceManager.cpp 2008-11-05 17:58:43 +0000 @@ -155,7 +155,7 @@ TableSpace* TableSpaceManager::getTableS TableSpace* TableSpaceManager::createTableSpace(const char *name, const char *fileName, bool repository, TableSpaceInit *tsInit) { Sync syncDDL(&database->syncSysDDL, "TableSpaceManager::createTableSpace"); - syncDDL.lock(Shared); + syncDDL.lock(Exclusive); Sequence *sequence = database->sequenceManager->getSequence(database->getSymbol("SYSTEM"), database->getSymbol("TABLESPACE_IDS")); int type = (repository) ? TABLESPACE_TYPE_REPOSITORY : TABLESPACE_TYPE_TABLESPACE; int id = (int) sequence->update(1, database->getSystemTransaction()); @@ -168,26 +168,26 @@ TableSpace* TableSpaceManager::createTab throw SQLError(TABLESPACE_DATAFILE_EXIST_ERROR, "table space file name \"%s\" already exists\n", fileName); } + bool createdFile = false; try { tableSpace->save(); if (!repository) tableSpace->create(); - - syncDDL.unlock(); - database->commitSystemTransaction(); + createdFile = true; add(tableSpace); + database->serialLog->logControl->createTableSpace.append(tableSpace); } catch (...) { + if (createdFile) + IO::deleteFile(fileName); + database->rollbackSystemTransaction(); delete tableSpace; - throw; } - - database->serialLog->logControl->createTableSpace.append(tableSpace); - + database->commitSystemTransaction(); return tableSpace; }