MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Vladislav Vaintroub Date:August 4 2008 3:54pm
Subject:bzr commit into mysql-6.0-falcon branch (vvaintroub:2767) Bug#22165 Bug#35991
View as plain text  
#At file:///C:/bzr/mysql-6.0-falcon-team/

 2767 Vladislav Vaintroub	2008-08-04
      Bug#22165 (crash if update is running in parallel with ALTER)
      Bug#35991 (crash if update is running in parallel with TRUNCATE)
      
      Problem :  Falcon optimistically allows DDL statements to run 
      together with read/update. This leads to race conditions, in 
      particular with TRUNCATE (section pages freed by one threads
      accessed by another thread) and ALTER(table is deleted in 
      between but still accessed by some thread).
      There used to be an attempt to synchronize TRUNCATE operation 
      within Falcon ,via setTruncateLock/clearTruncateLock that is not
      working , because TRUNCATE thread disregards/clears locks 
      set by another threads.
      
      Solution:
      synchronize DDL statements using MySQL locks, i.e do not overwrite 
      lock value given in store_lock in case of TRUNCATE, DROP or ALTER. 
      Before DDL operation runs, there is still a check whether table has 
      uncommited records. Operation is denied with ER_CANT_LOCK if there 
      are some uncommited records.
      
      Falcon truncate synchronization is now removed.
renamed:
  mysql-test/suite/falcon_team/r/falcon_bug_22165.result => mysql-test/suite/falcon/r/falcon_bug_22165.result
  mysql-test/suite/falcon_team/r/falcon_bug_22173.result => mysql-test/suite/falcon/r/falcon_bug_22173.result
  mysql-test/suite/falcon_team/r/falcon_bug_22173a.result => mysql-test/suite/falcon/r/falcon_bug_22173a.result
  mysql-test/suite/falcon_team/t/falcon_bug_22165.test => mysql-test/suite/falcon/t/falcon_bug_22165.test
  mysql-test/suite/falcon_team/t/falcon_bug_22173.test => mysql-test/suite/falcon/t/falcon_bug_22173.test
  mysql-test/suite/falcon_team/t/falcon_bug_22173a.test => mysql-test/suite/falcon/t/falcon_bug_22173a.test
modified:
  mysql-test/suite/falcon/t/falcon_bug_37080.test
  storage/falcon/StorageTable.cpp
  storage/falcon/StorageTable.h
  storage/falcon/StorageTableShare.cpp
  storage/falcon/StorageTableShare.h
  storage/falcon/ha_falcon.cpp
  mysql-test/suite/falcon/r/falcon_bug_22165.result
  mysql-test/suite/falcon/r/falcon_bug_22173a.result
  mysql-test/suite/falcon/t/falcon_bug_22165.test
  mysql-test/suite/falcon/t/falcon_bug_22173a.test

per-file messages:
  mysql-test/suite/falcon/r/falcon_bug_22165.result
    Cleanup the test case. to run stored procedures in parallel, do not use events, but 
    an extra connection. This allows for more concurrency (events are called only 1 per
    second)
  mysql-test/suite/falcon/r/falcon_bug_22173.result
    This test has previously deadlocked on truncate and was put into falcon_team suite.
    Restore it in falcon suite
  mysql-test/suite/falcon/r/falcon_bug_22173a.result
    This test previously deadlocked on TRUNCATE and was put into falcon_team suite.
    Restore in falcon suite.
  mysql-test/suite/falcon/t/falcon_bug_22165.test
    Adjust result file
  mysql-test/suite/falcon/t/falcon_bug_22173.test
    This test previously deadlocked on TRUNCATE and was put into falcon_team suite.
    Restore in falcon suite.
  mysql-test/suite/falcon/t/falcon_bug_22173a.test
    This test previously deadlocked on TRUNCATE and was put into falcon_team suite.
    Restore in falcon suite.
  mysql-test/suite/falcon/t/falcon_bug_37080.test
    ER_CANT_LOCK that can come from truncate on a table
    with uncommited records.
  storage/falcon/StorageTable.cpp
    Remove Falcon truncate lock
  storage/falcon/StorageTable.h
    remove Falcon truncate lock
  storage/falcon/StorageTableShare.cpp
    remove Falcon truncate lock
  storage/falcon/StorageTableShare.h
    remove Falcon truncate lock
  storage/falcon/ha_falcon.cpp
    - remove Falcon truncate lock.
    - synchronize DDL statements in external_lock
    - in store_lock ,return error if DLL operation (TRUNCATE,DROP,ALTER)
    is requested and table has uncommited records.
