OK to push.
>-----Original Message-----
>From: Vladislav Vaintroub [mailto:vvaintroub@stripped]
>Sent: Thursday, July 17, 2008 3:39 PM
>To: commits@stripped
>Subject: bzr commit into mysql-6.0-falcon branch (vvaintroub:2752)
Bug#38186
>
>#At file:///C:/bzr/mysql-6.0-falcon/
>
> 2752 Vladislav Vaintroub 2008-07-17
> Bug#38186 : CREATE TABLESPACE fails sometimes if called directly
after
> DROP TABLESPACE on the same file
>
> The problem is that tablespace files are not deleted directly on
>client COMMIT.
> Deletion is done later, by background(Gopher) thread. Thus the file
>may still
> exist when "create tablespace" is called.
>
> The solution is to to modify CREATE TABLESPACE and if the file is
>there and
> there are pending DROP operation, wait for some seconds until the
>file is deleted.
>
> An attempt to solve this problem was done previously, but waiting for
>deletion
> was put on the wrong place. Client thread was waiting for gopher in
> TablespaceManager::dropTablespace, which can caused a "soft-
>deadlock" :
> - Client thread was holding syncSysDDL lock and was waiting for
Gopher
> to delete file
> - Gopher did not run, was stuck in thread->sleep and waited for
>Scheduler
> to wakeup
> - Scheduler was doing scavenge and was stuck waiting for syncSysDDL
>lock
> in Database:updateCardinalities()
>
> This soft-deadlock was resolved after 10 seconds, client gave up and
> returned with "tablespace file already exists".
>
> The refinement to this solution is given here . Client waits for
> file to be deleted in StorageHandler::createTablespace while no
Falcon
>locks
> are held. Thus the soft-deadlock described is not possible with this
>solution
>renamed:
> mysql-test/suite/falcon_team/r/falcon_bug_31295.result => mysql-
>test/suite/falcon/r/falcon_bug_31295.result
> mysql-test/suite/falcon_team/t/falcon_bug_31295.test => mysql-
>test/suite/falcon/t/falcon_bug_31295.test
>modified:
> storage/falcon/IOx.h
> storage/falcon/StorageHandler.cpp
> storage/falcon/TableSpaceManager.cpp
> storage/falcon/TableSpaceManager.h
>
>=== renamed file 'mysql-test/suite/falcon_team/r/falcon_bug_31295.result'
=>
>'mysql-test/suite/falcon/r/falcon_bug_31295.result'
>=== renamed file 'mysql-test/suite/falcon_team/t/falcon_bug_31295.test' =>
>'mysql-test/suite/falcon/t/falcon_bug_31295.test'
>=== modified file 'storage/falcon/IOx.h'
>--- a/storage/falcon/IOx.h 2008-07-07 14:00:45 +0000
>+++ b/storage/falcon/IOx.h 2008-07-17 20:38:45 +0000
>@@ -54,8 +54,8 @@ public:
> void writeHeader (Hdr *header);
> int read(int length, UCHAR *buffer);
> void write(uint32 length, const UCHAR *data);
>- bool doesFileExist(const char *fileName);
>- int fileStat(const char *fileName, struct stat *stats =
NULL,
>int *errnum = NULL);
>+ static bool doesFileExist(const char *fileName);
>+ static int fileStat(const char *fileName, struct stat *stats =
NULL,
>int *errnum = NULL);
> void declareFatalError();
> void seek (int pageNumber);
> void closeFile();
>
>=== modified file 'storage/falcon/StorageHandler.cpp'
>--- a/storage/falcon/StorageHandler.cpp 2008-07-15 18:57:27 +0000
>+++ b/storage/falcon/StorageHandler.cpp 2008-07-17 20:38:45 +0000
>@@ -35,6 +35,10 @@
> #include "InfoTable.h"
> #include "CmdGen.h"
> #include "Dbb.h"
>+#include "Database.h"
>+#include "TableSpaceManager.h"
>+
>+
>
> #define DICTIONARY_ACCOUNT "mysql"
> #define DICTIONARY_PW "mysql"
>@@ -493,10 +497,16 @@ int StorageHandler::createTablespace(con
>
> if (!dictionaryConnection)
> return StorageErrorTablesSpaceOperationFailed;
>-
>- //StorageDatabase *storageDatabase = NULL;
>+
> JString tableSpace = JString::upcase(tableSpaceName);
>-
>+
>+ TableSpaceManager *tableSpaceManager =
>+ dictionaryConnection->database->tableSpaceManager;
>+
>+ if (!tableSpaceManager->waitForPendingDrop(tableSpaceName, 10))
>+ // file still exists after waiting for 10 seconds
>+ return StorageErrorTableSpaceExist;
>+
> try
> {
> JString cmd = genCreateTableSpace(tableSpaceName, filename,
>initialSize, extentSize,
>
>=== modified file 'storage/falcon/TableSpaceManager.cpp'
>--- a/storage/falcon/TableSpaceManager.cpp 2008-07-15 18:57:27 +0000
>+++ b/storage/falcon/TableSpaceManager.cpp 2008-07-17 20:38:45 +0000
>@@ -170,32 +170,10 @@ TableSpace* TableSpaceManager::createTab
>
> TableSpace *tableSpace = new TableSpace(database, name, id,
fileName,
>type, tsInit);
>
>- if (!repository)
>+ if (!repository && IO::doesFileExist(fileName))
> {
>- bool fileExists;
>-
>- // Check if table space file already exists.
>- // Take into account, that tablespace might have been
already
>dropped
>- // by another transaction, yet file can still be present on
the
>disk,
>- // if log record is not yet fully committed by the gopher
>thread).
>- // So we'll wait for a few seconds if there are pending
drops
>and
>- // tablespace file exists.
>-
>- for (int i=0; i < 10; i++)
>- {
>- fileExists =
tableSpace->dbb->doesFileExist(fileName);
>-
>- if (fileExists && pendingDrops > 0)
>-
>
Thread::getThread("TableSpaceManager::createTableSpace")->sleep(1000);
>- else
>- break;
>- }
>-
>- if (fileExists)
>- {
>- delete tableSpace;
>- throw SQLError(TABLESPACE_DATAFILE_EXIST_ERROR,
"table
>space file name \"%s\" already exists\n", fileName);
>- }
>+ delete tableSpace;
>+ throw SQLError(TABLESPACE_DATAFILE_EXIST_ERROR, "table space
>file name \"%s\" already exists\n", fileName);
> }
>
> try
>@@ -541,4 +519,26 @@ void TableSpaceManager::getTableSpaceFil
> }
> }
>
>+
>+// Wait for specified amount of time for a file to be deleted.
>+// Don't wait if pendingDrops count is 0.
>+//
>+// The function returns true, if wait was successfull, i.e file does not
>exist
>+//(anymore)
>+bool TableSpaceManager::waitForPendingDrop(const char *filename, int
>seconds)
>+{
>+ bool fileExists;
>+
>+ do
>+ {
>+ fileExists = IO::doesFileExist(filename);
>+ if (fileExists && pendingDrops > 0 && seconds-- > 0)
>+
> Thread::getThread("TransactionManager::waitForPendingDrop")-
>>sleep(1000);
>+ else
>+ break;
>+ }
>+ while(true);
>+
>+ return !fileExists;
>+}
>
>
>=== modified file 'storage/falcon/TableSpaceManager.h'
>--- a/storage/falcon/TableSpaceManager.h 2008-06-08 22:12:35 +0000
>+++ b/storage/falcon/TableSpaceManager.h 2008-07-17 20:38:45 +0000
>@@ -62,6 +62,7 @@ public:
> void reportWrites(void);
> void redoCreateTableSpace(int id, int nameLength,
const
>char* name, int fileNameLength, const char* fileName, int type,
>TableSpaceInit* tsInit);
> void initialize(void);
>+ bool waitForPendingDrop(const char *filename, int
>seconds);
>
> Database *database;
> TableSpace *tableSpaces;
>
>
>--
>MySQL Code Commits Mailing List
>For list archives: http://lists.mysql.com/commits
>To unsubscribe: http://lists.mysql.com/commits?unsub=1