diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2019-07-05 12:45:35 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2019-07-05 12:45:35 +0530 |
commit | 5d6a99e5d851cc47ca5b545e28055f2b6240b419 (patch) | |
tree | 0e3cabae9c55a917c98dcc3bf302b08443a0233a | |
parent | 234e88b5d61fa96b512868cada1cfc3299fb0400 (diff) | |
download | mariadb-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.cc | 116 |
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)) { |