summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2019-07-05 12:45:35 +0530
committerThirunarayanan Balathandayuthapani <thiru@mariadb.com>2019-07-05 12:45:35 +0530
commit5d6a99e5d851cc47ca5b545e28055f2b6240b419 (patch)
tree0e3cabae9c55a917c98dcc3bf302b08443a0233a
parent234e88b5d61fa96b512868cada1cfc3299fb0400 (diff)
downloadmariadb-git-bb-10.2-MDEV-15641.tar.gz
MDEV-15641 InnoDB crash while committing table-rebuilding ALTER TABLEbb-10.2-MDEV-15641
- Addressed Eugene's review comments. - Renamed the test case. - Added the comment about applying the online log
-rw-r--r--mysql-test/suite/innodb/r/alter_large_dml.result (renamed from mysql-test/suite/innodb/r/alter_big.result)0
-rw-r--r--mysql-test/suite/innodb/t/alter_large_dml.opt (renamed from mysql-test/suite/innodb/t/alter_big.opt)0
-rw-r--r--mysql-test/suite/innodb/t/alter_large_dml.test (renamed from mysql-test/suite/innodb/t/alter_big.test)0
-rw-r--r--storage/innobase/handler/handler0alter.cc116
4 files changed, 62 insertions, 54 deletions
diff --git a/mysql-test/suite/innodb/r/alter_big.result b/mysql-test/suite/innodb/r/alter_large_dml.result
index 056e8fdd768..056e8fdd768 100644
--- a/mysql-test/suite/innodb/r/alter_big.result
+++ b/mysql-test/suite/innodb/r/alter_large_dml.result
diff --git a/mysql-test/suite/innodb/t/alter_big.opt b/mysql-test/suite/innodb/t/alter_large_dml.opt
index f6d3b8428c9..f6d3b8428c9 100644
--- a/mysql-test/suite/innodb/t/alter_big.opt
+++ b/mysql-test/suite/innodb/t/alter_large_dml.opt
diff --git a/mysql-test/suite/innodb/t/alter_big.test b/mysql-test/suite/innodb/t/alter_large_dml.test
index 5ab3f394115..5ab3f394115 100644
--- a/mysql-test/suite/innodb/t/alter_big.test
+++ b/mysql-test/suite/innodb/t/alter_large_dml.test
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index ce363a0d9c6..5ec0957f7ba 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -8077,74 +8077,75 @@ static bool alter_rebuild_apply_log(
TABLE* altered_table)
{
DBUG_ENTER("alter_rebuild_apply_log");
+
+ if (!ctx->online) {
+ DBUG_RETURN(false);
+ }
+
/* We copied the table. Any indexes that were requested to be
dropped were not created in the copy of the table. Apply any
last bit of the rebuild log and then rename the tables. */
dict_table_t* user_table = ctx->old_table;
dict_table_t* rebuilt_table = ctx->new_table;
- if (ctx->online) {
- DEBUG_SYNC_C("row_log_table_apply2_before");
+ DEBUG_SYNC_C("row_log_table_apply2_before");
- dict_vcol_templ_t* s_templ = NULL;
+ dict_vcol_templ_t* s_templ = NULL;
- if (ctx->new_table->n_v_cols > 0) {
- s_templ = UT_NEW_NOKEY(
- dict_vcol_templ_t());
- s_templ->vtempl = NULL;
+ if (ctx->new_table->n_v_cols > 0) {
+ s_templ = UT_NEW_NOKEY(
+ dict_vcol_templ_t());
+ s_templ->vtempl = NULL;
- innobase_build_v_templ(
- altered_table, ctx->new_table, s_templ,
- NULL, true);
- ctx->new_table->vc_templ = s_templ;
- }
+ innobase_build_v_templ(altered_table, ctx->new_table, s_templ,
+ NULL, true);
+ ctx->new_table->vc_templ = s_templ;
+ }
- dberr_t error = row_log_table_apply(
- ctx->thr, user_table, altered_table,
- static_cast<ha_innobase_inplace_ctx*>(
- ha_alter_info->handler_ctx)->m_stage);
+ dberr_t error = row_log_table_apply(
+ ctx->thr, user_table, altered_table,
+ static_cast<ha_innobase_inplace_ctx*>(
+ ha_alter_info->handler_ctx)->m_stage);
- if (s_templ) {
- ut_ad(ctx->need_rebuild());
- dict_free_vc_templ(s_templ);
- UT_DELETE(s_templ);
- ctx->new_table->vc_templ = NULL;
- }
+ if (s_templ) {
+ ut_ad(ctx->need_rebuild());
+ dict_free_vc_templ(s_templ);
+ UT_DELETE(s_templ);
+ ctx->new_table->vc_templ = NULL;
+ }
- ulint err_key = thr_get_trx(ctx->thr)->error_key_num;
+ ulint err_key = thr_get_trx(ctx->thr)->error_key_num;
- switch (error) {
- KEY* dup_key;
- case DB_SUCCESS:
- break;
- case DB_DUPLICATE_KEY:
- if (err_key == ULINT_UNDEFINED) {
- /* This should be the hidden index on
- FTS_DOC_ID. */
- dup_key = NULL;
- } else {
- DBUG_ASSERT(err_key <
- ha_alter_info->key_count);
- dup_key = &ha_alter_info
- ->key_info_buffer[err_key];
- }
- print_keydup_error(altered_table, dup_key, MYF(0));
- DBUG_RETURN(true);
- case DB_ONLINE_LOG_TOO_BIG:
- my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
- get_error_key_name(err_key, ha_alter_info,
- rebuilt_table));
- DBUG_RETURN(true);
- case DB_INDEX_CORRUPT:
- my_error(ER_INDEX_CORRUPT, MYF(0),
- get_error_key_name(err_key, ha_alter_info,
- rebuilt_table));
- DBUG_RETURN(true);
- default:
- my_error_innodb(error, ctx->old_table->name.m_name,
- user_table->flags);
- DBUG_RETURN(true);
+ switch (error) {
+ KEY* dup_key;
+ case DB_SUCCESS:
+ break;
+ case DB_DUPLICATE_KEY:
+ if (err_key == ULINT_UNDEFINED) {
+ /* This should be the hidden index on
+ FTS_DOC_ID. */
+ dup_key = NULL;
+ } else {
+ DBUG_ASSERT(err_key < ha_alter_info->key_count);
+ dup_key = &ha_alter_info->key_info_buffer[err_key];
}
+
+ print_keydup_error(altered_table, dup_key, MYF(0));
+ DBUG_RETURN(true);
+ case DB_ONLINE_LOG_TOO_BIG:
+ my_error(ER_INNODB_ONLINE_LOG_TOO_BIG, MYF(0),
+ get_error_key_name(err_key, ha_alter_info,
+ rebuilt_table));
+ DBUG_RETURN(true);
+ case DB_INDEX_CORRUPT:
+ my_error(ER_INDEX_CORRUPT, MYF(0),
+ get_error_key_name(err_key, ha_alter_info,
+ rebuilt_table));
+ DBUG_RETURN(true);
+ default:
+ my_error_innodb(error, ctx->old_table->name.m_name,
+ user_table->flags);
+ DBUG_RETURN(true);
}
DBUG_RETURN(false);
@@ -8295,6 +8296,13 @@ ha_innobase::commit_inplace_alter_table(
fts_optimize_remove_table(ctx->new_table);
}
+ /* Apply the online log of the table before acquiring
+ data dictionary latches. Here alter thread already acquired
+ MDL_EXCLUSIVE on the table. So there can't be anymore DDLs, DMLs
+ for the altered table. By applying the log here, InnoDB
+ makes sure that concurrent DDLs, purge thread or any other
+ background thread doesn't wait for the dict_operation_lock
+ for longer time. */
if (new_clustered && commit
&& alter_rebuild_apply_log(
ctx, ha_alter_info, altered_table)) {