summaryrefslogtreecommitdiff
path: root/handler
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-09-05 10:44:23 +0200
committerSergei Golubchik <sergii@pisem.net>2012-09-05 10:44:23 +0200
commit0352f09a2e3e17470ab75678265b98a275cb25a0 (patch)
tree8f805f4f08cb293c01d7ee269db7ea2b6b715e3b /handler
parent651ac12e8821a994e6176e63eef3e87b70f9746c (diff)
downloadmariadb-git-0352f09a2e3e17470ab75678265b98a275cb25a0.tar.gz
Percona-Server-5.5.27-rel28.1
Diffstat (limited to 'handler')
-rw-r--r--handler/ha_innodb.cc51
-rw-r--r--handler/handler0alter.cc18
-rw-r--r--handler/i_s.cc245
-rw-r--r--handler/i_s.h1
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;