From: kevin.lewis Date: February 16 2012 3:48pm Subject: bzr push into mysql-trunk branch (kevin.lewis:3910 to 3911) List-Archive: http://lists.mysql.com/commits/142914 Message-Id: <20120216154830.7A8F11E4776B@dhcp-adc-twvpn-2-vpnpool-10-154-44-48.vpn.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 3911 kevin.lewis@stripped 2012-02-16 Refactor the use of srv_file_per_table. It is a global variable that can change at any time during a CREATE table process, but it is refered to several time during that process. Save the value of that setting at the start of the CREATE and use the same boolean value during the whole CREATE. This patch saves it in dict_table_t:flags2 which is not tested for backward compatibility in older engines. It means that the table is/was created in its own tablespace or ibd file. Approved by Sunny in rb:908 modified: storage/innobase/dict/dict0crea.cc storage/innobase/fil/fil0fil.cc storage/innobase/handler/ha_innodb.cc storage/innobase/include/dict0mem.h storage/innobase/include/fil0fil.h storage/innobase/row/row0mysql.cc 3910 Jorgen Loland 2012-02-16 BUG#13354910 followup: add assertion that records_in_range() is not called for open ranges. modified: sql/handler.cc sql/opt_range.cc === modified file 'storage/innobase/dict/dict0crea.cc' --- a/storage/innobase/dict/dict0crea.cc revid:jorgen.loland@stripped +++ b/storage/innobase/dict/dict0crea.cc revid:kevin.lewis@stripped @@ -258,27 +258,20 @@ dict_build_table_def_step( ibool is_path; mtr_t mtr; ulint space = 0; - ibool file_per_table; + bool use_tablespace; ut_ad(mutex_own(&(dict_sys->mutex))); table = node->table; - - /* Cache the global variable "srv_file_per_table" to - a local variable before using it. Please note - "srv_file_per_table" is not under dict_sys mutex - protection, and could be changed while executing - this function. So better to cache the current value - to a local variable, and all future reference to - "srv_file_per_table" should use this local variable. */ - file_per_table = srv_file_per_table; + use_tablespace = !!(table->flags2 & DICT_TF2_USE_TABLESPACE); dict_hdr_get_new_id(&table->id, NULL, NULL); thr_get_trx(thr)->table_id = table->id; - if (file_per_table) { - /* Get a new space id if srv_file_per_table is set */ + if (use_tablespace) { + /* This table will not use the system tablespace. + Get a new space id. */ dict_hdr_get_new_id(NULL, NULL, &space); if (UNIV_UNLIKELY(space == ULINT_UNDEFINED)) { @@ -311,6 +304,7 @@ dict_build_table_def_step( error = fil_create_new_single_table_tablespace( space, path_or_name, is_path, dict_tf_to_fsp_flags(table->flags), + table->flags2, FIL_IBD_FILE_INITIAL_SIZE); table->space = (unsigned int) space; === modified file 'storage/innobase/fil/fil0fil.cc' --- a/storage/innobase/fil/fil0fil.cc revid:jorgen.loland@stripped +++ b/storage/innobase/fil/fil0fil.cc revid:kevin.lewis@stripped @@ -2243,6 +2243,7 @@ fil_op_log_parse_or_replay( if (fil_create_new_single_table_tablespace( space_id, name, FALSE, flags, + DICT_TF2_USE_TABLESPACE, FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) { ut_error; } @@ -2748,6 +2749,7 @@ fil_create_new_single_table_tablespace( ibool is_temp, /*!< in: TRUE if a table created with CREATE TEMPORARY TABLE */ ulint flags, /*!< in: tablespace flags */ + ulint flags2, /*!< in: table flags2 */ ulint size) /*!< in: the initial size of the tablespace file in pages, must be >= FIL_IBD_FILE_INITIAL_SIZE */ @@ -2759,7 +2761,6 @@ fil_create_new_single_table_tablespace( byte* page; char* path; ibool success; - ulint create_mode; ut_a(space_id > 0); ut_a(space_id < SRV_LOG_SPACE_FIRST_ID); @@ -2768,22 +2769,9 @@ fil_create_new_single_table_tablespace( path = fil_make_ibd_name(tablename, is_temp); - /* When srv_file_per_table is on, file creation failure may not - be critical to the whole instance. Do not crash the server in - case of unknown errors. - - Note "srv_file_per_table" is a global variable with no explicit - synchronization protection. It could be changed during this execution - path. It might not have the same value as the one when building the - table definition */ - - create_mode = srv_file_per_table - ? OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT - : OS_FILE_CREATE; - file = os_file_create( innodb_file_data_key, path, - create_mode, + OS_FILE_CREATE | OS_FILE_ON_ERROR_NO_EXIT, OS_FILE_NORMAL, OS_DATA_FILE, &ret); === modified file 'storage/innobase/handler/ha_innodb.cc' --- a/storage/innobase/handler/ha_innodb.cc revid:jorgen.loland@stripped +++ b/storage/innobase/handler/ha_innodb.cc revid:kevin.lewis@stripped @@ -8361,8 +8361,8 @@ get_row_format_name( } /** If file-per-table is missing, issue warning and set ret false */ -#define CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE \ - if (!srv_file_per_table) { \ +#define CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE(use_tablespace)\ + if (!use_tablespace) { \ push_warning_printf( \ thd, Sql_condition::WARN_LEVEL_WARN, \ ER_ILLEGAL_HA_CREATE_OPTION, \ @@ -8398,7 +8398,8 @@ create_options_are_valid( THD* thd, /*!< in: connection thread. */ TABLE* form, /*!< in: information on table columns and indexes */ - HA_CREATE_INFO* create_info) /*!< in: create info. */ + HA_CREATE_INFO* create_info, /*!< in: create info. */ + bool use_tablespace) /*!< in: srv_file_per_table */ { ibool kbs_specified = FALSE; ibool ret = TRUE; @@ -8425,7 +8426,7 @@ create_options_are_valid( case 8: case 16: /* Valid KEY_BLOCK_SIZE, check its dependencies. */ - if (!srv_file_per_table) { + if (!use_tablespace) { push_warning( thd, Sql_condition::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, @@ -8475,11 +8476,11 @@ create_options_are_valid( other incompatibilities. */ switch (row_format) { case ROW_TYPE_COMPRESSED: - CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE; + CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE(use_tablespace); CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE; break; case ROW_TYPE_DYNAMIC: - CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE; + CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE(use_tablespace); CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE; /* fall through since dynamic also shuns KBS */ case ROW_TYPE_COMPACT: @@ -8568,6 +8569,13 @@ ha_innobase::create( enum row_type row_format; rec_format_t innodb_row_format = REC_FORMAT_COMPACT; + /* Cache the global variable "srv_file_per_table" to a local + variable before using it. Note that "srv_file_per_table" + is not under dict_sys mutex protection, and could be changed + while creating the table. So we read the current value here + and make all further decisions based on this. */ + bool use_tablespace = srv_file_per_table; + /* Zip Shift Size - log2 - 9 of compressed page size, zero for uncompressed */ ulint zip_ssize = 0; @@ -8598,7 +8606,7 @@ ha_innobase::create( returns error if it is in full path format, but not creating a temp. table. Currently InnoDB does not support symbolic link on Windows. */ - if (srv_file_per_table + if (use_tablespace && !mysqld_embedded && (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) { @@ -8674,7 +8682,8 @@ ha_innobase::create( } /* Validate create options if innodb_strict_mode is set. */ - if (!create_options_are_valid(thd, form, create_info)) { + if (!create_options_are_valid( + thd, form, create_info, use_tablespace)) { DBUG_RETURN(ER_ILLEGAL_HA_CREATE_OPTION); } @@ -8696,7 +8705,7 @@ ha_innobase::create( } /* Make sure compressed row format is allowed. */ - if (!srv_file_per_table) { + if (!use_tablespace) { push_warning( thd, Sql_condition::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, @@ -8766,7 +8775,7 @@ ha_innobase::create( case ROW_TYPE_COMPRESSED: case ROW_TYPE_DYNAMIC: - if (!srv_file_per_table) { + if (!use_tablespace) { push_warning_printf( thd, Sql_condition::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, @@ -8832,6 +8841,10 @@ ha_innobase::create( flags2 |= DICT_TF2_TEMPORARY; } + if (use_tablespace) { + flags2 |= DICT_TF2_USE_TABLESPACE; + } + /* Get the transaction associated with the current thd, or create one if not yet created */ === modified file 'storage/innobase/include/dict0mem.h' --- a/storage/innobase/include/dict0mem.h revid:jorgen.loland@stripped +++ b/storage/innobase/include/dict0mem.h revid:kevin.lewis@stripped @@ -170,21 +170,25 @@ to cache the BLOB prefixes. */ These flags will be stored in SYS_TABLES.MIX_LEN. All unused flags will be written as 0. The column may contain garbage for tables created with old versions of InnoDB that only implemented -ROW_FORMAT=REDUNDANT. */ +ROW_FORMAT=REDUNDANT. InnoDB engines do not check these flags +for unknown bits in order to protect backward incompatibility. */ /* @{ */ /** Total number of bits in table->flags2. */ -#define DICT_TF2_BITS 4 +#define DICT_TF2_BITS 5 #define DICT_TF2_BIT_MASK ~(~0 << DICT_TF2_BITS) -#define DICT_TF2_TEMPORARY 1 /*!< TRUE for tables from - CREATE TEMPORARY TABLE. */ -#define DICT_TF2_FTS_HAS_DOC_ID 2 /* Has internal defined - DOC ID column */ -#define DICT_TF2_FTS 4 /* has an FTS index */ -#define DICT_TF2_FTS_ADD_DOC_ID 8 /* Need to add Doc ID column - for FTS index build. - This is a transient bit - for index build */ +/** TEMPORARY; TRUE for tables from CREATE TEMPORARY TABLE. */ +#define DICT_TF2_TEMPORARY 1 +/** The table has an internal defined DOC ID column */ +#define DICT_TF2_FTS_HAS_DOC_ID 2 +/** The table has an FTS index */ +#define DICT_TF2_FTS 4 +/** Need to add Doc ID column for FTS index build. +This is a transient bit for index build */ +#define DICT_TF2_FTS_ADD_DOC_ID 8 +/** This bit is used during table creation to indicate that it will +use its own tablespace instead of the system tablespace. */ +#define DICT_TF2_USE_TABLESPACE 16 /* @} */ #define DICT_TF2_FLAG_SET(table, flag) \ === modified file 'storage/innobase/include/fil0fil.h' --- a/storage/innobase/include/fil0fil.h revid:jorgen.loland@stripped +++ b/storage/innobase/include/fil0fil.h revid:kevin.lewis@stripped @@ -462,6 +462,7 @@ fil_create_new_single_table_tablespace( ibool is_temp, /*!< in: TRUE if a table created with CREATE TEMPORARY TABLE */ ulint flags, /*!< in: tablespace flags */ + ulint flags2, /*!< in: table flags2 */ ulint size); /*!< in: the initial size of the tablespace file in pages, must be >= FIL_IBD_FILE_INITIAL_SIZE */ === modified file 'storage/innobase/row/row0mysql.cc' --- a/storage/innobase/row/row0mysql.cc revid:jorgen.loland@stripped +++ b/storage/innobase/row/row0mysql.cc revid:kevin.lewis@stripped @@ -3119,7 +3119,8 @@ row_truncate_table_for_mysql( if (space == ULINT_UNDEFINED || fil_create_new_single_table_tablespace( - space, table->name, FALSE, flags, + space, table->name, FALSE, + flags, table->flags2, FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) { dict_table_x_unlock_indexes(table); ut_print_timestamp(stderr); No bundle (reason: useless for push emails).