=== renamed file 'mysql-test/suite/falcon_team/r/falcon_bug_22165.result' => 'mysql-test/suite/falcon/r/falcon_bug_22165.result'
--- a/mysql-test/suite/falcon_team/r/falcon_bug_22165.result	2008-08-04 09:21:20 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_22165.result	2008-08-04 15:53:52 +0000
@@ -1,11 +1,8 @@
 *** Bug #22165 ***
 SET @@storage_engine = 'Falcon';
-DROP PROCEDURE IF EXISTS db1.p1;
-DROP EVENT IF EXISTS db1.e1;
-DROP EVENT IF EXISTS db1.e2;
-DROP DATABASE IF EXISTS db1;
-CREATE DATABASE db1;
-USE db1;
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
+CREATE TABLE t1 (a bigint, b varchar(1000), c timestamp);
 CREATE PROCEDURE p1 ()
 begin
 declare v int default 0;
@@ -23,13 +20,5 @@ COMMIT;
 SET v = v + 1;
 end while;
 end//
-CREATE TABLE t1 (a bigint, b varchar(1000), c timestamp);
-CREATE EVENT e1 ON SCHEDULE EVERY 1 second DO CALL db1.p1();
-CREATE EVENT e2 ON SCHEDULE EVERY 1 second DO CALL db1.p1();
-SET GLOBAL event_scheduler = 1;
-SET GLOBAL event_scheduler = 0;
-USE test;
-DROP EVENT db1.e1;
-DROP EVENT db1.e2;
-DROP PROCEDURE db1.p1;
-DROP DATABASE db1;
+DROP PROCEDURE p1;
+DROP TABLE t1;

=== renamed file 'mysql-test/suite/falcon_team/r/falcon_bug_22173.result' => 'mysql-test/suite/falcon/r/falcon_bug_22173.result'
=== renamed file 'mysql-test/suite/falcon_team/r/falcon_bug_22173a.result' => 'mysql-test/suite/falcon/r/falcon_bug_22173a.result'
--- a/mysql-test/suite/falcon_team/r/falcon_bug_22173a.result	2008-04-20 08:30:43 +0000
+++ b/mysql-test/suite/falcon/r/falcon_bug_22173a.result	2008-08-04 15:53:52 +0000
@@ -12,6 +12,7 @@ begin declare v1 int default 0;
 declare v2 int;
 declare continue handler for 1020 begin end;
 declare continue handler for 1213 begin end;
+declare continue handler for 1015 begin end;
 while v1 < 2500 do
 /* SELECT 'insert', v1; */
 INSERT INTO t1 VALUES (v1);

=== renamed file 'mysql-test/suite/falcon_team/t/falcon_bug_22165.test' => 'mysql-test/suite/falcon/t/falcon_bug_22165.test'
--- a/mysql-test/suite/falcon_team/t/falcon_bug_22165.test	2008-07-22 13:19:24 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_22165.test	2008-08-04 15:53:52 +0000
@@ -11,14 +11,11 @@ let $engine = 'Falcon';
 eval SET @@storage_engine = $engine;
 
 --disable_warnings
-DROP PROCEDURE IF EXISTS db1.p1;
-DROP EVENT IF EXISTS db1.e1;
-DROP EVENT IF EXISTS db1.e2;
-DROP DATABASE IF EXISTS db1;
+DROP TABLE IF EXISTS t1;
+DROP PROCEDURE IF EXISTS p1;
 --enable_warnings
+CREATE TABLE t1 (a bigint, b varchar(1000), c timestamp);
 
-CREATE DATABASE db1;
-USE db1;
 delimiter //;
 CREATE PROCEDURE p1 ()
 begin
@@ -39,18 +36,31 @@ begin
 end//
 delimiter ;//
 
-CREATE TABLE t1 (a bigint, b varchar(1000), c timestamp);
+connect (conn1,localhost,root,,);
+connect (conn2,localhost,root,,);
+
 
