List:Commits« Previous MessageNext Message »
From:Kevin Lewis Date:July 17 2008 10:48pm
Subject:RE: bzr commit into mysql-6.0-falcon branch (vvaintroub:2752) Bug#38186
View as plain text  
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

Thread
bzr commit into mysql-6.0-falcon branch (vvaintroub:2752) Bug#38186Vladislav Vaintroub17 Jul
  • RE: bzr commit into mysql-6.0-falcon branch (vvaintroub:2752) Bug#38186Kevin Lewis17 Jul