diff options
author | unknown <knielsen@knielsen-hq.org> | 2011-12-14 14:58:22 +0100 |
---|---|---|
committer | unknown <knielsen@knielsen-hq.org> | 2011-12-14 14:58:22 +0100 |
commit | 6afbf295f018e077be7c569ef8e433e510441bea (patch) | |
tree | 2be3dc217f20980e3d2b8c6e933286d967b6ba58 /handler | |
parent | d4d7a8fa62c406be73f6c0f6d75e795293db548b (diff) | |
download | mariadb-git-6afbf295f018e077be7c569ef8e433e510441bea.tar.gz |
Updated with XtraDB from Percona Server 5.5.17-rel22.1
Files copied from Percona-Server-5.5.17-rel22.1.tar.gz source tarball.
Diffstat (limited to 'handler')
-rw-r--r-- | handler/ha_innodb.cc | 346 | ||||
-rw-r--r-- | handler/handler0alter.cc | 21 | ||||
-rw-r--r-- | handler/i_s.cc | 42 |
3 files changed, 351 insertions, 58 deletions
diff --git a/handler/ha_innodb.cc b/handler/ha_innodb.cc index 7a2d8e8fdbe..26212cca36e 100644 --- a/handler/ha_innodb.cc +++ b/handler/ha_innodb.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2011, MySQL AB & Innobase Oy. All Rights Reserved. +Copyright (c) 2000, 2011, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, 2009 Google Inc. Copyright (c) 2009, Percona Inc. @@ -193,16 +193,18 @@ static my_bool innobase_overwrite_relay_log_info = FALSE; static my_bool innobase_rollback_on_timeout = FALSE; static my_bool innobase_create_status_file = FALSE; static my_bool innobase_stats_on_metadata = TRUE; +static my_bool innobase_large_prefix = FALSE; static my_bool innobase_use_sys_stats_table = FALSE; static my_bool innobase_buffer_pool_shm_checksum = TRUE; static uint innobase_buffer_pool_shm_key = 0; -static my_bool innobase_large_prefix = FALSE; static char* internal_innobase_data_file_path = NULL; static char* innodb_version_str = (char*) INNODB_VERSION_STR; +static my_bool innobase_blocking_lru_restore = FALSE; + /** Possible values for system variable "innodb_stats_method". The values are defined the same as its corresponding MyISAM system variable "myisam_stats_method"(see "myisam_stats_method_names"), for better usability */ @@ -486,6 +488,12 @@ static MYSQL_THDVAR_ULONG(flush_log_at_trx_commit, PLUGIN_VAR_OPCMDARG, " or 2 (write at commit, flush once per second).", NULL, NULL, 1, 0, 2, 0); +static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG, + "In the transaction after enabled, UPDATE, INSERT and DELETE only move the cursor to the records " + "and do nothing other operations (no changes, no ibuf, no undo, no transaction log) in the transaction. " + "This is to cause replication prefetch IO. ATTENTION: the transaction started after enabled is affected.", + NULL, NULL, FALSE); + static handler *innobase_create_handler(handlerton *hton, TABLE_SHARE *table, @@ -673,6 +681,8 @@ static SHOW_VAR innodb_status_variables[]= { (char*) &export_vars.innodb_buffer_pool_pages_old, SHOW_LONG}, {"buffer_pool_pages_total", (char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG}, + {"buffer_pool_read_ahead_rnd", + (char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG}, {"buffer_pool_read_ahead", (char*) &export_vars.innodb_buffer_pool_read_ahead, SHOW_LONG}, {"buffer_pool_read_ahead_evicted", @@ -989,6 +999,19 @@ thd_flush_log_at_trx_commit( return(THDVAR((THD*) thd, flush_log_at_trx_commit)); } +/******************************************************************//** +Returns true if expand_fast_index_creation is enabled for the current +session. +@return the value of the server's expand_fast_index_creation variable */ +extern "C" UNIV_INTERN +ibool +thd_expand_fast_index_creation( +/*================================*/ + void* thd) +{ + return((ibool) (((THD*) thd)->variables.expand_fast_index_creation)); +} + /********************************************************************//** Obtain the InnoDB transaction of a MySQL thread. @return reference to transaction pointer */ @@ -1142,7 +1165,6 @@ convert_error_code_to_mysql( misleading, a new MySQL error code should be introduced */ - case DB_COL_APPEARS_TWICE_IN_INDEX: case DB_CORRUPTION: return(HA_ERR_CRASHED); @@ -1194,6 +1216,10 @@ convert_error_code_to_mysql( #endif /* HA_ERR_TOO_MANY_CONCURRENT_TRXS */ case DB_UNSUPPORTED: return(HA_ERR_UNSUPPORTED); + case DB_INDEX_CORRUPT: + return(HA_ERR_INDEX_CORRUPT); + case DB_UNDO_RECORD_TOO_BIG: + return(HA_ERR_UNDO_REC_TOO_BIG); } } @@ -1682,6 +1708,8 @@ innobase_trx_init( trx->check_unique_secondary = !thd_test_options( thd, OPTION_RELAXED_UNIQUE_CHECKS); + trx->fake_changes = THDVAR(thd, fake_changes); + #ifdef EXTENDED_SLOWLOG if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) { trx->take_stats = TRUE; @@ -2265,6 +2293,29 @@ no_db_name: } +/*****************************************************************//** +A wrapper function of innobase_convert_name(), convert a table or +index name to the MySQL system_charset_info (UTF-8) and quote it if needed. +@return pointer to the end of buf */ +static inline +void +innobase_format_name( +/*==================*/ + char* buf, /*!< out: buffer for converted identifier */ + ulint buflen, /*!< in: length of buf, in bytes */ + const char* name, /*!< in: index or table name to format */ + ibool is_index_name) /*!< in: index name */ +{ + const char* bufend; + + bufend = innobase_convert_name(buf, buflen, name, strlen(name), + NULL, !is_index_name); + + ut_ad((ulint) (bufend - buf) < buflen); + + buf[bufend - buf] = '\0'; +} + /**********************************************************************//** Determines if the currently running transaction has been interrupted. @return TRUE if interrupted */ @@ -2795,6 +2846,8 @@ innobase_change_buffering_inited_ok: srv_use_checksums = (ibool) innobase_use_checksums; srv_fast_checksum = (ibool) innobase_fast_checksum; + srv_blocking_lru_restore = (ibool) innobase_blocking_lru_restore; + #ifdef HAVE_LARGE_PAGES if ((os_use_large_pages = (ibool) my_use_large_pages)) os_large_page_size = (ulint) opt_large_page_size; @@ -2828,6 +2881,10 @@ innobase_change_buffering_inited_ok: innobase_commit_concurrency_init_default(); +#ifndef EXTENDED_FOR_KILLIDLE + srv_kill_idle_transaction = 0; +#endif + #ifdef HAVE_PSI_INTERFACE /* Register keys with MySQL performance schema */ if (PSI_server) { @@ -3160,6 +3217,11 @@ innobase_commit( trx_search_latch_release_if_reserved(trx); } + if (trx->fake_changes && (all || (!thd_test_options(thd, OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) { + innobase_rollback(hton, thd, all); /* rollback implicitly */ + thd->stmt_da->reset_diagnostics_area(); /* because debug assertion code complains, if something left */ + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } /* Transaction is deregistered only in a commit or a rollback. If it is deregistered we know there cannot be resources to be freed and we could return immediately. For the time being, we play safe @@ -4188,11 +4250,11 @@ retry: DBUG_RETURN(HA_ERR_CRASHED_ON_USAGE); } - if (share->ib_table) { - ut_a(share->ib_table == ib_table); - } else { - share->ib_table = ib_table; - } + share->ib_table = ib_table; + + + + if (NULL == ib_table) { if (is_part && retries < 10) { @@ -4493,25 +4555,6 @@ field_in_record_is_null( return(0); } -/**************************************************************//** -Sets a field in a record to SQL NULL. Uses the record format -information in table to track the null bit in record. */ -static inline -void -set_field_in_record_to_null( -/*========================*/ - TABLE* table, /*!< in: MySQL table object */ - Field* field, /*!< in: MySQL field object */ - char* record) /*!< in: a row in MySQL format */ -{ - int null_offset; - - null_offset = (uint) ((char*) field->null_ptr - - (char*) table->record[0]); - - record[null_offset] = record[null_offset] | field->null_bit; -} - /*************************************************************//** InnoDB uses this function to compare two data fields for which the data type is such that we must use MySQL code to compare them. NOTE that the prototype @@ -6160,12 +6203,14 @@ ha_innobase::index_read( index = prebuilt->index; - if (UNIV_UNLIKELY(index == NULL)) { + 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(HA_ERR_TABLE_DEF_CHANGED); + DBUG_RETURN(dict_index_is_corrupted(index) + ? HA_ERR_INDEX_CORRUPT + : HA_ERR_TABLE_DEF_CHANGED); } /* Note that if the index for which the search template is built is not @@ -6233,7 +6278,7 @@ ha_innobase::index_read( table->status = 0; #ifdef EXTENDED_FOR_USERSTAT rows_read++; - if (active_index >= 0 && active_index < MAX_KEY) + if (active_index < MAX_KEY) index_rows_read[active_index]++; #endif break; @@ -6364,10 +6409,33 @@ ha_innobase::change_active_index( prebuilt->index); if (UNIV_UNLIKELY(!prebuilt->index_usable)) { - push_warning_printf(user_thd, MYSQL_ERROR::WARN_LEVEL_WARN, - HA_ERR_TABLE_DEF_CHANGED, - "InnoDB: insufficient history for index %u", - keynr); + if (dict_index_is_corrupted(prebuilt->index)) { + char index_name[MAX_FULL_NAME_LEN + 1]; + char table_name[MAX_FULL_NAME_LEN + 1]; + + innobase_format_name( + index_name, sizeof index_name, + prebuilt->index->name, TRUE); + + innobase_format_name( + table_name, sizeof table_name, + prebuilt->index->table->name, FALSE); + + push_warning_printf( + user_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_INDEX_CORRUPT, + "InnoDB: Index %s for table %s is" + " marked as corrupted", + index_name, table_name); + DBUG_RETURN(1); + } else { + push_warning_printf( + user_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_TABLE_DEF_CHANGED, + "InnoDB: insufficient history for index %u", + keynr); + } + /* The caller seems to ignore this. Thus, we must check this again in row_search_for_mysql(). */ DBUG_RETURN(2); @@ -6459,7 +6527,7 @@ ha_innobase::general_fetch( table->status = 0; #ifdef EXTENDED_FOR_USERSTAT rows_read++; - if (active_index >= 0 && active_index < MAX_KEY) + if (active_index < MAX_KEY) index_rows_read[active_index]++; #endif break; @@ -7503,6 +7571,12 @@ ha_innobase::create( trx = innobase_trx_allocate(thd); + if (trx->fake_changes) { + innobase_commit_low(trx); + trx_free_for_mysql(trx); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + /* Latch the InnoDB data dictionary exclusively so that no deadlocks or lock waits can happen in it during a table create operation. Drop table etc. do this latching in row0mysql.c. */ @@ -7723,6 +7797,10 @@ ha_innobase::truncate(void) DBUG_RETURN(HA_ERR_CRASHED); } + if (prebuilt->trx->fake_changes) { + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + /* Truncate the table in InnoDB */ error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx); @@ -7779,6 +7857,12 @@ ha_innobase::delete_table( trx = innobase_trx_allocate(thd); + if (trx->fake_changes) { + innobase_commit_low(trx); + trx_free_for_mysql(trx); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + name_len = strlen(name); ut_a(name_len < 1000); @@ -7865,6 +7949,12 @@ innobase_drop_database( trx->mysql_thd = NULL; #else trx = innobase_trx_allocate(thd); + if (trx->fake_changes) { + my_free(namebuf); + innobase_commit_low(trx); + trx_free_for_mysql(trx); + return; /* ignore */ + } #endif row_drop_database_for_mysql(namebuf, trx); my_free(namebuf); @@ -7970,6 +8060,11 @@ ha_innobase::rename_table( trx_search_latch_release_if_reserved(parent_trx); trx = innobase_trx_allocate(thd); + if (trx->fake_changes) { + innobase_commit_low(trx); + trx_free_for_mysql(trx); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } error = innobase_rename_table(trx, from, to, TRUE); @@ -8056,6 +8151,10 @@ ha_innobase::records_in_range( n_rows = HA_POS_ERROR; goto func_exit; } + if (dict_index_is_corrupted(index)) { + n_rows = HA_ERR_INDEX_CORRUPT; + goto func_exit; + } if (UNIV_UNLIKELY(!row_merge_is_index_usable(prebuilt->trx, index))) { n_rows = HA_ERR_TABLE_DEF_CHANGED; goto func_exit; @@ -8470,6 +8569,8 @@ ha_innobase::info_low( if (flag & HA_STATUS_VARIABLE) { + ulint page_size; + dict_table_stats_lock(ib_table, RW_S_LATCH); n_rows = ib_table->stat_n_rows; @@ -8512,14 +8613,19 @@ ha_innobase::info_low( prebuilt->autoinc_last_value = 0; } + page_size = dict_table_zip_size(ib_table); + if (page_size == 0) { + page_size = UNIV_PAGE_SIZE; + } + stats.records = (ha_rows)n_rows; stats.deleted = 0; - stats.data_file_length = ((ulonglong) - ib_table->stat_clustered_index_size) - * UNIV_PAGE_SIZE; - stats.index_file_length = ((ulonglong) - ib_table->stat_sum_of_other_index_sizes) - * UNIV_PAGE_SIZE; + stats.data_file_length + = ((ulonglong) ib_table->stat_clustered_index_size) + * page_size; + stats.index_file_length = + ((ulonglong) ib_table->stat_sum_of_other_index_sizes) + * page_size; dict_table_stats_unlock(ib_table, RW_S_LATCH); @@ -8757,6 +8863,7 @@ ha_innobase::check( ulint n_rows_in_table = ULINT_UNDEFINED; ibool is_ok = TRUE; ulint old_isolation_level; + ibool table_corrupted; DBUG_ENTER("ha_innobase::check"); DBUG_ASSERT(thd == ha_thd()); @@ -8798,6 +8905,14 @@ ha_innobase::check( prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ; + /* Check whether the table is already marked as corrupted + before running the check table */ + table_corrupted = prebuilt->table->corrupted; + + /* Reset table->corrupted bit so that check table can proceed to + do additional check */ + prebuilt->table->corrupted = FALSE; + /* Enlarge the fatal lock wait timeout during CHECK TABLE. */ mutex_enter(&kernel_mutex); srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */ @@ -8806,6 +8921,7 @@ ha_innobase::check( for (index = dict_table_get_first_index(prebuilt->table); index != NULL; index = dict_table_get_next_index(index)) { + char index_name[MAX_FULL_NAME_LEN + 1]; #if 0 fputs("Validating index ", stderr); ut_print_name(stderr, trx, FALSE, index->name); @@ -8814,11 +8930,16 @@ ha_innobase::check( if (!btr_validate_index(index, prebuilt->trx)) { is_ok = FALSE; + + innobase_format_name( + index_name, sizeof index_name, + prebuilt->index->name, TRUE); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NOT_KEYFILE, "InnoDB: The B-tree of" - " index '%-.200s' is corrupted.", - index->name); + " index %s is corrupted.", + index_name); continue; } @@ -8831,11 +8952,26 @@ ha_innobase::check( prebuilt->trx, prebuilt->index); if (UNIV_UNLIKELY(!prebuilt->index_usable)) { - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, - HA_ERR_TABLE_DEF_CHANGED, - "InnoDB: Insufficient history for" - " index '%-.200s'", - index->name); + innobase_format_name( + index_name, sizeof index_name, + prebuilt->index->name, TRUE); + + if (dict_index_is_corrupted(prebuilt->index)) { + push_warning_printf( + user_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_INDEX_CORRUPT, + "InnoDB: Index %s is marked as" + " corrupted", + index_name); + is_ok = FALSE; + } else { + push_warning_printf( + thd, MYSQL_ERROR::WARN_LEVEL_WARN, + HA_ERR_TABLE_DEF_CHANGED, + "InnoDB: Insufficient history for" + " index %s", + index_name); + } continue; } @@ -8849,12 +8985,19 @@ ha_innobase::check( prebuilt->select_lock_type = LOCK_NONE; if (!row_check_index_for_mysql(prebuilt, index, &n_rows)) { + innobase_format_name( + index_name, sizeof index_name, + index->name, TRUE); + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_NOT_KEYFILE, "InnoDB: The B-tree of" - " index '%-.200s' is corrupted.", - index->name); + " index %s is corrupted.", + index_name); is_ok = FALSE; + row_mysql_lock_data_dictionary(prebuilt->trx); + dict_set_corrupted(index); + row_mysql_unlock_data_dictionary(prebuilt->trx); } if (thd_killed(user_thd)) { @@ -8881,6 +9024,20 @@ ha_innobase::check( } } + if (table_corrupted) { + /* If some previous operation has marked the table as + corrupted in memory, and has not propagated such to + clustered index, we will do so here */ + index = dict_table_get_first_index(prebuilt->table); + + if (!dict_index_is_corrupted(index)) { + mutex_enter(&dict_sys->mutex); + dict_set_corrupted(index); + mutex_exit(&dict_sys->mutex); + } + prebuilt->table->corrupted = TRUE; + } + /* Restore the original isolation level */ prebuilt->trx->isolation_level = old_isolation_level; @@ -10768,6 +10925,10 @@ innobase_xa_prepare( return(0); } + if (trx->fake_changes) { + return(0); + } + thd_get_xid(thd, (MYSQL_XID*) &trx->xid); /* Release a possible FIFO ticket and search latch. Since we will @@ -11586,6 +11747,57 @@ innobase_index_name_is_reserved( return(false); } +/*********************************************************************** +functions for kill session of idle transaction */ +extern "C" +ibool +innobase_thd_is_idle( +/*=================*/ + const void* thd) /*!< in: thread handle (THD*) */ +{ +#ifdef EXTENDED_FOR_KILLIDLE + return(thd_command((const THD*) thd) == COM_SLEEP); +#else + return(FALSE); +#endif +} + +extern "C" +ib_int64_t +innobase_thd_get_start_time( +/*========================*/ + const void* thd) /*!< in: thread handle (THD*) */ +{ +#ifdef EXTENDED_FOR_KILLIDLE + return((ib_int64_t)thd_start_time((const THD*) thd)); +#else + return(0); /*dummy value*/ +#endif +} + +extern "C" +void +innobase_thd_kill( +/*==============*/ + ulong thd_id) +{ +#ifdef EXTENDED_FOR_KILLIDLE + thd_kill(thd_id); +#else + return; +#endif +} + +extern "C" +ulong +innobase_thd_get_thread_id( +/*=======================*/ + const void* thd) +{ + return(thd_get_thread_id((const THD*) thd)); +} + + static SHOW_VAR innodb_status_variables_export[]= { {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, {NullS, NullS, SHOW_LONG} @@ -11731,6 +11943,11 @@ static MYSQL_SYSVAR_BOOL(large_prefix, innobase_large_prefix, "Support large index prefix length of REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes.", NULL, NULL, FALSE); +static MYSQL_SYSVAR_BOOL(force_load_corrupted, srv_load_corrupted, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "Force InnoDB to load metadata of corrupted table.", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog, PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, "Force InnoDB to not use next-key locking, to use only row-level locking.", @@ -11872,6 +12089,15 @@ static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter, "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket", NULL, NULL, 500L, 1L, ~0L, 0); +static MYSQL_SYSVAR_LONG(kill_idle_transaction, srv_kill_idle_transaction, + PLUGIN_VAR_RQCMDARG, +#ifdef EXTENDED_FOR_KILLIDLE + "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB.", +#else + "No effect for this build.", +#endif + NULL, NULL, 0, 0, LONG_MAX, 0); + static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR, "Number of file I/O threads in InnoDB.", @@ -12012,6 +12238,11 @@ static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug, NULL, NULL, 0, 0, 1, 0); #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ +static MYSQL_SYSVAR_BOOL(random_read_ahead, srv_random_read_ahead, + PLUGIN_VAR_NOCMDARG, + "Whether to use read ahead for random access within an extent.", + NULL, NULL, FALSE); + static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold, PLUGIN_VAR_RQCMDARG, "Number of pages that must be accessed sequentially for InnoDB to " @@ -12123,6 +12354,13 @@ static MYSQL_SYSVAR_UINT(buffer_pool_restore_at_startup, srv_auto_lru_dump, "0 (the default) disables automatic dumps.", NULL, NULL, 0, 0, UINT_MAX32, 0); +static MYSQL_SYSVAR_BOOL(blocking_buffer_pool_restore, + innobase_blocking_lru_restore, + PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY, + "Block XtraDB startup process until buffer pool is full restored from a " + "dump file (if present). Disabled by default.", + NULL, NULL, FALSE); + const char *corrupt_table_action_names[]= { "assert", /* 0 */ @@ -12162,6 +12400,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(fast_checksum), MYSQL_SYSVAR(commit_concurrency), MYSQL_SYSVAR(concurrency_tickets), + MYSQL_SYSVAR(kill_idle_transaction), MYSQL_SYSVAR(data_file_path), MYSQL_SYSVAR(doublewrite_file), MYSQL_SYSVAR(data_home_dir), @@ -12180,6 +12419,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(flush_method), MYSQL_SYSVAR(force_recovery), MYSQL_SYSVAR(large_prefix), + MYSQL_SYSVAR(force_load_corrupted), MYSQL_SYSVAR(locks_unsafe_for_binlog), MYSQL_SYSVAR(lock_wait_timeout), #ifdef UNIV_LOG_ARCHIVE @@ -12236,14 +12476,17 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { #if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG MYSQL_SYSVAR(change_buffering_debug), #endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */ + MYSQL_SYSVAR(random_read_ahead), MYSQL_SYSVAR(read_ahead_threshold), MYSQL_SYSVAR(io_capacity), MYSQL_SYSVAR(buffer_pool_restore_at_startup), + MYSQL_SYSVAR(blocking_buffer_pool_restore), MYSQL_SYSVAR(purge_threads), MYSQL_SYSVAR(purge_batch_size), MYSQL_SYSVAR(rollback_segments), MYSQL_SYSVAR(corrupt_table_action), MYSQL_SYSVAR(lazy_drop_table), + MYSQL_SYSVAR(fake_changes), NULL }; @@ -12260,7 +12503,8 @@ mysql_declare_plugin(innobase) INNODB_VERSION_SHORT, innodb_status_variables_export,/* status variables */ innobase_system_variables, /* system variables */ - NULL /* reserved */ + NULL, /* reserved */ + 0, /* flags */ }, i_s_innodb_rseg, i_s_innodb_trx, diff --git a/handler/handler0alter.cc b/handler/handler0alter.cc index 6d5b7b4668f..8c5783fa8b9 100644 --- a/handler/handler0alter.cc +++ b/handler/handler0alter.cc @@ -695,6 +695,10 @@ ha_innobase::add_index( possible adaptive hash latch to avoid deadlocks of threads. */ trx_search_latch_release_if_reserved(prebuilt->trx); + if (prebuilt->trx->fake_changes) { + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + /* Check if the index name is reserved. */ if (innobase_index_name_is_reserved(user_thd, key_info, num_of_keys)) { DBUG_RETURN(-1); @@ -732,6 +736,13 @@ ha_innobase::add_index( /* Create a background transaction for the operations on the data dictionary tables. */ trx = innobase_trx_allocate(user_thd); + if (trx->fake_changes) { + mem_heap_free(heap); + trx_general_rollback_for_mysql(trx, NULL); + trx_free_for_mysql(trx); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + trx_start_if_not_started(trx); /* Create table containing all indexes to be built in this @@ -1092,6 +1103,10 @@ ha_innobase::prepare_drop_index( trx_search_latch_release_if_reserved(prebuilt->trx); trx = prebuilt->trx; + if (trx->fake_changes) { + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + /* Test and mark all the indexes to be dropped */ row_mysql_lock_data_dictionary(trx); @@ -1296,6 +1311,12 @@ ha_innobase::final_drop_index( /* Create a background transaction for the operations on the data dictionary tables. */ trx = innobase_trx_allocate(user_thd); + if (trx->fake_changes) { + trx_general_rollback_for_mysql(trx, NULL); + trx_free_for_mysql(trx); + DBUG_RETURN(HA_ERR_WRONG_COMMAND); + } + trx_start_if_not_started(trx); /* Flag this transaction as a dictionary operation, so that diff --git a/handler/i_s.cc b/handler/i_s.cc index 839dce206d3..c0ad731e336 100644 --- a/handler/i_s.cc +++ b/handler/i_s.cc @@ -645,7 +645,11 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_trx = /* reserved for dependency checking */ /* void* */ - STRUCT_FLD(__reserved1, NULL) + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_locks */ @@ -911,7 +915,11 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_locks = /* reserved for dependency checking */ /* void* */ - STRUCT_FLD(__reserved1, NULL) + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), }; /* Fields of the dynamic table INFORMATION_SCHEMA.innodb_lock_waits */ @@ -1094,7 +1102,11 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_lock_waits = /* reserved for dependency checking */ /* void* */ - STRUCT_FLD(__reserved1, NULL) + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), }; /*******************************************************************//** @@ -1427,7 +1439,11 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp = /* reserved for dependency checking */ /* void* */ - STRUCT_FLD(__reserved1, NULL) + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), }; UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset = @@ -1477,7 +1493,11 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmp_reset = /* reserved for dependency checking */ /* void* */ - STRUCT_FLD(__reserved1, NULL) + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), }; /* Fields of the dynamic table information_schema.innodb_cmpmem. */ @@ -1720,7 +1740,11 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem = /* reserved for dependency checking */ /* void* */ - STRUCT_FLD(__reserved1, NULL) + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), }; UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset = @@ -1770,7 +1794,11 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_cmpmem_reset = /* reserved for dependency checking */ /* void* */ - STRUCT_FLD(__reserved1, NULL) + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), }; /*******************************************************************//** |