-CREATE EVENT e1 ON SCHEDULE EVERY 1 second DO CALL db1.p1();
-CREATE EVENT e2 ON SCHEDULE EVERY 1 second DO CALL db1.p1();
 
 # ----------------------------------------------------- #
 # --- Test                                          --- #
 # ----------------------------------------------------- #
-SET GLOBAL event_scheduler = 1;
---sleep 60
-SET GLOBAL event_scheduler = 0;
-
+--disable_query_log
+let $i=150;
+while ($i)
+{
+  connection conn1;
+  --send call p1();
+  connection conn2;
+  --send call p1();
+  
+  connection conn1;
+  --reap
+  connection conn2;
+  --reap
+  
+  dec $i;
+}
+--enable_query_log
 # ----------------------------------------------------- #
 # --- Check                                         --- #
 # ----------------------------------------------------- #
@@ -60,8 +70,9 @@ SET GLOBAL event_scheduler = 0;
 # ----------------------------------------------------- #
 # --- Final cleanup                                 --- #
 # ----------------------------------------------------- #
-USE test;
-DROP EVENT db1.e1;
-DROP EVENT db1.e2;
-DROP PROCEDURE db1.p1;
-DROP DATABASE db1;
+connection default;
+disconnect conn1;
+disconnect conn2;
+DROP PROCEDURE p1;
+DROP TABLE t1;
+

=== renamed file 'mysql-test/suite/falcon_team/t/falcon_bug_22173.test' => 'mysql-test/suite/falcon/t/falcon_bug_22173.test'
=== renamed file 'mysql-test/suite/falcon_team/t/falcon_bug_22173a.test' => 'mysql-test/suite/falcon/t/falcon_bug_22173a.test'
--- a/mysql-test/suite/falcon_team/t/falcon_bug_22173a.test	2008-04-20 08:30:43 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_22173a.test	2008-08-04 15:53:52 +0000
@@ -31,6 +31,7 @@ begin declare v1 int default 0;
 declare v2 int;
 declare continue handler for 1020 begin end;
 declare continue handler for 1213 begin end;
+declare continue handler for 1015 begin end;
 while v1 < 2500 do
   /* SELECT 'insert', v1; */
   INSERT INTO t1 VALUES (v1);
@@ -52,7 +53,6 @@ delimiter ;//
 
 --echo # Switch to connection conn1
 connection conn1;
---real_sleep 1
 call p1();
 
 --echo # Switch to connection default

=== modified file 'mysql-test/suite/falcon/t/falcon_bug_37080.test'
--- a/mysql-test/suite/falcon/t/falcon_bug_37080.test	2008-07-16 17:52:19 +0000
+++ b/mysql-test/suite/falcon/t/falcon_bug_37080.test	2008-08-04 15:53:52 +0000
@@ -31,8 +31,10 @@ while ($num)
    connection default;
    --send truncate table t1;
    connection conn1;
+   --error 0,ER_CANT_LOCK
    --reap
    connection default;
+   --error 0,ER_CANT_LOCK
    --reap 
    dec $num;
 }

