MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:July 17 2008 7:37pm
Subject:bzr commit into mysql-6.0-falcon branch (vvaintroub:2752) Bug#31295
View as plain text  
#At file:///C:/bzr/mysql-6.0-falcon/

 2752 Vladislav Vaintroub	2008-07-17
      Bug#31295 : 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 19:35:38 +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 19:35:38 +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 19:35:38 +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(--seconds > 0);
+
+	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 19:35:38 +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;

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