diff options
author | Mattias Jonsson <mattias.jonsson@oracle.com> | 2010-08-20 19:15:48 +0200 |
---|---|---|
committer | Mattias Jonsson <mattias.jonsson@oracle.com> | 2010-08-20 19:15:48 +0200 |
commit | 8df0bf13ab5930333ae1148856533e7bff156296 (patch) | |
tree | 75374006b84ddce6925e927c4e7abbf59ef1b107 /sql/sql_partition.cc | |
parent | f4cef8d31f6ee7afefe6cba16f817c01c46a63c2 (diff) | |
download | mariadb-git-8df0bf13ab5930333ae1148856533e7bff156296.tar.gz |
Bug#54747: Deadlock between REORGANIZE PARTITION and SELECT is not detected
The ALTER PARTITION and SELECT seemed to be deadlocked
when having innodb_thread_concurrency = 1.
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 (3).
mysql-test/r/partition_innodb.result:
updated test result
mysql-test/t/partition_innodb.test:
added test
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_trans_prepare/commit_alter_copy_data
Diffstat (limited to 'sql/sql_partition.cc')
-rw-r--r-- | sql/sql_partition.cc | 21 |
1 files changed, 11 insertions, 10 deletions
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 5bbe946179e..b72816f8ce3 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -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, ulonglong copied, 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, ulonglong copied, 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,17 +5528,25 @@ static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt) 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_trans_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); } - DBUG_RETURN(FALSE); + + if (mysql_trans_commit_alter_copy_data(thd)) + DBUG_RETURN(TRUE); /* The error has been reported */ + + DBUG_RETURN(test(error)); } |