=== modified file 'storage/falcon/StorageTable.cpp'
--- a/storage/falcon/StorageTable.cpp	2008-05-02 22:09:28 +0000
+++ b/storage/falcon/StorageTable.cpp	2008-08-04 15:53:52 +0000
@@ -56,8 +56,6 @@ StorageTable::StorageTable(StorageConnec
 
 StorageTable::~StorageTable(void)
 {
-	clearTruncateLock();
-	
 	if (bitmap)
 		((Bitmap*) bitmap)->release();
 
@@ -85,7 +83,6 @@ int StorageTable::open(void)
 
 int StorageTable::deleteTable(void)
 {
-	clearTruncateLock();
 	int ret = share->deleteTable(storageConnection);
 	
 	if (ret == 0)
@@ -96,32 +93,12 @@ int StorageTable::deleteTable(void)
 
 int StorageTable::truncateTable(void)
 {
-	clearTruncateLock();
-	Sync sync(share->syncTruncate, "StorageTable::truncateTable");
-	sync.lock(Exclusive);
 	clearRecord();
 	int ret = share->truncateTable(storageConnection);
-	
 	return ret;
 }
 
-void StorageTable::clearTruncateLock(void)
-{
-	if (haveTruncateLock)
-		{
-		share->clearTruncateLock();
-		haveTruncateLock = false;
-		}
-}
 
-void StorageTable::setTruncateLock()
-{
-	if (!haveTruncateLock)
-		{
-		share->setTruncateLock();
-		haveTruncateLock = true;
-		}
-}
 
 int StorageTable::insert(void)
 {

=== modified file 'storage/falcon/StorageTable.h'
--- a/storage/falcon/StorageTable.h	2008-05-02 22:09:28 +0000
+++ b/storage/falcon/StorageTable.h	2008-08-04 15:53:52 +0000
@@ -64,8 +64,7 @@ public:
 	void			clearAlter(void);
 	bool			setAlter(void);
 	
-	void			clearTruncateLock(void);
-	void			setTruncateLock();
+
 	
 	virtual void	setConnection(StorageConnection* connection);
 	virtual void	clearIndexBounds(void);

=== modified file 'storage/falcon/StorageTableShare.cpp'
--- a/storage/falcon/StorageTableShare.cpp	2008-07-15 18:57:27 +0000
+++ b/storage/falcon/StorageTableShare.cpp	2008-08-04 15:53:52 +0000
@@ -70,10 +70,7 @@ StorageTableShare::StorageTableShare(Sto
 	sequence = NULL;
 	tempTable = tempTbl;
 	setPath(path);
-	syncTruncate = new SyncObject;
-	syncTruncate->setName("StorageTableShare::syncTruncate");
-	truncateLockCount = 0;
-	
+
 	if (tempTable)
 		tableSpace = TEMPORARY_TABLESPACE;
 	else if (tableSpaceName && tableSpaceName[0])
@@ -84,11 +81,7 @@ StorageTableShare::StorageTableShare(Sto
 
 StorageTableShare::~StorageTableShare(void)
 {
-	while (truncateLockCount > 0)
-		clearTruncateLock();
-
 	delete syncObject;
-	delete syncTruncate;
 	delete [] impure;
 	
 	if (storageDatabase)
@@ -605,21 +598,6 @@ JString StorageTableShare::lookupPathNam
 	return path;
 }
 
-void StorageTableShare::setTruncateLock(void)
-{
-	INTERLOCKED_INCREMENT(truncateLockCount);
-	syncTruncate->lock(NULL, Shared);
-}
-
-void StorageTableShare::clearTruncateLock(void)
-{
-	if (truncateLockCount > 0)
-		{
-		INTERLOCKED_DECREMENT(truncateLockCount);
-		syncTruncate->unlock();
-//		syncTruncate->unlock(NULL, Shared);
-		}
-}
 
 int StorageTableShare::getFieldId(const char* fieldName)
 {

=== modified file 'storage/falcon/StorageTableShare.h'
--- a/storage/falcon/StorageTableShare.h	2008-07-09 04:38:02 +0000
+++ b/storage/falcon/StorageTableShare.h	2008-08-04 15:53:52 +0000
@@ -126,8 +126,6 @@ public:
 	uint64				estimateCardinality(void);
 	bool				tableExists(void);
 	JString				lookupPathName(void);
-	void				setTruncateLock(void);
-	void				clearTruncateLock(void);
 
 	static const char*	getDefaultRoot(void);
 	static const char*	cleanupTableName(const char* name, char* buffer, int bufferLength, char *schema, int schemaLength);
@@ -142,7 +140,6 @@ public:
 	unsigned char		*impure;
 	int					initialized;
 	SyncObject			*syncObject;
-	SyncObject			*syncTruncate;
 	StorageDatabase		*storageDatabase;
 	StorageHandler		*storageHandler;
 	Table				*table;
@@ -150,7 +147,6 @@ public:
 	Sequence			*sequence;
 	Format				*format;						// format for insertion
 	int					numberIndexes;
-	volatile INTERLOCK_TYPE	truncateLockCount;
 	bool				tempTable;
 	int getFieldId(const char* fieldName);
 };

=== modified file 'storage/falcon/ha_falcon.cpp'
--- a/storage/falcon/ha_falcon.cpp	2008-07-29 10:45:39 +0000
+++ b/storage/falcon/ha_falcon.cpp	2008-08-04 15:53:52 +0000
@@ -420,9 +420,6 @@ StorageInterface::StorageInterface(handl
 
 StorageInterface::~StorageInterface(void)
 {
-	if (storageTable)
-		storageTable->clearTruncateLock();
-
 	if (activeBlobs)
 		freeActiveBlobs();
 
@@ -534,10 +531,6 @@ StorageConnection* StorageInterface::get
 int StorageInterface::close(void)
 {
 	DBUG_ENTER("StorageInterface::close");
-
-	if (storageTable)
-		storageTable->clearTruncateLock();
-
 	unmapFields();
 
 	// Temporarily comment out DTrace probes in Falcon, see bug #36403
@@ -917,7 +910,9 @@ THR_LOCK_DATA **StorageInterface::store_
 		if (    (lock_type >= TL_WRITE_CONCURRENT_INSERT && lock_type <= TL_WRITE)
 		    && !(thd_in_lock_tables(thd) && sql_command == SQLCOM_LOCK_TABLES)
 		    && !(thd_tablespace_op(thd))
-		  //  &&  (sql_command != SQLCOM_TRUNCATE)
+		    &&  (sql_command != SQLCOM_ALTER_TABLE)
+		    &&  (sql_command != SQLCOM_DROP_TABLE)
+		    &&  (sql_command != SQLCOM_TRUNCATE)
 		    &&  (sql_command != SQLCOM_OPTIMIZE)
 		    &&  (sql_command != SQLCOM_CREATE_TABLE)
 		   )
@@ -1020,7 +1015,7 @@ int StorageInterface::delete_all_rows()
 	if (!storageTable)
 		storageTable = storageConnection->getStorageTable(storageShare);
 		
-	storageTable->truncateTable();
+	ret = storageTable->truncateTable();
 		
 	DBUG_RETURN(ret);
 }
@@ -1262,10 +1257,6 @@ void StorageInterface::startTransaction(
 	if (!storageConnection->transactionActive)
 		{
 		storageConnection->startTransaction(isolation);
-		
-		if (storageTable)
-			storageTable->setTruncateLock();
-				
 		trans_register_ha(mySqlThread, true, falcon_hton);
 		}
 
@@ -1873,12 +1864,7 @@ int StorageInterface::external_lock(THD 
 		storageConnection->setCurrentStatement(NULL);
 
 		if (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
-			{
-			if (storageTable)
-				storageTable->clearTruncateLock();
-		
 			storageConnection->endImplicitTransaction();
-			}
 		else
 			storageConnection->releaseVerb();
 
@@ -1891,10 +1877,11 @@ int StorageInterface::external_lock(THD 
 			storageConnection->setCurrentStatement(thd->query);
 
 		insertCount = 0;
-		bool isTruncate = false;
-		
+
 		switch (thd_sql_command(thd))
 			{
+			case SQLCOM_TRUNCATE:
+			case SQLCOM_DROP_TABLE:
 			case SQLCOM_ALTER_TABLE:
 			case SQLCOM_DROP_INDEX:
 			case SQLCOM_CREATE_INDEX:
@@ -1903,18 +1890,10 @@ int StorageInterface::external_lock(THD 
 
 				if (ret)
 					{
-					if (storageTable)
-						storageTable->clearTruncateLock();
-						
 					DBUG_RETURN(error(ret));
 					}
 				}
 				break;
-
-			case SQLCOM_TRUNCATE:
-				isTruncate = true;
-				break;
-				
 			default:
 				break;
 			}
@@ -1927,9 +1906,6 @@ int StorageInterface::external_lock(THD 
 			
 			if (storageConnection->startTransaction(isolation))
 				{
-				if (!isTruncate && storageTable)
-					storageTable->setTruncateLock();
-				
 				trans_register_ha(thd, true, falcon_hton);
 				}
 
@@ -1942,9 +1918,6 @@ int StorageInterface::external_lock(THD 
 			
 			if (storageConnection->startImplicitTransaction(isolation))
 				{
-				if (!isTruncate && storageTable)
-					storageTable->setTruncateLock();
-				
 				trans_register_ha(thd, false, falcon_hton);
 				}
 			}

Thread
bzr commit into mysql-6.0-falcon branch (vvaintroub:2767) Bug#22165 Bug#35991Vladislav Vaintroub4 Aug