diff options
author | Alexander Barkov <bar@mariadb.org> | 2017-05-26 19:32:28 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.org> | 2017-05-26 19:32:28 +0400 |
commit | 9bc32256427373e5bfa78f17c5854ac4e6a2fc31 (patch) | |
tree | 748fd55866bcbc4de5eee1c078ac8d2cad5b6fd7 /storage/xtradb/handler | |
parent | 77b2f55f61a4e3ba642049a01651c92bfb0a7d9d (diff) | |
parent | ca7cf69cb13285585922722063af888b957580ee (diff) | |
download | mariadb-git-9bc32256427373e5bfa78f17c5854ac4e6a2fc31.tar.gz |
Merge tag 'mariadb-10.2.6' into bb-10.2-ext
Diffstat (limited to 'storage/xtradb/handler')
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 341 | ||||
-rw-r--r-- | storage/xtradb/handler/handler0alter.cc | 62 |
2 files changed, 193 insertions, 210 deletions
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index b89bd419876..49b0fedb3b4 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -32,7 +32,7 @@ this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA *****************************************************************************/ - + #define MYSQL_SERVER #include <sql_table.h> // explain_filename, nz2, EXPLAIN_PARTITIONS_AS_COMMENT, @@ -289,7 +289,8 @@ static TYPELIB innodb_stats_method_typelib = { /** Possible values for system variables "innodb_checksum_algorithm" and "innodb_log_checksum_algorithm". */ -static const char* innodb_checksum_algorithm_names[] = { +UNIV_INTERN +const char* innodb_checksum_algorithm_names[] = { "CRC32", "STRICT_CRC32", "INNODB", @@ -301,7 +302,8 @@ static const char* innodb_checksum_algorithm_names[] = { /** Used to define an enumerate type of the system variables innodb_checksum_algorithm and innodb_log_checksum_algorithm. */ -static TYPELIB innodb_checksum_algorithm_typelib = { +UNIV_INTERN +TYPELIB innodb_checksum_algorithm_typelib = { array_elements(innodb_checksum_algorithm_names) - 1, "innodb_checksum_algorithm_typelib", innodb_checksum_algorithm_names, @@ -2018,7 +2020,9 @@ thd_supports_xa( THD* thd) /*!< in: thread handle, or NULL to query the global innodb_supports_xa */ { - return(THDVAR(thd, support_xa)); + /* THDVAR cannot be used in xtrabackup, + plugin variables for innodb are not loaded. */ + return (thd || !IS_XTRABACKUP())? THDVAR(thd, support_xa): FALSE; } /** Get the value of innodb_tmpdir. @@ -2051,7 +2055,9 @@ thd_fake_changes( THD* thd) /*!< in: thread handle, or NULL to query the global innodb_supports_xa */ { - return(THDVAR((THD*) thd, fake_changes)); + /* THDVAR cannot be used in xtrabackup, + plugin variables for innodb are not loaded */ + return (thd || !IS_XTRABACKUP())? THDVAR((THD*) thd, fake_changes) : FALSE ; } /******************************************************************//** @@ -2091,7 +2097,10 @@ thd_flush_log_at_trx_commit( /*================================*/ void* thd) { - return(THDVAR((THD*) thd, flush_log_at_trx_commit)); + /* THDVAR cannot be used in xtrabackup, + plugin variables for innodb are not loaded, + this makes xtrabackup crash when trying to use them. */ + return (thd || !IS_XTRABACKUP())? THDVAR((THD*)thd, flush_log_at_trx_commit) : FALSE; } /********************************************************************//** @@ -3058,7 +3067,7 @@ trx_is_started( /****************************************************************//** Update log_checksum_algorithm_ptr with a pointer to the function corresponding to a given checksum algorithm. */ -static + void innodb_log_checksum_func_update( /*============================*/ @@ -6233,20 +6242,23 @@ ha_innobase::innobase_initialize_autoinc() break; } case DB_RECORD_NOT_FOUND: - ut_print_timestamp(stderr); - fprintf(stderr, " InnoDB: MySQL and InnoDB data " - "dictionaries are out of sync.\n" - "InnoDB: Unable to find the AUTOINC column " - "%s in the InnoDB table %s.\n" - "InnoDB: We set the next AUTOINC column " - "value to 0,\n" - "InnoDB: in effect disabling the AUTOINC " - "next value generation.\n" - "InnoDB: You can either set the next " - "AUTOINC value explicitly using ALTER TABLE\n" - "InnoDB: or fix the data dictionary by " - "recreating the table.\n", - col_name, index->table->name); + char buf[MAX_FULL_NAME_LEN]; + ut_format_name(index->table->name, TRUE, buf, sizeof(buf)); + + ib_logf(IB_LOG_LEVEL_ERROR, + "MySQL and InnoDB data " + "dictionaries are out of sync." + " Unable to find the AUTOINC column " + " %s in the InnoDB table %s." + " We set the next AUTOINC column " + "value to 0" + " in effect disabling the AUTOINC " + "next value generation." + " You can either set the next " + "AUTOINC value explicitly using ALTER TABLE " + " or fix the data dictionary by " + "recreating the table.", + col_name, buf); /* This will disable the AUTOINC generation. */ auto_inc = 0; @@ -6305,7 +6317,7 @@ ha_innobase::open( DBUG_RETURN(1); } - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt && + if (UNIV_UNLIKELY(share->ib_table && share->ib_table->corrupted && srv_pass_corrupt_table <= 1)) { free_share(share); @@ -6341,23 +6353,24 @@ ha_innobase::open( && (table->s->fields != dict_table_get_n_user_cols(ib_table) - 1)))) { ib_logf(IB_LOG_LEVEL_WARN, - "table %s contains %lu user defined columns " - "in InnoDB, but %lu columns in MySQL. Please " + "table %s contains " ULINTPF " user defined columns " + "in InnoDB, but %u columns in MySQL. Please " "check INFORMATION_SCHEMA.INNODB_SYS_COLUMNS and " REFMAN "innodb-troubleshooting.html " "for how to resolve it", - norm_name, (ulong) dict_table_get_n_user_cols(ib_table), - (ulong) table->s->fields); + norm_name, dict_table_get_n_user_cols(ib_table), + table->s->fields); /* Mark this table as corrupted, so the drop table or force recovery can still use it, but not others. */ ib_table->corrupted = true; + ib_table->file_unreadable = true; dict_table_close(ib_table, FALSE, FALSE); ib_table = NULL; is_part = NULL; } - if (UNIV_UNLIKELY(ib_table && ib_table->is_corrupt && + if (UNIV_UNLIKELY(ib_table && ib_table->corrupted && srv_pass_corrupt_table <= 1)) { free_share(share); my_free(upd_buf); @@ -6467,7 +6480,7 @@ table_opened: ib_table->thd = (void*)thd; /* No point to init any statistics if tablespace is still encrypted. */ - if (!ib_table->is_encrypted) { + if (ib_table->is_readable()) { dict_stats_init(ib_table); } else { ib_table->stat_initialized = 1; @@ -6475,7 +6488,9 @@ table_opened: MONITOR_INC(MONITOR_TABLE_OPEN); - bool no_tablespace; + bool no_tablespace = false; + bool encrypted = false; + FilSpace space; if (dict_table_is_discarded(ib_table)) { @@ -6490,23 +6505,28 @@ table_opened: no_tablespace = false; - } else if (ib_table->ibd_file_missing) { + } else if (!ib_table->is_readable()) { + space = fil_space_acquire_silent(ib_table->space); - ib_senderrf( - thd, IB_LOG_LEVEL_WARN, - ER_TABLESPACE_MISSING, norm_name); - - /* This means we have no idea what happened to the tablespace - file, best to play it safe. */ - - no_tablespace = true; - } else if (ib_table->is_encrypted) { - /* This means that tablespace was found but we could not - decrypt encrypted page. */ - no_tablespace = true; - ib_table->ibd_file_missing = true; - } else { - no_tablespace = false; + if (space()) { + if (space()->crypt_data && space()->crypt_data->is_encrypted()) { + /* This means that tablespace was found but we could not + decrypt encrypted page. */ + no_tablespace = true; + encrypted = true; + } else { + no_tablespace = true; + } + } else { + ib_senderrf( + thd, IB_LOG_LEVEL_WARN, + ER_TABLESPACE_MISSING, norm_name); + + /* This means we have no idea what happened to the tablespace + file, best to play it safe. */ + + no_tablespace = true; + } } if (!thd_tablespace_op(thd) && no_tablespace) { @@ -6517,27 +6537,33 @@ table_opened: /* If table has no talespace but it has crypt data, check is tablespace made unaccessible because encryption service or used key_id is not available. */ - if (ib_table) { - fil_space_crypt_t* crypt_data = ib_table->crypt_data; + if (encrypted) { + bool warning_pushed = false; + char buf[MAX_FULL_NAME_LEN]; + ut_format_name(ib_table->name, TRUE, buf, sizeof(buf)); - if (crypt_data && crypt_data->should_encrypt()) { + if (!encryption_key_id_exists(space()->crypt_data->key_id)) { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + HA_ERR_DECRYPTION_FAILED, + "Table %s in file %s is encrypted but encryption service or" + " used key_id %u is not available. " + " Can't continue reading table.", + buf, space()->chain.start->name, + space()->crypt_data->key_id); + ret_err = HA_ERR_DECRYPTION_FAILED; + warning_pushed = true; + } - if (!encryption_key_id_exists(crypt_data->key_id)) { - push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, - HA_ERR_DECRYPTION_FAILED, - "Table %s is encrypted but encryption service or" - " used key_id %u is not available. " - " Can't continue reading table.", - ib_table->name, crypt_data->key_id); - ret_err = HA_ERR_DECRYPTION_FAILED; - } - } else if (ib_table->is_encrypted) { + /* If table is marked as encrypted then we push + warning if it has not been already done as used + key_id might be found but it is incorrect. */ + if (!warning_pushed) { push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, HA_ERR_DECRYPTION_FAILED, - "Table %s is encrypted but encryption service or" + "Table %s in file %s is encrypted but encryption service or" " used key_id is not available. " " Can't continue reading table.", - ib_table->name); + buf, space()->chain.start->name); ret_err = HA_ERR_DECRYPTION_FAILED; } } @@ -6673,7 +6699,7 @@ table_opened: /* Only if the table has an AUTOINC column. */ if (prebuilt->table != NULL - && !prebuilt->table->ibd_file_missing + && prebuilt->table->is_readable() && table->found_next_number_field != NULL) { dict_table_autoinc_lock(prebuilt->table); @@ -8658,16 +8684,6 @@ ha_innobase::write_row( ha_statistic_increment(&SSV::ha_write_count); - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - sql_command = thd_sql_command(user_thd); if ((sql_command == SQLCOM_ALTER_TABLE @@ -9005,16 +9021,6 @@ wsrep_error: func_exit: innobase_active_small(); - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - DBUG_RETURN(error_result); } @@ -9425,16 +9431,6 @@ ha_innobase::update_row( ha_statistic_increment(&SSV::ha_update_count); - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - if (prebuilt->upd_node) { uvect = prebuilt->upd_node->update; } else { @@ -9540,16 +9536,6 @@ func_exit: wsrep_error: #endif /* WITH_WSREP */ - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - DBUG_RETURN(err); } @@ -9578,11 +9564,6 @@ ha_innobase::delete_row( ha_statistic_increment(&SSV::ha_delete_count); - if (UNIV_UNLIKELY(share && share->ib_table - && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - if (!prebuilt->upd_node) { row_get_prebuilt_update_vector(prebuilt); } @@ -9617,11 +9598,6 @@ ha_innobase::delete_row( wsrep_error: #endif /* WITH_WSREP */ - if (UNIV_UNLIKELY(share && share->ib_table - && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - DBUG_RETURN(convert_error_code_to_mysql( error, prebuilt->table->flags, user_thd)); } @@ -9872,17 +9848,13 @@ ha_innobase::index_read( ha_statistic_increment(&SSV::ha_read_key_count); - if (UNIV_UNLIKELY(srv_pass_corrupt_table <= 1 && share - && share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - index = prebuilt->index; if (UNIV_UNLIKELY(index == NULL) || dict_index_is_corrupted(index)) { prebuilt->index_usable = FALSE; DBUG_RETURN(HA_ERR_CRASHED); } + if (UNIV_UNLIKELY(!prebuilt->index_usable)) { DBUG_RETURN(dict_index_is_corrupted(index) ? HA_ERR_INDEX_CORRUPT @@ -9949,11 +9921,6 @@ ha_innobase::index_read( ret = DB_UNSUPPORTED; } - if (UNIV_UNLIKELY(srv_pass_corrupt_table <= 1 && share - && share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - switch (ret) { case DB_SUCCESS: error = 0; @@ -10113,11 +10080,6 @@ ha_innobase::change_active_index( { DBUG_ENTER("change_active_index"); - if (UNIV_UNLIKELY(srv_pass_corrupt_table <= 1 && share - && share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - ut_ad(user_thd == ha_thd()); ut_a(prebuilt->trx == thd_to_trx(user_thd)); @@ -10237,13 +10199,23 @@ ha_innobase::general_fetch( DBUG_RETURN(HA_ERR_END_OF_FILE); } - if (UNIV_UNLIKELY(srv_pass_corrupt_table <= 1 && share - && share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - ut_a(prebuilt->trx == thd_to_trx(user_thd)); + if (prebuilt->table->is_readable()) { + } else { + if (prebuilt->table->corrupted) { + DBUG_RETURN(HA_ERR_CRASHED); + } else { + FilSpace space(prebuilt->table->space, true); + + if (space()) { + DBUG_RETURN(HA_ERR_DECRYPTION_FAILED); + } else { + DBUG_RETURN(HA_ERR_NO_SUCH_TABLE); + } + } + } + innobase_srv_conc_enter_innodb(prebuilt->trx); ret = row_search_for_mysql( @@ -10251,11 +10223,6 @@ ha_innobase::general_fetch( innobase_srv_conc_exit_innodb(prebuilt->trx); - if (UNIV_UNLIKELY(srv_pass_corrupt_table <= 1 && share - && share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - switch (ret) { case DB_SUCCESS: error = 0; @@ -12984,7 +12951,7 @@ ha_innobase::discard_or_import_tablespace( user may want to set the DISCARD flag in order to IMPORT a new tablespace. */ - if (dict_table->ibd_file_missing) { + if (!dict_table->is_readable()) { ib_senderrf( prebuilt->trx->mysql_thd, IB_LOG_LEVEL_WARN, ER_TABLESPACE_MISSING, @@ -12994,7 +12961,7 @@ ha_innobase::discard_or_import_tablespace( err = row_discard_tablespace_for_mysql( dict_table->name, prebuilt->trx); - } else if (!dict_table->ibd_file_missing) { + } else if (dict_table->is_readable()) { /* Commit the transaction in order to release the table lock. */ trx_commit_for_mysql(prebuilt->trx); @@ -13071,15 +13038,7 @@ ha_innobase::truncate() update_thd(ha_thd()); - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } + DBUG_ASSERT(share->ib_table == prebuilt->table); if (UNIV_UNLIKELY(prebuilt->trx->fake_changes)) { DBUG_RETURN(HA_ERR_WRONG_COMMAND); @@ -13092,16 +13051,6 @@ ha_innobase::truncate() err = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } - switch (err) { case DB_TABLESPACE_DELETED: @@ -14502,15 +14451,7 @@ ha_innobase::analyze( { int ret; - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - return(HA_ADMIN_CORRUPT); - } + DBUG_ASSERT(share->ib_table == prebuilt->table); /* Simply call this->info_low() with all the flags and request recalculation of the statistics */ @@ -14518,15 +14459,7 @@ ha_innobase::analyze( HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE, true /* this is ANALYZE */); - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - return(HA_ADMIN_CORRUPT); - } + DBUG_ASSERT(share->ib_table == prebuilt->table); if (ret != 0) { return(HA_ADMIN_FAILED); @@ -14630,7 +14563,8 @@ ha_innobase::check( DBUG_RETURN(HA_ADMIN_CORRUPT); - } else if (prebuilt->table->ibd_file_missing) { + } else if (!prebuilt->table->is_readable() && + fil_space_get(prebuilt->table->space) == NULL) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, @@ -14704,6 +14638,7 @@ ha_innobase::check( server_mutex, srv_fatal_semaphore_wait_threshold, SRV_SEMAPHORE_WAIT_EXTENSION); + dberr_t err = btr_validate_index(index, prebuilt->trx); /* Restore the fatal lock wait timeout after @@ -14802,6 +14737,7 @@ ha_innobase::check( if (!(index->type & DICT_CLUSTERED)) { check_result = false; }); + if (!check_result) { innobase_format_name( index_name, sizeof index_name, @@ -15831,15 +15767,7 @@ ha_innobase::transactional_table_lock( update_thd(thd); - if (share->ib_table != prebuilt->table) { - fprintf(stderr, - "InnoDB: Warning: share->ib_table %p prebuilt->table %p table %s is_corrupt %lu.", - share->ib_table, prebuilt->table, prebuilt->table->name, prebuilt->table->is_corrupt); - } - - if (UNIV_UNLIKELY(share->ib_table && share->ib_table->is_corrupt)) { - DBUG_RETURN(HA_ERR_CRASHED); - } + DBUG_ASSERT(share->ib_table == prebuilt->table); if (!thd_tablespace_op(thd)) { @@ -15850,7 +15778,7 @@ ha_innobase::transactional_table_lock( ER_TABLESPACE_DISCARDED, table->s->table_name.str); - } else if (prebuilt->table->ibd_file_missing) { + } else if (!prebuilt->table->is_readable()) { ib_senderrf( thd, IB_LOG_LEVEL_ERROR, @@ -17478,11 +17406,11 @@ innodb_log_archive_update( if (in_val) { /* turn archiving on */ - srv_log_archive_on = innobase_log_archive = 1; + innobase_log_archive = srv_log_archive_on = 1; log_archive_archivelog(); } else { /* turn archivng off */ - srv_log_archive_on = innobase_log_archive = 0; + innobase_log_archive = srv_log_archive_on = 0; log_archive_noarchivelog(); } } @@ -22037,22 +21965,27 @@ ib_logf( str = static_cast<char*>(malloc(BUFSIZ)); my_vsnprintf(str, BUFSIZ, format, args); #endif /* __WIN__ */ - - switch(level) { - case IB_LOG_LEVEL_INFO: - sql_print_information("InnoDB: %s", str); - break; - case IB_LOG_LEVEL_WARN: - sql_print_warning("InnoDB: %s", str); - break; - case IB_LOG_LEVEL_ERROR: - sql_print_error("InnoDB: %s", str); - sd_notifyf(0, "STATUS=InnoDB: Error: %s", str); - break; - case IB_LOG_LEVEL_FATAL: - sql_print_error("InnoDB: %s", str); - sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str); - break; + if (!IS_XTRABACKUP()) { + switch (level) { + case IB_LOG_LEVEL_INFO: + sql_print_information("InnoDB: %s", str); + break; + case IB_LOG_LEVEL_WARN: + sql_print_warning("InnoDB: %s", str); + break; + case IB_LOG_LEVEL_ERROR: + sql_print_error("InnoDB: %s", str); + sd_notifyf(0, "STATUS=InnoDB: Error: %s", str); + break; + case IB_LOG_LEVEL_FATAL: + sql_print_error("InnoDB: %s", str); + sd_notifyf(0, "STATUS=InnoDB: Fatal: %s", str); + break; + } + } + else { + /* Don't use server logger for XtraBackup, just print to stderr. */ + fprintf(stderr, "InnoDB: %s\n", str); } va_end(args); diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index 39e7c952f5d..ef8c62849ae 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -3137,7 +3137,7 @@ prepare_inplace_alter_table_dict( clustered index of the old table, later. */ if (new_clustered || !ctx->online - || user_table->ibd_file_missing + || !user_table->is_readable() || dict_table_is_discarded(user_table)) { /* No need to allocate a modification log. */ ut_ad(!ctx->add_index[a]->online_log); @@ -3557,6 +3557,43 @@ ha_innobase::prepare_inplace_alter_table( goto func_exit; } + indexed_table = prebuilt->table; + + if (indexed_table->is_readable()) { + } else { + if (indexed_table->corrupted) { + /* Handled below */ + } else { + FilSpace space(indexed_table->space, true); + + if (space()) { + String str; + const char* engine= table_type(); + char buf[MAX_FULL_NAME_LEN]; + ut_format_name(indexed_table->name, TRUE, buf, sizeof(buf)); + + push_warning_printf(user_thd, Sql_condition::WARN_LEVEL_WARN, + HA_ERR_DECRYPTION_FAILED, + "Table %s in file %s is encrypted but encryption service or" + " used key_id is not available. " + " Can't continue reading table.", + buf, space()->chain.start->name); + + my_error(ER_GET_ERRMSG, MYF(0), HA_ERR_DECRYPTION_FAILED, str.c_ptr(), engine); + DBUG_RETURN(true); + } + } + } + + if (indexed_table->corrupted + || dict_table_get_first_index(indexed_table) == NULL + || dict_index_is_corrupted( + dict_table_get_first_index(indexed_table))) { + /* The clustered index is corrupted. */ + my_error(ER_CHECK_NO_SUCH_TABLE, MYF(0)); + DBUG_RETURN(true); + } + if (ha_alter_info->handler_flags & Alter_inplace_info::CHANGE_CREATE_OPTION) { /* Check engine specific table options */ @@ -4209,7 +4246,7 @@ ok_exit: DBUG_ASSERT(ctx->trx); DBUG_ASSERT(ctx->prebuilt == prebuilt); - if (prebuilt->table->ibd_file_missing + if (prebuilt->table->file_unreadable || dict_table_is_discarded(prebuilt->table)) { goto all_done; } @@ -5231,7 +5268,7 @@ commit_try_rebuild( /* The new table must inherit the flag from the "parent" table. */ if (dict_table_is_discarded(user_table)) { - rebuilt_table->ibd_file_missing = true; + rebuilt_table->file_unreadable = true; rebuilt_table->flags2 |= DICT_TF2_DISCARDED; } @@ -5763,9 +5800,9 @@ ha_innobase::commit_inplace_alter_table( if (ha_alter_info->group_commit_ctx) { ctx_array = ha_alter_info->group_commit_ctx; } else { - ctx_single[0] = ctx0; - ctx_single[1] = NULL; - ctx_array = ctx_single; + ctx_single[0] = ctx0; + ctx_single[1] = NULL; + ctx_array = ctx_single; } DBUG_ASSERT(ctx0 == ctx_array[0]); @@ -5794,6 +5831,19 @@ ha_innobase::commit_inplace_alter_table( = static_cast<ha_innobase_inplace_ctx*>(*pctx); DBUG_ASSERT(ctx->prebuilt->trx == prebuilt->trx); + /* If decryption failed for old table or new table + fail here. */ + if ((ctx->old_table->file_unreadable && + fil_space_get(ctx->old_table->space) != NULL)|| + (ctx->new_table->file_unreadable && + fil_space_get(ctx->new_table->space) != NULL)) { + String str; + const char* engine= table_type(); + get_error_message(HA_ERR_DECRYPTION_FAILED, &str); + my_error(ER_GET_ERRMSG, MYF(0), HA_ERR_DECRYPTION_FAILED, str.c_ptr(), engine); + DBUG_RETURN(true); + } + /* Exclusively lock the table, to ensure that no other transaction is holding locks on the table while we change the table definition. The MySQL meta-data lock |