3904 kevin.lewis@stripped 2012-05-26
Changes requested from Sunny
modified:
storage/innobase/dict/dict0crea.cc
storage/innobase/dict/dict0load.cc
storage/innobase/fil/fil0fil.cc
storage/innobase/handler/ha_innodb.cc
3903 kevin.lewis@stripped 2012-05-26 [merge]
Merge
modified:
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.h
storage/innobase/handler/handler0alter.cc
storage/innobase/include/trx0trx.h
storage/innobase/include/trx0types.h
storage/innobase/trx/trx0trx.cc
3902 kevin.lewis@stripped 2012-05-25
Full 5980 commit.
added:
mysql-test/include/shutdown_mysqld.inc
mysql-test/include/start_mysqld.inc
mysql-test/r/partition_innodb_tablespace.result
mysql-test/suite/innodb/r/innodb-multiple-tablespaces.result
mysql-test/suite/innodb/r/innodb-tablespace.result
mysql-test/suite/innodb/r/innodb_wl5980_linux.result
mysql-test/suite/innodb/t/innodb-multiple-tablespaces.test
mysql-test/suite/innodb/t/innodb-tablespace.test
mysql-test/suite/innodb/t/innodb_wl5980_linux.test
mysql-test/suite/innodb/t/portability_wl5980_linux.zip
mysql-test/suite/parts/r/partition_reorganize_innodb.result
mysql-test/suite/parts/r/partition_reorganize_myisam.result
mysql-test/suite/parts/t/partition_reorganize_innodb.test
mysql-test/suite/parts/t/partition_reorganize_myisam.test
mysql-test/t/partition_innodb_tablespace.test
modified:
include/my_base.h
mysql-test/r/mysqlshow.result
mysql-test/suite/innodb/r/innodb-alter-discard.result
mysql-test/suite/innodb/r/innodb-restart.result
mysql-test/suite/innodb/r/innodb-system-table-view.result
mysql-test/suite/innodb/r/innodb_16k.result
mysql-test/suite/innodb/r/innodb_4k.result
mysql-test/suite/innodb/r/innodb_8k.result
mysql-test/suite/innodb/t/innodb-alter-discard.test
mysql-test/suite/innodb/t/innodb-restart.test
mysql-test/suite/innodb/t/innodb-system-table-view.test
mysql-test/suite/innodb/t/innodb_16k.test
mysql-test/suite/innodb/t/innodb_4k.test
mysql-test/suite/innodb/t/innodb_8k.test
mysql-test/suite/parts/r/partition_basic_symlink_innodb.result
mysql-test/suite/parts/t/partition_basic_symlink_innodb.test
mysys/my_handler_errors.h
sql/ha_partition.cc
sql/ha_partition.h
sql/handler.cc
sql/sql_partition.cc
sql/sql_partition.h
sql/sql_table.cc
storage/innobase/dict/dict0boot.cc
storage/innobase/dict/dict0crea.cc
storage/innobase/dict/dict0dict.cc
storage/innobase/dict/dict0load.cc
storage/innobase/fil/fil0fil.cc
storage/innobase/handler/ha_innodb.cc
storage/innobase/handler/ha_innodb.h
storage/innobase/handler/handler0alter.cc
storage/innobase/handler/i_s.cc
storage/innobase/handler/i_s.h
storage/innobase/include/db0err.h
storage/innobase/include/dict0boot.h
storage/innobase/include/dict0crea.h
storage/innobase/include/dict0dict.h
storage/innobase/include/dict0dict.ic
storage/innobase/include/dict0load.h
storage/innobase/include/dict0mem.h
storage/innobase/include/fil0fil.h
storage/innobase/include/fsp0fsp.h
storage/innobase/include/fsp0fsp.ic
storage/innobase/include/os0file.h
storage/innobase/include/row0merge.h
storage/innobase/lock/lock0lock.cc
storage/innobase/os/os0file.cc
storage/innobase/row/row0import.cc
storage/innobase/row/row0merge.cc
storage/innobase/row/row0mysql.cc
storage/innobase/srv/srv0start.cc
storage/innobase/trx/trx0rec.cc
storage/innobase/ut/ut0ut.cc
=== modified file 'storage/innobase/dict/dict0crea.cc'
--- a/storage/innobase/dict/dict0crea.cc revid:kevin.lewis@stripped
+++ b/storage/innobase/dict/dict0crea.cc revid:kevin.lewis@stripped
@@ -286,8 +286,8 @@ dict_build_table_def_step(
- page 3 will contain the root of the clustered index of the
table we create here. */
- path = table->data_dir_path ? table->data_dir_path :
- table->dir_path_of_temp_table;
+ path = table->data_dir_path ? table->data_dir_path
+ : table->dir_path_of_temp_table;
ut_ad(dict_table_get_format(table) <= UNIV_FORMAT_MAX);
ut_ad(!dict_table_zip_size(table)
@@ -1211,7 +1211,7 @@ function_exit:
Check whether a system table exists. Additionally, if it exists,
move it to the non-LRU end of the table LRU list. This is oly used
for system tables that can be upgraded or added to an older database,
-which include SYS_FOREIGN, SYS_FOREIGN_COLS, SYS_TABLESPACES and
+which include SYS_FOREIGN, SYS_FOREIGN_COLS, SYS_TABLESPACES and
SYS_DATAFILES.
@return TRUE if they exist. */
static
@@ -1264,22 +1264,22 @@ dict_create_or_check_foreign_constraint_
{
trx_t* trx;
my_bool srv_file_per_table_backup;
- dberr_t error;
- dberr_t sys_foreign_ok;
- dberr_t sys_foreign_cols_ok;
+ dberr_t err;
+ dberr_t sys_foreign_err;
+ dberr_t sys_foreign_cols_err;
ut_a(srv_get_active_thread_type() == SRV_NONE);
/* Note: The master thread has not been started at this point. */
- sys_foreign_ok = dict_check_if_system_table_exists(
+ sys_foreign_err = dict_check_if_system_table_exists(
"SYS_FOREIGN", DICT_NUM_FIELDS__SYS_FOREIGN + 1, 3);
- sys_foreign_cols_ok = dict_check_if_system_table_exists(
+ sys_foreign_cols_err = dict_check_if_system_table_exists(
"SYS_FOREIGN_COLS", DICT_NUM_FIELDS__SYS_FOREIGN_COLS + 1, 1);
- if (sys_foreign_ok == DB_SUCCESS
- && sys_foreign_cols_ok == DB_SUCCESS) {
+ if (sys_foreign_err == DB_SUCCESS
+ && sys_foreign_cols_err == DB_SUCCESS) {
return(DB_SUCCESS);
}
@@ -1291,23 +1291,23 @@ dict_create_or_check_foreign_constraint_
/* Check which incomplete table definition to drop. */
- if (sys_foreign_ok == DB_CORRUPTION) {
- fprintf(stderr,
- "InnoDB: dropping incompletely created "
- "SYS_FOREIGN table\n");
+ if (sys_foreign_err == DB_CORRUPTION) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Dropping incompletely created "
+ "SYS_FOREIGN table.\n");
row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
}
- if (sys_foreign_cols_ok == DB_CORRUPTION) {
- fprintf(stderr,
- "InnoDB: dropping incompletely created "
- "SYS_FOREIGN_COLS table\n");
+ if (sys_foreign_cols_err == DB_CORRUPTION) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Dropping incompletely created "
+ "SYS_FOREIGN_COLS table.\n");
row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
}
- fprintf(stderr,
- "InnoDB: Creating foreign key constraint system tables\n");
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Creating foreign key constraint system tables.\n");
/* NOTE: in dict_load_foreigns we use the fact that
there are 2 secondary indexes on SYS_FOREIGN, and they
@@ -1326,7 +1326,7 @@ dict_create_or_check_foreign_constraint_
srv_file_per_table = 0;
- error = que_eval_sql(
+ err = que_eval_sql(
NULL,
"PROCEDURE CREATE_FOREIGN_SYS_TABLES_PROC () IS\n"
"BEGIN\n"
@@ -1347,23 +1347,20 @@ dict_create_or_check_foreign_constraint_
"END;\n",
FALSE, trx);
- if (error != DB_SUCCESS) {
- fprintf(stderr, "InnoDB: error %lu in creation\n",
- (ulong) error);
-
- ut_a(error == DB_OUT_OF_FILE_SPACE
- || error == DB_TOO_MANY_CONCURRENT_TRXS);
+ if (err != DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Creation of SYS_FOREIGN and SYS_FOREIGN_COLS "
+ "has failed with error %lu. Tablespace is full. "
+ "Dropping incompletely created tables.\n",
+ (ulong) err);
- fprintf(stderr,
- "InnoDB: creation failed\n"
- "InnoDB: tablespace is full\n"
- "InnoDB: dropping incompletely created"
- " SYS_FOREIGN tables\n");
+ ut_ad(err == DB_OUT_OF_FILE_SPACE
+ || err == DB_TOO_MANY_CONCURRENT_TRXS);
row_drop_table_for_mysql("SYS_FOREIGN", trx, TRUE);
row_drop_table_for_mysql("SYS_FOREIGN_COLS", trx, TRUE);
- error = DB_MUST_GET_MORE_FILE_SPACE;
+ err = DB_MUST_GET_MORE_FILE_SPACE;
}
trx_commit_for_mysql(trx);
@@ -1374,23 +1371,22 @@ dict_create_or_check_foreign_constraint_
srv_file_per_table = srv_file_per_table_backup;
- if (error == DB_SUCCESS) {
- fprintf(stderr,
- "InnoDB: Foreign key constraint system tables"
- " created\n");
+ if (err == DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Foreign key constraint system tables created\n");
}
/* Note: The master thread has not been started at this point. */
/* Confirm and move to the non-LRU part of the table LRU list. */
- sys_foreign_ok = dict_check_if_system_table_exists(
+ sys_foreign_err = dict_check_if_system_table_exists(
"SYS_FOREIGN", DICT_NUM_FIELDS__SYS_FOREIGN + 1, 3);
- ut_a(sys_foreign_ok == DB_SUCCESS);
+ ut_a(sys_foreign_err == DB_SUCCESS);
- sys_foreign_cols_ok = dict_check_if_system_table_exists(
+ sys_foreign_cols_err = dict_check_if_system_table_exists(
"SYS_FOREIGN_COLS", DICT_NUM_FIELDS__SYS_FOREIGN_COLS + 1, 1);
- ut_a(sys_foreign_cols_ok == DB_SUCCESS);
+ ut_a(sys_foreign_cols_err == DB_SUCCESS);
- return(error);
+ return(err);
}
/****************************************************************//**
@@ -1631,21 +1627,21 @@ dict_create_or_check_sys_tablespace(void
{
trx_t* trx;
my_bool srv_file_per_table_backup;
- dberr_t error;
- dberr_t sys_tablespaces_ok;
- dberr_t sys_datafiles_ok;
+ dberr_t err;
+ dberr_t sys_tablespaces_err;
+ dberr_t sys_datafiles_err;
ut_a(srv_get_active_thread_type() == SRV_NONE);
/* Note: The master thread has not been started at this point. */
- sys_tablespaces_ok = dict_check_if_system_table_exists(
+ sys_tablespaces_err = dict_check_if_system_table_exists(
"SYS_TABLESPACES", DICT_NUM_FIELDS__SYS_TABLESPACES + 1, 1);
- sys_datafiles_ok = dict_check_if_system_table_exists(
+ sys_datafiles_err = dict_check_if_system_table_exists(
"SYS_DATAFILES", DICT_NUM_FIELDS__SYS_DATAFILES + 1, 1);
- if (sys_tablespaces_ok == DB_SUCCESS
- && sys_datafiles_ok == DB_SUCCESS) {
+ if (sys_tablespaces_err == DB_SUCCESS
+ && sys_datafiles_err == DB_SUCCESS) {
return(DB_SUCCESS);
}
@@ -1657,30 +1653,30 @@ dict_create_or_check_sys_tablespace(void
/* Check which incomplete table definition to drop. */
- if (sys_tablespaces_ok == DB_CORRUPTION) {
- fprintf(stderr,
- "InnoDB: dropping incompletely created"
- " SYS_TABLESPACES table\n");
+ if (sys_tablespaces_err == DB_CORRUPTION) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Dropping incompletely created "
+ "SYS_TABLESPACES table.\n");
row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE);
}
- if (sys_datafiles_ok == DB_CORRUPTION) {
- fprintf(stderr,
- "InnoDB: dropping incompletely created"
- " SYS_DATAFILES table\n");
+ if (sys_datafiles_err == DB_CORRUPTION) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "Dropping incompletely created "
+ "SYS_DATAFILES table.\n");
row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE);
}
- fprintf(stderr,
- "InnoDB: Creating tablespace and datafile system tables\n");
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Creating tablespace and datafile system tables.\n");
/* We always want SYSTEM tables to be created inside the system
tablespace. */
srv_file_per_table_backup = srv_file_per_table;
srv_file_per_table = 0;
- error = que_eval_sql(
+ err = que_eval_sql(
NULL,
"PROCEDURE CREATE_SYS_TABLESPACE_PROC () IS\n"
"BEGIN\n"
@@ -1695,23 +1691,20 @@ dict_create_or_check_sys_tablespace(void
"END;\n",
FALSE, trx);
- if (error != DB_SUCCESS) {
- fprintf(stderr,
- "InnoDB: error %lu in creating SYS_TABLESPACES\n",
- (ulong) error);
+ if (err != DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "Creation of SYS_TABLESPACES and SYS_DATAFILES "
+ "has failed with error %lu. Tablespace is full. "
+ "Dropping incompletely created tables.\n",
+ (ulong) err);
- ut_a(error == DB_OUT_OF_FILE_SPACE
- || error == DB_TOO_MANY_CONCURRENT_TRXS);
-
- fprintf(stderr,
- "InnoDB: Creation failed, tablespace is full\n"
- "InnoDB: dropping incompletely created"
- " SYS_TABLESPACE and SYS_DATAFILES tables\n");
+ ut_a(err == DB_OUT_OF_FILE_SPACE
+ || err == DB_TOO_MANY_CONCURRENT_TRXS);
row_drop_table_for_mysql("SYS_TABLESPACES", trx, TRUE);
row_drop_table_for_mysql("SYS_DATAFILES", trx, TRUE);
- error = DB_MUST_GET_MORE_FILE_SPACE;
+ err = DB_MUST_GET_MORE_FILE_SPACE;
}
trx_commit_for_mysql(trx);
@@ -1722,24 +1715,23 @@ dict_create_or_check_sys_tablespace(void
srv_file_per_table = srv_file_per_table_backup;
- if (error == DB_SUCCESS) {
- fprintf(stderr,
- "InnoDB: System tables for Tablespaces and "
- "Datafiles created\n");
+ if (err == DB_SUCCESS) {
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "Tablespace and datafile system tables created\n");
}
/* Note: The master thread has not been started at this point. */
/* Confirm and move to the non-LRU part of the table LRU list. */
- sys_tablespaces_ok = dict_check_if_system_table_exists(
+ sys_tablespaces_err = dict_check_if_system_table_exists(
"SYS_TABLESPACES", DICT_NUM_FIELDS__SYS_TABLESPACES + 1, 1);
- ut_a(sys_tablespaces_ok == DB_SUCCESS);
+ ut_a(sys_tablespaces_err == DB_SUCCESS);
- sys_datafiles_ok = dict_check_if_system_table_exists(
+ sys_datafiles_err = dict_check_if_system_table_exists(
"SYS_DATAFILES", DICT_NUM_FIELDS__SYS_DATAFILES + 1, 1);
- ut_a(sys_datafiles_ok == DB_SUCCESS);
+ ut_a(sys_datafiles_err == DB_SUCCESS);
- return(error);
+ return(err);
}
/********************************************************************//**
@@ -1760,7 +1752,7 @@ dict_create_add_tablespace_to_dictionary
pars_info_t* info = pars_info_create();
- ut_a(space > 0);
+ ut_a(space > TRX_SYS_SPACE);
pars_info_add_int4_literal(info, "space", space);
=== modified file 'storage/innobase/dict/dict0load.cc'
--- a/storage/innobase/dict/dict0load.cc revid:kevin.lewis@stripped
+++ b/storage/innobase/dict/dict0load.cc revid:kevin.lewis@stripped
@@ -489,7 +489,7 @@ dict_process_sys_foreign_rec(
const byte* field;
ulint n_fields_and_type;
- if (UNIV_UNLIKELY(rec_get_deleted_flag(rec, 0))) {
+ if (rec_get_deleted_flag(rec, 0)) {
return("delete-marked record in SYS_FOREIGN");
}
@@ -499,7 +499,7 @@ dict_process_sys_foreign_rec(
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN__ID, &len);
- if (UNIV_UNLIKELY(len < 1 || len == UNIV_SQL_NULL)) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
err_len:
return("incorrect column length in SYS_FOREIGN");
}
@@ -526,7 +526,7 @@ err_len:
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN__FOR_NAME, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
goto err_len;
}
foreign->foreign_table_name = mem_heap_strdupl(
@@ -534,7 +534,7 @@ err_len:
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN__REF_NAME, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
goto err_len;
}
foreign->referenced_table_name = mem_heap_strdupl(
@@ -582,7 +582,7 @@ dict_process_sys_foreign_col_rec(
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN_COLS__ID, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
err_len:
return("incorrect column length in SYS_FOREIGN_COLS");
}
@@ -608,14 +608,14 @@ err_len:
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN_COLS__FOR_COL_NAME, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
goto err_len;
}
*for_col_name = mem_heap_strdupl(heap, (char*) field, len);
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FOREIGN_COLS__REF_COL_NAME, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
goto err_len;
}
*ref_col_name = mem_heap_strdupl(heap, (char*) field, len);
@@ -640,6 +640,11 @@ dict_process_sys_tablespaces(
ulint len;
const byte* field;
+ /* Initialize the output values */
+ *space = ULINT_UNDEFINED;
+ *name = NULL;
+ *flags = ULINT_UNDEFINED;
+
if (rec_get_deleted_flag(rec, 0)) {
return("delete-marked record in SYS_TABLESPACES");
}
@@ -670,7 +675,7 @@ err_len:
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_TABLESPACES__NAME, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
goto err_len;
}
*name = mem_heap_strdupl(heap, (char*) field, len);
@@ -732,7 +737,7 @@ err_len:
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_DATAFILES__PATH, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
goto err_len;
}
*path = mem_heap_strdupl(heap, (char*) field, len);
@@ -897,10 +902,9 @@ dict_update_filepath(
if (err == DB_SUCCESS) {
/* We just updated SYS_DATAFILES due to the contents in
a link file. Make a note that we did this. */
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: The InnoDB data dictionary"
- " table SYS_DATAFILES for tablespace ID %lu"
- " was updated to use file %s.\n",
+ ib_logf(IB_LOG_LEVEL_INFO,
+ "The InnoDB data dictionary table SYS_DATAFILES "
+ "for tablespace ID %lu was updated to use file %s.\n",
(ulong) space_id, filepath);
}
@@ -1211,7 +1215,7 @@ err_len:
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_COLUMNS__NAME, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
goto err_len;
}
@@ -1486,7 +1490,7 @@ err_len:
field = rec_get_nth_field_old(
rec, DICT_FLD__SYS_FIELDS__COL_NAME, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
goto err_len;
}
@@ -1964,7 +1968,7 @@ dict_load_table_low(
rec_get_nth_field_offs_old(
rec, DICT_FLD__SYS_TABLES__NAME, &len);
- if (len < 1 || len == UNIV_SQL_NULL) {
+ if (len == 0 || len == UNIV_SQL_NULL) {
err_len:
return("incorrect column length in SYS_TABLES");
}
=== modified file 'storage/innobase/fil/fil0fil.cc'
--- a/storage/innobase/fil/fil0fil.cc revid:kevin.lewis@stripped
+++ b/storage/innobase/fil/fil0fil.cc revid:kevin.lewis@stripped
@@ -2339,7 +2339,7 @@ fil_ibuf_check_pending_ops(
if (space->n_pending_ops != 0) {
- if (count > 5000) {
+ if (count > 5000) {
ib_logf(IB_LOG_LEVEL_WARN,
"Trying to close/delete tablespace "
"'%s' but there are %lu pending change "
@@ -3243,10 +3243,10 @@ fil_create_new_single_table_tablespace(
if (is_temp) {
/* Temporary table filepath */
- ut_a(dir_path);
+ ut_ad(dir_path);
path = fil_make_ibd_name(dir_path, TRUE);
} else if (has_data_dir) {
- ut_a(dir_path);
+ ut_ad(dir_path);
path = os_file_make_remote_pathname(dir_path, tablename);
/* Since this tablespace file will be created in a
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc revid:kevin.lewis@stripped
+++ b/storage/innobase/handler/ha_innodb.cc revid:kevin.lewis@stripped
@@ -96,6 +96,9 @@ this program; if not, write to the Free
# ifndef MYSQL_PLUGIN_IMPORT
# define MYSQL_PLUGIN_IMPORT /* nothing */
# endif /* MYSQL_PLUGIN_IMPORT */
+
+/** to protect innobase_open_files */
+static mysql_mutex_t innobase_share_mutex;
/** to force correct commit order in binlog */
static ulong commit_threads = 0;
static mysql_mutex_t commit_threads_m;
@@ -231,6 +234,8 @@ it every INNOBASE_WAKE_INTERVAL'th step.
#define INNOBASE_WAKE_INTERVAL 32
static ulong innobase_active_counter = 0;
+static hash_table_t* innobase_open_tables;
+
/** Allowed values of innodb_change_buffering */
static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
"none", /* IBUF_USE_NONE */
@@ -257,6 +262,7 @@ const struct _ft_vft_ext ft_vft_ext_resu
#ifdef HAVE_PSI_INTERFACE
/* Keys to register pthread mutexes/cond in the current file with
performance schema */
+static mysql_pfs_key_t innobase_share_mutex_key;
static mysql_pfs_key_t commit_threads_m_key;
static mysql_pfs_key_t commit_cond_mutex_key;
static mysql_pfs_key_t commit_cond_key;
@@ -264,6 +270,7 @@ static mysql_pfs_key_t commit_cond_key;
static PSI_mutex_info all_pthread_mutexes[] = {
{&commit_threads_m_key, "commit_threads_m", 0},
{&commit_cond_mutex_key, "commit_cond_mutex", 0},
+ {&innobase_share_mutex_key, "innobase_share_mutex", 0}
};
static PSI_cond_info all_innodb_conds[] = {
@@ -620,6 +627,23 @@ static SHOW_VAR innodb_status_variables[
{NullS, NullS, SHOW_LONG}
};
+/************************************************************************//**
+Handling the shared INNOBASE_SHARE structure that is needed to provide table
+locking. Register the table name if it doesn't exist in the hash table. */
+static
+INNOBASE_SHARE*
+get_share(
+/*======*/
+ const char* table_name); /*!< in: table to lookup */
+
+/************************************************************************//**
+Free the shared object that was registered with get_share(). */
+static
+void
+free_share(
+/*=======*/
+ INNOBASE_SHARE* share); /*!< in/own: share to free */
+
/*****************************************************************//**
Frees a possible InnoDB trx object associated with the current THD.
@return 0 or error number */
@@ -3103,6 +3127,10 @@ innobase_change_buffering_inited_ok:
ibuf_max_size_update(innobase_change_buffer_max_size);
+ innobase_open_tables = hash_create(200);
+ mysql_mutex_init(innobase_share_mutex_key,
+ &innobase_share_mutex,
+ MY_MUTEX_INIT_FAST);
mysql_mutex_init(commit_threads_m_key,
&commit_threads_m, MY_MUTEX_INIT_FAST);
mysql_mutex_init(commit_cond_mutex_key,
@@ -3161,11 +3189,14 @@ innobase_end(
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
innodb_inited = 0;
+ hash_table_free(innobase_open_tables);
+ innobase_open_tables = NULL;
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
err = 1;
}
srv_free_paths_and_sizes();
my_free(internal_innobase_data_file_path);
+ mysql_mutex_destroy(&innobase_share_mutex);
mysql_mutex_destroy(&commit_threads_m);
mysql_mutex_destroy(&commit_cond_m);
mysql_cond_destroy(&commit_cond);
@@ -4195,8 +4226,8 @@ innobase_match_index_columns(
}
/*******************************************************************//**
-This function builds a translation table in Innobase_share
-object for fast index location with mysql array number from its
+This function builds a translation table in INNOBASE_SHARE
+structure for fast index location with mysql array number from its
table->key_info structure. This also provides the necessary translation
between the key order in mysql key_info and Innodb ib_table->indexes if
they are not fully matched with each other.
@@ -4213,7 +4244,7 @@ innobase_build_index_translation(
dictionary */
dict_table_t* ib_table,/*!< in: table in Innodb data
dictionary */
- Innobase_share* share) /*!< in/out: share object
+ INNOBASE_SHARE* share) /*!< in/out: share structure
where index translation table
will be constructed in. */
{
@@ -4333,7 +4364,7 @@ static
dict_index_t*
innobase_index_lookup(
/*==================*/
- Innobase_share* share, /*!< in: share object for index
+ INNOBASE_SHARE* share, /*!< in: share structure for index
translation table. */
uint keynr) /*!< in: index number for the requested
index */
@@ -4488,7 +4519,7 @@ ha_innobase::open(
user_thd = NULL;
- if (!(share=get_share())) {
+ if (!(share=get_share(name))) {
DBUG_RETURN(1);
}
@@ -4599,6 +4630,7 @@ retry:
REFMAN "innodb-troubleshooting.html for how "
"you can resolve the problem.", norm_name);
+ free_share(share);
my_errno = ENOENT;
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
@@ -4643,6 +4675,7 @@ table_opened:
}
if (!thd_tablespace_op(thd) && no_tablespace) {
+ free_share(share);
my_errno = ENOENT;
dict_table_close(ib_table, FALSE, FALSE);
@@ -4879,6 +4912,8 @@ ha_innobase::close()
upd_buf_size = 0;
}
+ free_share(share);
+
MONITOR_INC(MONITOR_TABLE_CLOSE);
/* Tell InnoDB server that there might be work for
@@ -8929,7 +8964,7 @@ ha_innobase::parse_table_name(
}
if (create_info->data_file_name) {
- ibool ignore = FALSE;
+ bool ignore = false;
/* Use DATA DIRECTORY only with file-per-table. */
if (!use_tablespace) {
@@ -8938,7 +8973,7 @@ ha_innobase::parse_table_name(
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: DATA DIRECTORY requires"
" innodb_file_per_table.");
- ignore = TRUE;
+ ignore = true;
}
/* Do not use DATA DIRECTORY with TEMPORARY TABLE. */
@@ -8948,7 +8983,7 @@ ha_innobase::parse_table_name(
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: DATA DIRECTORY cannot be"
" used for TEMPORARY tables.");
- ignore = TRUE;
+ ignore = true;
}
if (ignore) {
@@ -10334,7 +10369,7 @@ static
int
innobase_get_mysql_key_number_for_index(
/*====================================*/
- Innobase_share* share, /*!< in: share object for index
+ INNOBASE_SHARE* share, /*!< in: share structure for index
translation table. */
const TABLE* table, /*!< in: table in MySQL data
dictionary */
@@ -12314,31 +12349,94 @@ innobase_show_status(
}
/************************************************************************//**
-Handling the shared Innobase_share object that is needed to provide table
-locking. */
-Innobase_share*
-ha_innobase::get_share(void)
-/*========================*/
+Handling the shared INNOBASE_SHARE structure that is needed to provide table
+locking. Register the table name if it doesn't exist in the hash table. */
+static
+INNOBASE_SHARE*
+get_share(
+/*======*/
+ const char* table_name)
{
- Innobase_share *tmp_share;
+ INNOBASE_SHARE* share;
- lock_shared_ha_data();
- tmp_share= static_cast<Innobase_share*>(get_ha_share_ptr());
+ mysql_mutex_lock(&innobase_share_mutex);
- if (!tmp_share)
- {
- tmp_share= new Innobase_share;
- if (!tmp_share)
- {
- unlock_shared_ha_data();
- return(NULL);
- }
+ ulint fold = ut_fold_string(table_name);
+
+ HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
+ INNOBASE_SHARE*, share,
+ ut_ad(share->use_count > 0),
+ !strcmp(share->table_name, table_name));
+
+ if (!share) {
+
+ uint length = (uint) strlen(table_name);
+
+ /* TODO: invoke HASH_MIGRATE if innobase_open_tables
+ grows too big */
+
+ share = (INNOBASE_SHARE*) my_malloc(sizeof(*share)+length+1,
+ MYF(MY_FAE | MY_ZEROFILL));
+
+ share->table_name = (char*) memcpy(share + 1,
+ table_name, length + 1);
+
+ HASH_INSERT(INNOBASE_SHARE, table_name_hash,
+ innobase_open_tables, fold, share);
- set_ha_share_ptr(static_cast<Handler_share*>(tmp_share));
+ thr_lock_init(&share->lock);
+
+ /* Index translation table initialization */
+ share->idx_trans_tbl.index_mapping = NULL;
+ share->idx_trans_tbl.index_count = 0;
+ share->idx_trans_tbl.array_size = 0;
+ }
+
+ share->use_count++;
+ mysql_mutex_unlock(&innobase_share_mutex);
+
+ return(share);
+}
+
+/************************************************************************//**
+Free the shared object that was registered with get_share(). */
+static
+void
+free_share(
+/*=======*/
+ INNOBASE_SHARE* share) /*!< in/own: table share to free */
+{
+ mysql_mutex_lock(&innobase_share_mutex);
+
+#ifdef UNIV_DEBUG
+ INNOBASE_SHARE* share2;
+ ulint fold = ut_fold_string(share->table_name);
+
+ HASH_SEARCH(table_name_hash, innobase_open_tables, fold,
+ INNOBASE_SHARE*, share2,
+ ut_ad(share->use_count > 0),
+ !strcmp(share->table_name, share2->table_name));
+
+ ut_a(share2 == share);
+#endif /* UNIV_DEBUG */
+
+ if (!--share->use_count) {
+ ulint fold = ut_fold_string(share->table_name);
+
+ HASH_DELETE(INNOBASE_SHARE, table_name_hash,
+ innobase_open_tables, fold, share);
+ thr_lock_delete(&share->lock);
+
+ /* Free any memory from index translation table */
+ my_free(share->idx_trans_tbl.index_mapping);
+
+ my_free(share);
+
+ /* TODO: invoke HASH_MIGRATE if innobase_open_tables
+ shrinks too much */
}
- unlock_shared_ha_data();
- ut_ad(tmp_share);
- return(tmp_share);
+
+ mysql_mutex_unlock(&innobase_share_mutex);
}
/*****************************************************************//**
=== modified file 'storage/innobase/handler/ha_innodb.h'
--- a/storage/innobase/handler/ha_innodb.h revid:kevin.lewis@stripped
+++ b/storage/innobase/handler/ha_innodb.h revid:kevin.lewis@stripped
@@ -38,29 +38,19 @@ typedef struct innodb_idx_translate_stru
/** InnoDB table share */
-class Innobase_share : public Handler_share
-{
-public:
+typedef struct st_innobase_share {
THR_LOCK lock; /*!< MySQL lock protecting
this structure */
+ const char* table_name; /*!< InnoDB table name */
+ uint use_count; /*!< reference count,
+ incremented in get_share()
+ and decremented in
+ free_share() */
+ void* table_name_hash;/*!< hash table chain node */
innodb_idx_translate_t idx_trans_tbl; /*!< index translation
table between MySQL and
Innodb */
- Innobase_share()
- {
- thr_lock_init(&lock);
- idx_trans_tbl.index_mapping = NULL;
- idx_trans_tbl.index_count = 0;
- idx_trans_tbl.array_size = 0;
- }
- ~Innobase_share()
- {
- thr_lock_delete(&lock);
-
- /* Free any memory from index translation table */
- my_free(idx_trans_tbl.index_mapping);
- }
-};
+} INNOBASE_SHARE;
/** InnoDB B-tree index */
@@ -83,7 +73,7 @@ class ha_innobase: public handler
currently using the handle; this is
set in external_lock function */
THR_LOCK_DATA lock;
- Innobase_share* share; /*!< information for MySQL
+ INNOBASE_SHARE* share; /*!< information for MySQL
table locking */
uchar* upd_buf; /*!< buffer used in updates */
@@ -368,8 +358,6 @@ public:
private:
/** The multi range read session object */
DsMrr_impl ds_mrr;
- /** Connects/gets Innobase_share in TABLE_SHARE */
- Innobase_share* get_share();
/* @} */
};
=== modified file 'storage/innobase/handler/handler0alter.cc'
--- a/storage/innobase/handler/handler0alter.cc revid:kevin.lewis@stripped
+++ b/storage/innobase/handler/handler0alter.cc revid:kevin.lewis@stripped
@@ -1290,14 +1290,11 @@ online_retry_drop_indexes(
THD* user_thd) /*!< in/out: MySQL connection */
{
if (table->drop_aborted) {
- trx_t* trx = innobase_trx_allocate(user_thd);
- trx_start_if_not_started(trx);
- trx->will_lock = 1;
+ trx_t* trx = innobase_trx_allocate(user_thd);
+
+ trx_start_for_ddl(trx, TRX_DICT_OP_INDEX);
row_mysql_lock_data_dictionary(trx);
- /* Flag this transaction as a dictionary operation, so that
- the data dictionary will be locked in crash recovery. */
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
online_retry_drop_indexes_low(table, trx);
trx_commit_for_mysql(trx);
row_mysql_unlock_data_dictionary(trx);
@@ -1329,13 +1326,11 @@ online_retry_drop_indexes_with_trx(
drop any incompletely created indexes that may have been left
behind in rollback_inplace_alter_table() earlier. */
if (table->drop_aborted) {
- /* Re-use the dictionary transaction object
- to avoid some memory allocation overhead. */
- ut_ad(trx_get_dict_operation(trx) == TRX_DICT_OP_TABLE);
- trx->dict_operation = TRX_DICT_OP_INDEX;
+
trx->table_id = 0;
- trx_start_if_not_started(trx);
- trx->will_lock = 1;
+
+ trx_start_for_ddl(trx, TRX_DICT_OP_INDEX);
+
online_retry_drop_indexes_low(table, trx);
trx_commit_for_mysql(trx);
}
@@ -1404,8 +1399,9 @@ prepare_inplace_alter_table_dict(
/* Create a background transaction for the operations on
the data dictionary tables. */
trx = innobase_trx_allocate(user_thd);
- trx_start_if_not_started(trx);
- trx->will_lock = 1;
+
+ trx_start_for_ddl(trx, TRX_DICT_OP_INDEX);
+
if (!heap) {
heap = mem_heap_create(1024);
}
@@ -1443,9 +1439,10 @@ prepare_inplace_alter_table_dict(
add_key_nums = (ulint*) mem_heap_alloc(
heap, n_add_index * sizeof *add_key_nums);
- /* Flag this transaction as a dictionary operation, so that
- the data dictionary will be locked in crash recovery. */
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
+ /* This transaction should be dictionary operation, so that
+ the data dictionary will be locked during crash recovery. */
+
+ ut_ad(trx->dict_operation == TRX_DICT_OP_INDEX);
const bool exclusive = ha_alter_info->alter_info->requested_lock
== Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE;
@@ -1697,11 +1694,11 @@ col_fail:
}
if (fts_index) {
-#ifdef UNIV_DEBUG
/* Ensure that the dictionary operation mode will
not change while creating the auxiliary tables. */
enum trx_dict_op op = trx_get_dict_operation(trx);
+#ifdef UNIV_DEBUG
switch (op) {
case TRX_DICT_OP_NONE:
break;
@@ -1720,12 +1717,17 @@ op_ok:
DICT_TF2_FLAG_SET(indexed_table, DICT_TF2_FTS);
+ /* This function will commit the transaction and reset
+ the trx_t::dict_operation flag on success. */
+
error = fts_create_index_tables(trx, fts_index);
if (error != DB_SUCCESS) {
goto error_handling;
}
+ trx_start_for_ddl(trx, op);
+
if (!indexed_table->fts
|| ib_vector_size(indexed_table->fts->indexes) == 0) {
error = fts_create_common_tables(
@@ -2529,6 +2531,9 @@ rollback_inplace_alter_table(
} else {
DBUG_ASSERT(!(ha_alter_info->handler_flags
& Alter_inplace_info::ADD_PK_INDEX));
+
+ trx_start_for_ddl(ctx->trx, TRX_DICT_OP_INDEX);
+
row_merge_drop_indexes(ctx->trx, prebuilt->table, FALSE);
}
@@ -2845,15 +2850,20 @@ ha_innobase::commit_inplace_alter_table(
/* Create a background transaction for the operations on
the data dictionary tables. */
trx = innobase_trx_allocate(user_thd);
- trx_start_if_not_started(trx);
- trx->will_lock = 1;
- /* Flag this transaction as a dictionary operation, so that
- the data dictionary will be locked in crash recovery. */
- trx_set_dict_operation(trx, TRX_DICT_OP_INDEX);
+
+ trx_start_for_ddl(trx, TRX_DICT_OP_INDEX);
+
new_clustered = false;
} else {
+ trx_dict_op_t op;
+
trx = ctx->trx;
+
new_clustered = ctx->indexed_table != prebuilt->table;
+
+ op = (new_clustered) ? TRX_DICT_OP_TABLE : TRX_DICT_OP_INDEX;
+
+ trx_start_for_ddl(trx, op);
}
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
@@ -2923,10 +2933,10 @@ ha_innobase::commit_inplace_alter_table(
}
} else if (ctx) {
dberr_t error;
+
/* We altered the table in place. */
- ulint i;
/* Lose the TEMP_INDEX_PREFIX. */
- for (i = 0; i < ctx->num_to_add; i++) {
+ for (ulint i = 0; i < ctx->num_to_add; i++) {
dict_index_t* index = ctx->add[i];
DBUG_ASSERT(*index->name
== TEMP_INDEX_PREFIX);
@@ -2948,7 +2958,7 @@ ha_innobase::commit_inplace_alter_table(
index->name in the dictionary cache, because the index
is about to be freed after row_merge_drop_indexes_dict(). */
- for (i = 0; i < ctx->num_to_drop; i++) {
+ for (ulint i = 0; i < ctx->num_to_drop; i++) {
dict_index_t* index = ctx->drop[i];
DBUG_ASSERT(*index->name != TEMP_INDEX_PREFIX);
DBUG_ASSERT(index->table == prebuilt->table);
@@ -3044,6 +3054,7 @@ trx_commit:
}
if (!new_clustered && ha_alter_info->index_drop_count) {
+
/* Really drop the indexes that were dropped.
The transaction had to be committed first
(after renaming the indexes), so that in the
@@ -3053,10 +3064,7 @@ trx_commit:
have started dropping an index tree, there is
no way to roll it back. */
- trx_start_if_not_started(trx);
- DBUG_ASSERT(trx_get_dict_operation(trx)
- == TRX_DICT_OP_INDEX);
- trx->will_lock = 1;
+ trx_start_for_ddl(trx, TRX_DICT_OP_INDEX);
for (ulint i = 0; i < ctx->num_to_drop; i++) {
dict_index_t* index = ctx->drop[i];
=== modified file 'storage/innobase/include/trx0trx.h'
--- a/storage/innobase/include/trx0trx.h revid:kevin.lewis@stripped
+++ b/storage/innobase/include/trx0trx.h revid:kevin.lewis@stripped
@@ -148,6 +148,28 @@ trx_start_if_not_started_low(
trx_start_if_not_started_low((t))
#endif /* UNIV_DEBUG */
+/*************************************************************//**
+Starts the transaction for a DDL operation. */
+UNIV_INTERN
+void
+trx_start_for_ddl_low(
+/*==================*/
+ trx_t* trx, /*!< in/out: transaction */
+ trx_dict_op_t op) /*!< in: dictionary operation type */
+ __attribute__((nonnull));
+
+#ifdef UNIV_DEBUG
+#define trx_start_for_ddl(t, o) \
+ { \
+ (t)->start_line = __LINE__; \
+ (t)->start_file = __FILE__; \
+ trx_start_for_ddl_low((t), (o)); \
+ }
+#else
+#define trx_start_for_ddl(t, o) \
+ trx_start_for_ddl_low((t), (o))
+#endif /* UNIV_DEBUG */
+
/****************************************************************//**
Commits a transaction. */
UNIV_INTERN
@@ -299,21 +321,6 @@ trx_print(
or 0 to use the default max length */
__attribute__((nonnull));
-/** Type of data dictionary operation */
-typedef enum trx_dict_op {
- /** The transaction is not modifying the data dictionary. */
- TRX_DICT_OP_NONE = 0,
- /** The transaction is creating a table or an index, or
- dropping a table. The table must be dropped in crash
- recovery. This and TRX_DICT_OP_NONE are the only possible
- operation modes in crash recovery. */
- TRX_DICT_OP_TABLE = 1,
- /** The transaction is creating or dropping an index in an
- existing table. In crash recovery, the data dictionary
- must be locked, but the table must not be dropped. */
- TRX_DICT_OP_INDEX = 2
-} trx_dict_op_t;
-
/**********************************************************************//**
Determine if a transaction is a dictionary operation.
@return dictionary operation mode */
=== modified file 'storage/innobase/include/trx0types.h'
--- a/storage/innobase/include/trx0types.h revid:kevin.lewis@stripped
+++ b/storage/innobase/include/trx0types.h revid:kevin.lewis@stripped
@@ -52,6 +52,21 @@ enum trx_state_enum {
TRX_STATE_COMMITTED_IN_MEMORY
};
+/** Type of data dictionary operation */
+typedef enum trx_dict_op {
+ /** The transaction is not modifying the data dictionary. */
+ TRX_DICT_OP_NONE = 0,
+ /** The transaction is creating a table or an index, or
+ dropping a table. The table must be dropped in crash
+ recovery. This and TRX_DICT_OP_NONE are the only possible
+ operation modes in crash recovery. */
+ TRX_DICT_OP_TABLE = 1,
+ /** The transaction is creating or dropping an index in an
+ existing table. In crash recovery, the data dictionary
+ must be locked, but the table must not be dropped. */
+ TRX_DICT_OP_INDEX = 2
+} trx_dict_op_t;
+
/** Memory objects */
/* @{ */
/** Transaction */
=== modified file 'storage/innobase/trx/trx0trx.cc'
--- a/storage/innobase/trx/trx0trx.cc revid:kevin.lewis@stripped
+++ b/storage/innobase/trx/trx0trx.cc revid:kevin.lewis@stripped
@@ -1196,6 +1196,8 @@ trx_commit(
ut_ad(!trx->in_ro_trx_list);
ut_ad(!trx->in_rw_trx_list);
+ trx->dict_operation = TRX_DICT_OP_NONE;
+
trx->error_state = DB_SUCCESS;
/* trx->in_mysql_trx_list would hold between
@@ -2093,3 +2095,24 @@ trx_start_if_not_started_low(
ut_error;
}
+
+/*************************************************************//**
+Starts the transaction for a DDL operation. */
+UNIV_INTERN
+void
+trx_start_for_ddl_low(
+/*==================*/
+ trx_t* trx, /*!< in/out: transaction */
+ trx_dict_op_t op) /*!< in: dictionary operation type */
+{
+ /* Flag this transaction as a dictionary operation, so that
+ the data dictionary will be locked in crash recovery. */
+
+ trx_set_dict_operation(trx, op);
+
+ /* Ensure it is not flagged as an auto-commit-non-locking transation. */
+ trx->will_lock = 1;
+
+ trx_start_low(trx);
+}
+
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-trunk branch (kevin.lewis:3902 to 3904) | kevin.lewis | 27 May |