From: Date: June 11 2008 8:31pm Subject: bzr commit into mysql-6.0-falcon branch (vvaintroub:2699) Bug#37080 List-Archive: http://lists.mysql.com/commits/47752 X-Bug: 37080 Message-Id: <200806111831.m5BIVL24019943@mail.mysql.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit #At bzr+ssh://bk-internal.mysql.com/bzrroot/server/mysql-6.0-falcon/ 2699 Vladislav Vaintroub 2008-06-11 Bug#37080 - Falcon deadlock on concurrent insert and truncate Problem: Two threads, one processing TRUNCATE and gopher processing INSERT acquire the same locks, SerlialLog::syncSections and Table::syncObject in different order Solution: Rearrange locks, so that syncSections is always locked before Table::syncObject. For this, move lock to syncSection from SRLDropTable::append() up the stack, into to Database::dropTable() Database::truncateTable() added: mysql-test/suite/falcon/r/falcon_bug_37080.result mysql-test/suite/falcon/t/falcon_bug_37080.test modified: storage/falcon/Database.cpp storage/falcon/SRLDropTable.cpp per-file messages: mysql-test/suite/falcon/r/falcon_bug_37080.result result file for Bug#37080 mysql-test/suite/falcon/t/falcon_bug_37080.test test case for Bug#37080 2 concurrent connections, one sending 1000 INSERTs and another 100 TRUNCATEs. output is completely ignored, we're interested in deadlocks storage/falcon/Database.cpp moved syncSections exclusive lock from SRLDropTable::append() to Database:dropTable() and Database::truncateTable() to avoid deadlock storage/falcon/SRLDropTable.cpp moved syncSections exclusive lock from SRLDropTable::append() to Database:dropTable() and Database::truncateTable() to avoid deadlock === added file 'mysql-test/suite/falcon/r/falcon_bug_37080.result' --- a/mysql-test/suite/falcon/r/falcon_bug_37080.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/falcon/r/falcon_bug_37080.result 2008-06-11 18:31:05 +0000 @@ -0,0 +1,5 @@ +*** Bug #37080 *** +SET @@storage_engine = 'Falcon'; +DROP TABLE IF EXISTS t; +CREATE TABLE t(i int); +DROP TABLE t; === added file 'mysql-test/suite/falcon/t/falcon_bug_37080.test' --- a/mysql-test/suite/falcon/t/falcon_bug_37080.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/falcon/t/falcon_bug_37080.test 2008-06-11 18:31:05 +0000 @@ -0,0 +1,50 @@ +--source include/have_falcon.inc +# +# Bug#37080: Falcon deadlock on parallel TRUNCATE and INSERT +# +--echo *** Bug #37080 *** + +# ----------------------------------------------------- # +# --- Initialisation --- # +# ----------------------------------------------------- # +let $engine = 'Falcon'; +eval SET @@storage_engine = $engine; + +--disable_warnings +DROP TABLE IF EXISTS t; +--enable_warnings + + +CREATE TABLE t(i int); +connect (conn1,localhost,root,,); +# ----------------------------------------------------- # +# --- Test --- # +# ----------------------------------------------------- # + + +let $num=10000; +--disable_query_log +--disable_abort_on_error +while ($num) +{ + connection conn1; + --send insert into t values(1); + connection default; + --send truncate table t; + connection conn1; + --reap + connection default; + --reap + dec $num; +} +--enable_abort_on_error +--enable_query_log + +# ----------------------------------------------------- # +# --- Check --- # +# ----------------------------------------------------- # + +# ----------------------------------------------------- # +# --- Final cleanup --- # +# ----------------------------------------------------- # +DROP TABLE t; === modified file 'storage/falcon/Database.cpp' --- a/storage/falcon/Database.cpp 2008-05-09 19:58:50 +0000 +++ b/storage/falcon/Database.cpp 2008-06-11 18:31:05 +0000 @@ -1452,6 +1452,10 @@ void Database::dropTable(Table *table, T invalidateCompiledStatements(table); table->drop(transaction); + + //Lock sections (factored out of SRLDropTable to avoid a deadlock) + Sync syncSections(&serialLog->syncSections, "Database::dropTable"); + syncSections.lock(Exclusive); table->expunge(getSystemTransaction()); delete table; } @@ -1474,8 +1478,14 @@ void Database::truncateTable(Table *tabl Sync syncTbl(&syncTables, "Database::truncateTable"); syncTbl.lock(Shared); - // No table access until truncate completes + //Lock sections (factored out of SRLDropTable to avoid a deadlock) + //The lock order (serialLog->syncSections before table->syncObject) is + //important + + Sync syncSections(&serialLog->syncSections, "Database::truncateTable"); + syncSections.lock(Exclusive); + // No table access until truncate completes Sync syncObj(&table->syncObject, "Database::truncateTable"); syncObj.lock(Exclusive); === modified file 'storage/falcon/SRLDropTable.cpp' --- a/storage/falcon/SRLDropTable.cpp 2007-09-20 15:44:25 +0000 +++ b/storage/falcon/SRLDropTable.cpp 2008-06-11 18:31:05 +0000 @@ -46,9 +46,6 @@ SRLDropTable::~SRLDropTable() void SRLDropTable::append(Dbb *dbb, TransId transId, int section) { - Sync syncSections(&log->syncSections, "SRLDropTable::append"); - syncSections.lock(Exclusive); - START_RECORD(srlDropTable, "SRLDropTable::append"); putInt(dbb->tableSpaceId); log->getTransaction(transId);