diff options
Diffstat (limited to 'storage/xtradb/handler/handler0alter.cc')
-rw-r--r-- | storage/xtradb/handler/handler0alter.cc | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index ea02463010c..1e57f6c5293 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -463,6 +463,20 @@ ha_innobase::check_if_supported_inplace_alter( } } + ulint n_indexes = UT_LIST_GET_LEN((prebuilt->table)->indexes); + + /* If InnoDB dictionary and MySQL frm file are not consistent + use "Copy" method. */ + if (prebuilt->table->dict_frm_mismatch) { + + ha_alter_info->unsupported_reason = innobase_get_err_msg( + ER_NO_SUCH_INDEX); + ib_push_frm_error(user_thd, prebuilt->table, altered_table, + n_indexes, true); + + DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); + } + /* We should be able to do the operation in-place. See if we can do it online (LOCK=NONE). */ bool online = true; @@ -2777,6 +2791,10 @@ prepare_inplace_alter_table_dict( ctx->num_to_add_index = ha_alter_info->index_add_count; + ut_ad(ctx->prebuilt->trx->mysql_thd != NULL); + const char* path = thd_innodb_tmpdir( + ctx->prebuilt->trx->mysql_thd); + index_defs = innobase_create_key_defs( ctx->heap, ha_alter_info, altered_table, ctx->num_to_add_index, num_fts_index, @@ -3130,8 +3148,10 @@ prepare_inplace_alter_table_dict( error = DB_OUT_OF_MEMORY; goto error_handling;); rw_lock_x_lock(&ctx->add_index[a]->lock); + bool ok = row_log_allocate(ctx->add_index[a], - NULL, true, NULL, NULL); + NULL, true, NULL, + NULL, path); rw_lock_x_unlock(&ctx->add_index[a]->lock); if (!ok) { @@ -3157,7 +3177,7 @@ prepare_inplace_alter_table_dict( clust_index, ctx->new_table, !(ha_alter_info->handler_flags & Alter_inplace_info::ADD_PK_INDEX), - ctx->add_cols, ctx->col_map); + ctx->add_cols, ctx->col_map, path); rw_lock_x_unlock(&clust_index->lock); if (!ok) { @@ -4159,6 +4179,7 @@ ok_exit: files and merge sort. */ DBUG_EXECUTE_IF("innodb_OOM_inplace_alter", error = DB_OUT_OF_MEMORY; goto oom;); + error = row_merge_build_indexes( prebuilt->trx, prebuilt->table, ctx->new_table, @@ -6194,6 +6215,21 @@ foreign_fail: row_mysql_unlock_data_dictionary(trx); trx_free_for_mysql(trx); + /* Rebuild index translation table now for temporary tables if we are + restoring secondary keys, as ha_innobase::open will not be called for + the next access. */ + if (dict_table_is_temporary(ctx0->new_table) + && ctx0->num_to_add_index > 0) { + ut_ad(!ctx0->num_to_drop_index); + ut_ad(!ctx0->num_to_drop_fk); + if (!innobase_build_index_translation(altered_table, + ctx0->new_table, + share)) { + MONITOR_ATOMIC_DEC(MONITOR_PENDING_ALTER_TABLE); + DBUG_RETURN(true); + } + } + /* TODO: The following code could be executed while allowing concurrent access to the table (MDL downgrade). */ |