From: Mattias Jonsson Date: August 20 2010 10:07am Subject: bzr commit into mysql-5.5-bugfixing branch (mattias.jonsson:3184) Bug#54747 List-Archive: http://lists.mysql.com/commits/116357 X-Bug: 54747 Message-Id: <201008201008.o7KA66Hu007652@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============6767469288758830664==" --===============6767469288758830664== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///Users/mattiasj/mysql-bzr/b54747-5.5-bf/ based on revid:joerg@stripped 3184 Mattias Jonsson 2010-08-20 Bug#54747: Deadlock between REORGANIZE PARTITION and SELECT is not detected Problem was that there was unreleased latches in the ALTER PARTITION thread which was needed by the SELECT thread to be able to continue. Solution was to release the latches by commit before requesting upgrade to exclusive MDL lock. Updated according to reviewers comments. @ mysql-test/r/partition_debug_sync.result updated result @ mysql-test/t/partition_debug_sync.test added test @ sql/sql_base.cc added debug sync for easier testing @ sql/sql_partition.cc Moved implicit commit into mysql_change_partition so that if latches are taken, they are always released before waiting on exclusive lock. @ sql/sql_table.cc refactored the code to prepare and commit around copy_data_between_tables, to be able to reuse it in mysql_change_partitions @ sql/sql_table.h exporting mysql_prepare/commit_alter_copy_data modified: mysql-test/r/partition_debug_sync.result mysql-test/t/partition_debug_sync.test sql/sql_base.cc sql/sql_partition.cc sql/sql_table.cc sql/sql_table.h === modified file 'mysql-test/r/partition_debug_sync.result' --- a/mysql-test/r/partition_debug_sync.result 2010-07-01 13:53:46 +0000 +++ b/mysql-test/r/partition_debug_sync.result 2010-08-20 10:07:33 +0000 @@ -1,6 +1,38 @@ DROP TABLE IF EXISTS t1, t2; SET DEBUG_SYNC= 'RESET'; # +# Bug#54747: Deadlock between REORGANIZE PARTITION and +# SELECT is not detected +# +SET GLOBAL innodb_thread_concurrency = 1; +CREATE TABLE t1 +(user_num BIGINT, +hours SMALLINT, +KEY user_num (user_num)) +ENGINE = InnoDB +PARTITION BY RANGE COLUMNS (hours) +(PARTITION hour_003 VALUES LESS THAN (3), +PARTITION hour_004 VALUES LESS THAN (4), +PARTITION hour_005 VALUES LESS THAN (5), +PARTITION hour_last VALUES LESS THAN (MAXVALUE)); +LOAD DATA LOCAL INFILE 'MYSQLTEST_VARDIR/t_part_range.load' +INTO TABLE t1 (user_num, hours); +# Start a ALTER PARTITION and wait between the copy and rename of table. +# con1 +SET DEBUG_SYNC= 'wait_while_table_is_used SIGNAL run_select WAIT_FOR select_started'; +ALTER TABLE t1 +REORGANIZE PARTITION hour_003, hour_004 INTO +(PARTITION oldest VALUES LESS THAN (4)); +# Start a concurrent SELECT +SET DEBUG_SYNC= 'now WAIT_FOR run_select'; +SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL select_started'; +SELECT COUNT(*) FROM t1; +COUNT(*) +10000 +SET DEBUG_SYNC= 'RESET'; +SET GLOBAL innodb_thread_concurrency = 0; +DROP TABLE t1; +# # Bug#42438: Crash ha_partition::change_table_ptr # Test when remove partitioning is done while drop table is waiting # for the table. === modified file 'mysql-test/t/partition_debug_sync.test' --- a/mysql-test/t/partition_debug_sync.test 2010-07-01 13:53:46 +0000 +++ b/mysql-test/t/partition_debug_sync.test 2010-08-20 10:07:33 +0000 @@ -12,6 +12,70 @@ SET DEBUG_SYNC= 'RESET'; --enable_warnings --echo # +--echo # Bug#54747: Deadlock between REORGANIZE PARTITION and +--echo # SELECT is not detected +--echo # + +let $thread_concurrency = `SELECT @@innodb_thread_concurrency`; +SET GLOBAL innodb_thread_concurrency = 1; + +CREATE TABLE t1 +(user_num BIGINT, + hours SMALLINT, + KEY user_num (user_num)) +ENGINE = InnoDB +PARTITION BY RANGE COLUMNS (hours) +(PARTITION hour_003 VALUES LESS THAN (3), + PARTITION hour_004 VALUES LESS THAN (4), + PARTITION hour_005 VALUES LESS THAN (5), + PARTITION hour_last VALUES LESS THAN (MAXVALUE)); + +--perl +open( DATA, ">$ENV{MYSQLTEST_VARDIR}/t_part_range.load" ) + || die "Could not open file $ENV{MYSQLTEST_VARDIR}/t_part_range.load for writing: $!"; +for ( 1..10000 ) +{ + print DATA ( int(rand(9000000000))+1000000000 ), "\t", ( int(rand(5)) ), "\n"; +} +close( DATA ); +EOF + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +eval LOAD DATA LOCAL INFILE '$MYSQLTEST_VARDIR/t_part_range.load' + INTO TABLE t1 (user_num, hours); + +--remove_file $MYSQLTEST_VARDIR/t_part_range.load + +--echo # Start a ALTER PARTITION and wait between the copy and rename of table. +--echo # con1 + +--connect (con1,localhost,root,,) +SET DEBUG_SYNC= 'wait_while_table_is_used SIGNAL run_select WAIT_FOR select_started'; +--send +ALTER TABLE t1 +REORGANIZE PARTITION hour_003, hour_004 INTO +(PARTITION oldest VALUES LESS THAN (4)); + +--echo # Start a concurrent SELECT + +--connection default +#START TRANSACTION; +SET DEBUG_SYNC= 'now WAIT_FOR run_select'; +SET DEBUG_SYNC= 'after_lock_tables_takes_lock SIGNAL select_started'; +SELECT COUNT(*) FROM t1; + +--connection con1 +--reap + +--disconnect con1 + +--connection default + +SET DEBUG_SYNC= 'RESET'; +eval SET GLOBAL innodb_thread_concurrency = $thread_concurrency; +DROP TABLE t1; + +--echo # --echo # Bug#42438: Crash ha_partition::change_table_ptr --echo # Test when remove partitioning is done while drop table is waiting --echo # for the table. === modified file 'sql/sql_base.cc' --- a/sql/sql_base.cc 2010-08-13 07:50:25 +0000 +++ b/sql/sql_base.cc 2010-08-20 10:07:33 +0000 @@ -2197,6 +2197,8 @@ bool wait_while_table_is_used(THD *thd, table->s->table_name.str, (ulong) table->s, table->db_stat, table->s->version)); + DEBUG_SYNC(thd, "wait_while_table_is_used"); + if (thd->mdl_context.upgrade_shared_lock_to_exclusive( table->mdl_ticket, thd->variables.lock_wait_timeout)) DBUG_RETURN(TRUE); === modified file 'sql/sql_partition.cc' --- a/sql/sql_partition.cc 2010-08-13 07:50:25 +0000 +++ b/sql/sql_partition.cc 2010-08-20 10:07:33 +0000 @@ -63,6 +63,7 @@ #include "sql_table.h" // build_table_filename, // build_table_shadow_filename, // table_to_filename + // mysql_*_alter_copy_data #include "opt_range.h" // store_key_image_to_rec #include "sql_analyse.h" // append_escaped @@ -4377,7 +4378,6 @@ static int fast_end_partition(THD *thd, ALTER_PARTITION_PARAM_TYPE *lpt, bool written_bin_log) { - int error; char tmp_name[80]; DBUG_ENTER("fast_end_partition"); @@ -4386,13 +4386,6 @@ static int fast_end_partition(THD *thd, if (!is_empty) query_cache_invalidate3(thd, table_list, 0); - error= trans_commit_stmt(thd); - if (trans_commit_implicit(thd)) - error= 1; - - if (error) - DBUG_RETURN(TRUE); /* The error has been reported */ - if ((!is_empty) && (!written_bin_log) && (!thd->lex->no_write_to_binlog) && write_bin_log(thd, FALSE, thd->query(), thd->query_length())) @@ -5535,16 +5528,24 @@ static bool mysql_change_partitions(ALTE char path[FN_REFLEN+1]; int error; handler *file= lpt->table->file; + THD *thd= lpt->thd; DBUG_ENTER("mysql_change_partitions"); build_table_filename(path, sizeof(path) - 1, lpt->db, lpt->table_name, "", 0); + + if(mysql_prepare_alter_copy_data(thd)) + DBUG_RETURN(TRUE); + if ((error= file->ha_change_partitions(lpt->create_info, path, &lpt->copied, &lpt->deleted, lpt->pack_frm_data, lpt->pack_frm_len))) { file->print_error(error, MYF(error != ER_OUTOFMEMORY ? 0 : ME_FATALERROR)); - DBUG_RETURN(TRUE); } + + if (mysql_commit_alter_copy_data(thd)) + DBUG_RETURN(TRUE); /* The error has been reported */ + DBUG_RETURN(FALSE); } === modified file 'sql/sql_table.cc' --- a/sql/sql_table.cc 2010-08-16 12:58:38 +0000 +++ b/sql/sql_table.cc 2010-08-20 10:07:33 +0000 @@ -6702,6 +6702,54 @@ err_with_mdl: } /* mysql_alter_table */ + + +/** + Prepare the transaction for the alter table's copy phase. +*/ + +bool mysql_prepare_alter_copy_data(THD *thd) +{ + DBUG_ENTER("mysql_prepare_alter_copy_data"); + /* + Turn off recovery logging since rollback of an alter table is to + delete the new table so there is no need to log the changes to it. + + This needs to be done before external_lock. + */ + if (ha_enable_transaction(thd, FALSE)) + DBUG_RETURN(TRUE); + DBUG_RETURN(FALSE); +} + + +/** + Commit the copy phase of the alter table. +*/ + +bool mysql_commit_alter_copy_data(THD *thd) +{ + bool error= FALSE; + DBUG_ENTER("mysql_commit_alter_copy_data"); + + if (ha_enable_transaction(thd, TRUE)) + DBUG_RETURN(TRUE); + + /* + Ensure that the new table is saved properly to disk before installing + the new .frm. + And that InnoDB's internal latches are released, to avoid deadlock + when waiting on other tables before rename (Bug#54747). + */ + if (trans_commit_stmt(thd)) + error= TRUE; + if (trans_commit_implicit(thd)) + error= TRUE; + + DBUG_RETURN(error); +} + + static int copy_data_between_tables(TABLE *from,TABLE *to, List &create, @@ -6728,14 +6776,7 @@ copy_data_between_tables(TABLE *from,TAB ulonglong prev_insert_id; DBUG_ENTER("copy_data_between_tables"); - /* - Turn off recovery logging since rollback of an alter table is to - delete the new table so there is no need to log the changes to it. - - This needs to be done before external_lock - */ - error= ha_enable_transaction(thd, FALSE); - if (error) + if (mysql_prepare_alter_copy_data(thd)) DBUG_RETURN(-1); if (!(copy= new Copy_field[to->s->fields])) @@ -6894,20 +6935,8 @@ copy_data_between_tables(TABLE *from,TAB } to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY); - if (ha_enable_transaction(thd, TRUE)) - { + if (mysql_commit_alter_copy_data(thd)) error= 1; - goto err; - } - - /* - Ensure that the new table is saved properly to disk so that we - can do a rename - */ - if (trans_commit_stmt(thd)) - error=1; - if (trans_commit_implicit(thd)) - error=1; err: thd->variables.sql_mode= save_sql_mode; === modified file 'sql/sql_table.h' --- a/sql/sql_table.h 2010-08-16 12:53:30 +0000 +++ b/sql/sql_table.h 2010-08-20 10:07:33 +0000 @@ -142,6 +142,8 @@ bool mysql_create_table_no_lock(THD *thd bool mysql_prepare_alter_table(THD *thd, TABLE *table, HA_CREATE_INFO *create_info, Alter_info *alter_info); +bool mysql_prepare_alter_copy_data(THD *thd); +bool mysql_commit_alter_copy_data(THD *thd); bool mysql_alter_table(THD *thd, char *new_db, char *new_name, HA_CREATE_INFO *create_info, TABLE_LIST *table_list, --===============6767469288758830664== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/mattias.jonsson@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: mattias.jonsson@stripped\ # uwp14yiuccu4n2nt # target_branch: file:///Users/mattiasj/mysql-bzr/b54747-5.5-bf/ # testament_sha1: ccc216f37bc235ba92fb4232f6c71bb46fda10af # timestamp: 2010-08-20 12:07:48 +0200 # source_branch: file:///Users/mattiasj/mysql-bzr/test-55-bugfixing/ # base_revision_id: joerg@stripped # # Begin bundle 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 d8DzIA== --===============6767469288758830664==--