diff options
author | Sergei Golubchik <sergii@pisem.net> | 2012-09-05 10:44:23 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2012-09-05 10:44:23 +0200 |
commit | 0352f09a2e3e17470ab75678265b98a275cb25a0 (patch) | |
tree | 8f805f4f08cb293c01d7ee269db7ea2b6b715e3b /handler | |
parent | 651ac12e8821a994e6176e63eef3e87b70f9746c (diff) | |
download | mariadb-git-0352f09a2e3e17470ab75678265b98a275cb25a0.tar.gz |
Percona-Server-5.5.27-rel28.1
Diffstat (limited to 'handler')
-rw-r--r-- | handler/ha_innodb.cc | 51 | ||||
-rw-r--r-- | handler/handler0alter.cc | 18 | ||||
-rw-r--r-- | handler/i_s.cc | 245 | ||||
-rw-r--r-- | handler/i_s.h | 1 |
4 files changed, 297 insertions, 18 deletions
diff --git a/handler/ha_innodb.cc b/handler/ha_innodb.cc index a1a60aa2276..f5eea6d086b 100644 --- a/handler/ha_innodb.cc +++ b/handler/ha_innodb.cc @@ -49,6 +49,7 @@ this program; if not, write to the Free Software Foundation, Inc., #include <sql_acl.h> // PROCESS_ACL #include <m_ctype.h> +#include <debug_sync.h> // DEBUG_SYNC #include <mysys_err.h> #include <mysql/plugin.h> #include <mysql/innodb_priv.h> @@ -500,6 +501,9 @@ static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG, "This is to cause replication prefetch IO. ATTENTION: the transaction started after enabled is affected.", NULL, NULL, FALSE); +static MYSQL_THDVAR_ULONG(merge_sort_block_size, PLUGIN_VAR_RQCMDARG, + "The block size used doing external merge-sort for secondary index creation.", + NULL, NULL, 1UL << 20, 1UL << 20, 1UL << 30, 0); static handler *innobase_create_handler(handlerton *hton, TABLE_SHARE *table, @@ -1018,6 +1022,20 @@ thd_expand_fast_index_creation( return((ibool) (((THD*) thd)->variables.expand_fast_index_creation)); } +/******************************************************************//** +Returns the merge-sort block size used for the secondary index creation +for the current connection. +@return the merge-sort block size, in bytes */ +extern "C" UNIV_INTERN +ulong +thd_merge_sort_block_size( +/*================================*/ + void* thd) /*!< in: thread handle (THD*), or NULL to query ++ the global merge_sort_block_size */ +{ + return(THDVAR((THD*) thd, merge_sort_block_size)); +} + /********************************************************************//** Obtain the InnoDB transaction of a MySQL thread. @return reference to transaction pointer */ @@ -2900,6 +2918,7 @@ innobase_change_buffering_inited_ok: srv_read_ahead &= 3; srv_adaptive_flushing_method %= 3; + srv_flush_neighbor_pages %= 3; srv_force_recovery = (ulint) innobase_force_recovery; @@ -6573,6 +6592,7 @@ ha_innobase::index_read( ulint ret; DBUG_ENTER("index_read"); + DEBUG_SYNC_C("ha_innobase_index_read_begin"); ut_a(prebuilt->trx == thd_to_trx(user_thd)); ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT); @@ -8458,6 +8478,8 @@ ha_innobase::rename_table( error = innobase_rename_table(trx, from, to, TRUE); + DEBUG_SYNC(thd, "after_innobase_rename_table"); + /* Tell the InnoDB server that there might be work for utility threads: */ @@ -8784,10 +8806,15 @@ innobase_get_mysql_key_number_for_index( } } - /* Print an error message if we cannot find the index - ** in the "index translation table". */ - sql_print_error("Cannot find index %s in InnoDB index " - "translation table.", index->name); + /* If index_count in translation table is set to 0, it + is possible we are in the process of rebuilding table, + do not spit error in this case */ + if (share->idx_trans_tbl.index_count) { + /* Print an error message if we cannot find the index + ** in the "index translation table". */ + sql_print_error("Cannot find index %s in InnoDB index " + "translation table.", index->name); + } } /* If we do not have an "index translation table", or not able @@ -12251,7 +12278,7 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite, static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity, PLUGIN_VAR_RQCMDARG, "Number of IOPs the server can do. Tunes the background IO rate", - NULL, NULL, 200, 100, ~0L, 0); + NULL, NULL, 200, 100, ~0UL, 0); static MYSQL_SYSVAR_ULONG(purge_batch_size, srv_purge_batch_size, PLUGIN_VAR_OPCMDARG, @@ -12384,7 +12411,7 @@ static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing, static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag, PLUGIN_VAR_RQCMDARG, "Desired maximum length of the purge queue (0 = no limit)", - NULL, NULL, 0, 0, ~0L, 0); + NULL, NULL, 0, 0, ~0UL, 0); static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, @@ -12488,7 +12515,7 @@ static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency, static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter, PLUGIN_VAR_RQCMDARG, "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); + NULL, NULL, 500L, 1L, ~0UL, 0); static MYSQL_SYSVAR_LONG(kill_idle_transaction, srv_kill_idle_transaction, PLUGIN_VAR_RQCMDARG, @@ -12559,12 +12586,12 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files, static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds, PLUGIN_VAR_RQCMDARG, "Count of spin-loop rounds in InnoDB mutexes (30 by default)", - NULL, NULL, 30L, 0L, ~0L, 0); + NULL, NULL, 30L, 0L, ~0UL, 0); static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay, PLUGIN_VAR_OPCMDARG, "Maximum delay between polling for a spin lock (6 by default)", - NULL, NULL, 6L, 0L, ~0L, 0); + NULL, NULL, 6L, 0L, ~0UL, 0); static MYSQL_SYSVAR_BOOL(thread_concurrency_timer_based, innobase_thread_concurrency_timer_based, @@ -12580,7 +12607,7 @@ static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency, static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay, PLUGIN_VAR_RQCMDARG, "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep", - NULL, NULL, 10000L, 0L, ~0L, 0); + NULL, NULL, 10000L, 0L, ~0UL, 0); static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, @@ -12755,7 +12782,7 @@ innodb_adaptive_flushing_method_update( void* var_ptr, const void* save) { - *(long *)var_ptr= (*(long *)save) % 4; + *(long *)var_ptr= (*(long *)save) % 3; } const char *adaptive_flushing_method_names[]= { @@ -12933,6 +12960,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= { MYSQL_SYSVAR(corrupt_table_action), MYSQL_SYSVAR(lazy_drop_table), MYSQL_SYSVAR(fake_changes), + MYSQL_SYSVAR(merge_sort_block_size), NULL }; @@ -12953,6 +12981,7 @@ mysql_declare_plugin(innobase) 0, /* flags */ }, i_s_innodb_rseg, +i_s_innodb_undo_logs, i_s_innodb_trx, i_s_innodb_locks, i_s_innodb_lock_waits, diff --git a/handler/handler0alter.cc b/handler/handler0alter.cc index 398e8bee425..46ffc28180d 100644 --- a/handler/handler0alter.cc +++ b/handler/handler0alter.cc @@ -712,6 +712,10 @@ ha_innobase::add_index( ut_a(indexed_table == prebuilt->table); + if (indexed_table->tablespace_discarded) { + DBUG_RETURN(-1); + } + /* Check that index keys are sensible */ error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table); @@ -780,7 +784,7 @@ ha_innobase::add_index( row_mysql_lock_data_dictionary(trx); dict_locked = TRUE; - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); /* If a new primary key is defined for the table we need to drop the original table and rebuild all indexes. */ @@ -816,7 +820,7 @@ ha_innobase::add_index( } ut_d(dict_table_check_for_dup_indexes(prebuilt->table, - FALSE)); + TRUE)); mem_heap_free(heap); trx_general_rollback_for_mysql(trx, NULL); row_mysql_unlock_data_dictionary(trx); @@ -1070,7 +1074,7 @@ ha_innobase::final_add_index( trx_commit_for_mysql(prebuilt->trx); } - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); row_mysql_unlock_data_dictionary(trx); trx_free_for_mysql(trx); @@ -1117,7 +1121,7 @@ ha_innobase::prepare_drop_index( /* Test and mark all the indexes to be dropped */ row_mysql_lock_data_dictionary(trx); - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); /* Check that none of the indexes have previously been flagged for deletion. */ @@ -1288,7 +1292,7 @@ func_exit: } while (index); } - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); row_mysql_unlock_data_dictionary(trx); DBUG_RETURN(err); @@ -1341,7 +1345,7 @@ ha_innobase::final_drop_index( prebuilt->table->flags, user_thd); row_mysql_lock_data_dictionary(trx); - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); if (UNIV_UNLIKELY(err)) { @@ -1385,7 +1389,7 @@ ha_innobase::final_drop_index( share->idx_trans_tbl.index_count = 0; func_exit: - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); trx_commit_for_mysql(trx); trx_commit_for_mysql(prebuilt->trx); row_mysql_unlock_data_dictionary(trx); diff --git a/handler/i_s.cc b/handler/i_s.cc index a7b453846f7..c03ecb15e1c 100644 --- a/handler/i_s.cc +++ b/handler/i_s.cc @@ -48,6 +48,7 @@ extern "C" { #include "trx0i_s.h" #include "trx0trx.h" /* for TRX_QUE_STATE_STR_MAX_LEN */ #include "trx0rseg.h" /* for trx_rseg_struct */ +#include "trx0undo.h" /* for trx_undo_struct */ #include "trx0sys.h" /* for trx_sys */ #include "dict0dict.h" /* for dict_sys */ #include "buf0lru.h" /* for XTRA_LRU_[DUMP/RESTORE] */ @@ -5144,3 +5145,247 @@ UNIV_INTERN struct st_mysql_plugin i_s_innodb_buffer_pool_pages_blob = STRUCT_FLD(flags, 0UL) }; + +static ST_FIELD_INFO i_s_innodb_undo_logs_fields_info[] = +{ +#define IDX_USEG_TRX_ID 0 + {STRUCT_FLD(field_name, "trx_id"), + STRUCT_FLD(field_length, TRX_ID_MAX_LEN + 1), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_USEG_RSEG_ID 1 + {STRUCT_FLD(field_name, "rseg_id"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_USEG_USEG_ID 2 + {STRUCT_FLD(field_name, "useg_id"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_USEG_TYPE 3 +#define USEG_TYPE_MAX_LEN 256 + {STRUCT_FLD(field_name, "type"), + STRUCT_FLD(field_length, USEG_TYPE_MAX_LEN), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + + #define IDX_USEG_STATE 4 + #define USEG_STATE_MAX_LEN 256 + {STRUCT_FLD(field_name, "state"), + STRUCT_FLD(field_length, USEG_STATE_MAX_LEN), + STRUCT_FLD(field_type, MYSQL_TYPE_STRING), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, 0), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + +#define IDX_USEG_SIZE 5 + {STRUCT_FLD(field_name, "size"), + STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS), + STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG), + STRUCT_FLD(value, 0), + STRUCT_FLD(field_flags, MY_I_S_UNSIGNED), + STRUCT_FLD(old_name, ""), + STRUCT_FLD(open_method, SKIP_OPEN_TABLE)}, + + END_OF_ST_FIELD_INFO +}; +static +int +i_s_innodb_undo_logs_fill_store( +/*=================*/ + THD* thd, /* in: thread */ + TABLE* table, /* in/out: table to fill */ + trx_undo_t* useg) /* in: useg to fill from */ +{ + char trx_id[TRX_ID_MAX_LEN + 1]; + + DBUG_ENTER("i_s_innodb_undo_logs_fill_store"); + + switch (useg->type) { + case TRX_UNDO_INSERT: + OK(field_store_string(table->field[IDX_USEG_TYPE], "INSERT")); + break; + case TRX_UNDO_UPDATE: + OK(field_store_string(table->field[IDX_USEG_TYPE], "UPDATE")); + break; + default: + OK(field_store_string(table->field[IDX_USEG_TYPE], "UNKNOWN")); + break; + } + + ut_snprintf(trx_id, sizeof(trx_id), TRX_ID_FMT, useg->trx_id); + + switch (useg->state) { + case TRX_UNDO_ACTIVE: + OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id)); + OK(field_store_string(table->field[IDX_USEG_STATE], "ACTIVE")); + break; + case TRX_UNDO_CACHED: + OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL)); + OK(field_store_string(table->field[IDX_USEG_STATE], "CACHED")); + break; + case TRX_UNDO_TO_FREE: + OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL)); + OK(field_store_string(table->field[IDX_USEG_STATE], "TO_FREE")); + break; + case TRX_UNDO_TO_PURGE: + OK(field_store_string(table->field[IDX_USEG_TRX_ID], NULL)); + OK(field_store_string(table->field[IDX_USEG_STATE], "TO_PURGE")); + break; + case TRX_UNDO_PREPARED: + OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id)); + OK(field_store_string(table->field[IDX_USEG_STATE], "PREPARED")); + break; + default: + OK(field_store_string(table->field[IDX_USEG_TRX_ID], trx_id)); + OK(field_store_string(table->field[IDX_USEG_STATE], "UNKNOWN")); + break; + } + + table->field[IDX_USEG_RSEG_ID]->store(useg->rseg->id); + table->field[IDX_USEG_USEG_ID]->store(useg->id); + table->field[IDX_USEG_SIZE]->store(useg->size); + if (schema_table_store_record(thd, table)) { + DBUG_RETURN(1); + } + DBUG_RETURN(0); +} +static +int +i_s_innodb_undo_logs_fill( +/*=================*/ + THD* thd, /* in: thread */ + TABLE_LIST* tables, /* in/out: tables to fill */ + COND* cond) /* in: condition (ignored) */ +{ + TABLE* table = (TABLE *) tables->table; + int status = 0; + trx_rseg_t* rseg; + trx_undo_t* useg; + + DBUG_ENTER("i_s_innodb_undo_logs_fill"); + + /* deny access to non-superusers */ + if (check_global_access(thd, PROCESS_ACL)) { + DBUG_RETURN(0); + } + + RETURN_IF_INNODB_NOT_STARTED(tables->schema_table_name); + + rseg = UT_LIST_GET_FIRST(trx_sys->rseg_list); + while (rseg && status == 0) { + mutex_enter(&(rseg->mutex)); + useg = UT_LIST_GET_FIRST(rseg->update_undo_list); + while (useg && status == 0) { + status = i_s_innodb_undo_logs_fill_store(thd, table, useg); + useg = UT_LIST_GET_NEXT(undo_list, useg); + } + + useg = UT_LIST_GET_FIRST(rseg->update_undo_cached); + while (useg && status == 0) { + status = i_s_innodb_undo_logs_fill_store(thd, table, useg); + useg = UT_LIST_GET_NEXT(undo_list, useg); + } + + useg = UT_LIST_GET_FIRST(rseg->insert_undo_list); + while (useg && status == 0) { + status = i_s_innodb_undo_logs_fill_store(thd, table, useg); + useg = UT_LIST_GET_NEXT(undo_list, useg); + } + + useg = UT_LIST_GET_FIRST(rseg->insert_undo_cached); + while (useg && status == 0) { + status = i_s_innodb_undo_logs_fill_store(thd, table, useg); + useg = UT_LIST_GET_NEXT(undo_list, useg); + } + mutex_exit(&(rseg->mutex)); + rseg = UT_LIST_GET_NEXT(rseg_list, rseg); + } + + DBUG_RETURN(status); +} + +static +int +i_s_innodb_undo_logs_init( +/*=================*/ + /* out: 0 on success */ + void* p) /* in/out: table schema object */ +{ + DBUG_ENTER("i_s_innodb_undo_logs_init"); + ST_SCHEMA_TABLE* schema = (ST_SCHEMA_TABLE*) p; + + schema->fields_info = i_s_innodb_undo_logs_fields_info; + schema->fill_table = i_s_innodb_undo_logs_fill; + + DBUG_RETURN(0); +} + +UNIV_INTERN struct st_mysql_plugin i_s_innodb_undo_logs = +{ + /* the plugin type (a MYSQL_XXX_PLUGIN value) */ + /* int */ + STRUCT_FLD(type, MYSQL_INFORMATION_SCHEMA_PLUGIN), + + /* pointer to type-specific plugin descriptor */ + /* void* */ + STRUCT_FLD(info, &i_s_info), + + /* plugin name */ + /* const char* */ + STRUCT_FLD(name, "INNODB_UNDO_LOGS"), + + /* plugin author (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(author, "Percona"), + + /* general descriptive text (for SHOW PLUGINS) */ + /* const char* */ + STRUCT_FLD(descr, "InnoDB rollback undo segment information"), + + /* the plugin license (PLUGIN_LICENSE_XXX) */ + /* int */ + STRUCT_FLD(license, PLUGIN_LICENSE_GPL), + + /* the function to invoke when plugin is loaded */ + /* int (*)(void*); */ + STRUCT_FLD(init, i_s_innodb_undo_logs_init), + + /* the function to invoke when plugin is unloaded */ + /* int (*)(void*); */ STRUCT_FLD(deinit, i_s_common_deinit), + + /* plugin version (for SHOW PLUGINS) */ + STRUCT_FLD(version, 0x0100 /* 1.0 */), + + /* struct st_mysql_show_var* */ + STRUCT_FLD(status_vars, NULL), + + /* struct st_mysql_sys_var** */ + STRUCT_FLD(system_vars, NULL), + + /* reserved for dependency checking */ + /* void* */ + STRUCT_FLD(__reserved1, NULL), + + /* Plugin flags */ + /* unsigned long */ + STRUCT_FLD(flags, 0UL), +}; + diff --git a/handler/i_s.h b/handler/i_s.h index fe4f2ba6dcf..723efd6a693 100644 --- a/handler/i_s.h +++ b/handler/i_s.h @@ -43,6 +43,7 @@ extern struct st_mysql_plugin i_s_innodb_sys_fields; extern struct st_mysql_plugin i_s_innodb_sys_foreign; extern struct st_mysql_plugin i_s_innodb_sys_foreign_cols; extern struct st_mysql_plugin i_s_innodb_rseg; +extern struct st_mysql_plugin i_s_innodb_undo_logs; extern struct st_mysql_plugin i_s_innodb_sys_stats; extern struct st_mysql_plugin i_s_innodb_table_stats; extern struct st_mysql_plugin i_s_innodb_index_stats; |