summaryrefslogtreecommitdiff
path: root/storage/xtradb/handler
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2011-02-28 19:39:30 +0200
committerMichael Widenius <monty@askmonty.org>2011-02-28 19:39:30 +0200
commit11ed10cbe2c7c4b83aca4153856e76f4bdc484dd (patch)
treeda0e622896425203d23ecdfd1bc77b57e3502edf /storage/xtradb/handler
parentdfcc0010cf7be502bfca31aff75ba830f6962264 (diff)
parent670f2f62c48741ea72440a1574dc99bae9390131 (diff)
downloadmariadb-git-11ed10cbe2c7c4b83aca4153856e76f4bdc484dd.tar.gz
Merge with 5.1 to get in changes from MySQL 5.1.55
Diffstat (limited to 'storage/xtradb/handler')
-rw-r--r--storage/xtradb/handler/ha_innodb.cc475
-rw-r--r--storage/xtradb/handler/handler0alter.cc11
-rw-r--r--storage/xtradb/handler/i_s.cc23
-rw-r--r--storage/xtradb/handler/innodb_patch_info.h1
4 files changed, 283 insertions, 227 deletions
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index ee060f61c75..23eb6ab67e4 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -149,6 +149,7 @@ static ulong innobase_read_io_threads;
static ulong innobase_write_io_threads;
static ulong innobase_page_size;
+static ulong innobase_log_block_size;
static my_bool innobase_thread_concurrency_timer_based;
static long long innobase_buffer_pool_size, innobase_log_file_size;
@@ -194,6 +195,7 @@ 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_use_sys_stats_table = FALSE;
+static my_bool innobase_buffer_pool_shm_checksum = TRUE;
static char* internal_innobase_data_file_path = NULL;
@@ -2114,6 +2116,32 @@ innobase_init(
goto error;
}
+ srv_log_block_size = 0;
+ if (innobase_log_block_size != (1 << 9)) { /*!=512*/
+ uint n_shift;
+
+ fprintf(stderr,
+ "InnoDB: Warning: innodb_log_block_size has been changed from default value 512. (###EXPERIMENTAL### operation)\n");
+ for (n_shift = 9; n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX; n_shift++) {
+ if (innobase_log_block_size == ((ulong)1 << n_shift)) {
+ srv_log_block_size = (1 << n_shift);
+ fprintf(stderr,
+ "InnoDB: The log block size is set to %lu.\n",
+ srv_log_block_size);
+ break;
+ }
+ }
+ } else {
+ srv_log_block_size = 512;
+ }
+
+ if (!srv_log_block_size) {
+ fprintf(stderr,
+ "InnoDB: Error: %lu is not valid value for innodb_log_block_size.\n",
+ innobase_log_block_size);
+ goto error;
+ }
+
#ifndef MYSQL_SERVER
innodb_overwrite_relay_log_info = FALSE;
#endif
@@ -2417,7 +2445,7 @@ innobase_change_buffering_inited_ok:
srv_n_write_io_threads = (ulint) innobase_write_io_threads;
srv_read_ahead &= 3;
- srv_adaptive_checkpoint %= 3;
+ srv_adaptive_checkpoint %= 4;
srv_force_recovery = (ulint) innobase_force_recovery;
@@ -2426,6 +2454,7 @@ innobase_change_buffering_inited_ok:
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
srv_use_checksums = (ibool) innobase_use_checksums;
srv_fast_checksum = (ibool) innobase_fast_checksum;
+ srv_buffer_pool_shm_checksum = (ibool) innobase_buffer_pool_shm_checksum;
#ifdef HAVE_LARGE_PAGES
if ((os_use_large_pages = (ibool) my_use_large_pages))
@@ -3871,6 +3900,7 @@ retry:
of length ref_length! */
if (!row_table_got_default_clust_index(ib_table)) {
+
prebuilt->clust_index_was_generated = FALSE;
if (UNIV_UNLIKELY(primary_key >= MAX_KEY)) {
@@ -6399,6 +6429,16 @@ create_table_def(
DBUG_RETURN(HA_ERR_GENERIC);
}
+ /* MySQL does the name length check. But we do additional check
+ on the name length here */
+ if (strlen(table_name) > MAX_FULL_NAME_LEN) {
+ push_warning_printf(
+ (THD*) trx->mysql_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_TABLE_NAME,
+ "InnoDB: Table Name or Database Name is too long");
+ DBUG_RETURN(ER_TABLE_NAME);
+ }
+
n_cols = form->s->fields;
/* We pass 0 as the space id, and determine at a lower level the space
@@ -6683,6 +6723,60 @@ create_clustered_index_when_no_primary(
}
/*****************************************************************//**
+Return a display name for the row format
+@return row format name */
+UNIV_INTERN
+const char*
+get_row_format_name(
+/*================*/
+ enum row_type row_format) /*!< in: Row Format */
+{
+ switch (row_format) {
+ case ROW_TYPE_COMPACT:
+ return("COMPACT");
+ case ROW_TYPE_COMPRESSED:
+ return("COMPRESSED");
+ case ROW_TYPE_DYNAMIC:
+ return("DYNAMIC");
+ case ROW_TYPE_REDUNDANT:
+ return("REDUNDANT");
+ case ROW_TYPE_DEFAULT:
+ return("DEFAULT");
+ case ROW_TYPE_FIXED:
+ return("FIXED");
+ case ROW_TYPE_PAGE:
+ case ROW_TYPE_NOT_USED:
+ break;
+ }
+ return("NOT USED");
+}
+
+/** 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) { \
+ push_warning_printf( \
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN, \
+ ER_ILLEGAL_HA_CREATE_OPTION, \
+ "InnoDB: ROW_FORMAT=%s requires" \
+ " innodb_file_per_table.", \
+ get_row_format_name(row_format)); \
+ ret = FALSE; \
+ }
+
+/** If file-format is Antelope, issue warning and set ret false */
+#define CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE \
+ if (srv_file_format < DICT_TF_FORMAT_ZIP) { \
+ push_warning_printf( \
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN, \
+ ER_ILLEGAL_HA_CREATE_OPTION, \
+ "InnoDB: ROW_FORMAT=%s requires" \
+ " innodb_file_format > Antelope.", \
+ get_row_format_name(row_format)); \
+ ret = FALSE; \
+ }
+
+
+/*****************************************************************//**
Validates the create options. We may build on this function
in future. For now, it checks two specifiers:
KEY_BLOCK_SIZE and ROW_FORMAT
@@ -6697,9 +6791,9 @@ create_options_are_valid(
columns and indexes */
HA_CREATE_INFO* create_info) /*!< in: create info. */
{
- ibool kbs_specified = FALSE;
+ ibool kbs_specified = FALSE;
ibool ret = TRUE;
-
+ enum row_type row_format = form->s->row_type;
ut_ad(thd != NULL);
@@ -6711,10 +6805,8 @@ create_options_are_valid(
ut_ad(form != NULL);
ut_ad(create_info != NULL);
- /* First check if KEY_BLOCK_SIZE was specified. */
- if (create_info->key_block_size
- || (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) {
-
+ /* First check if a non-zero KEY_BLOCK_SIZE was specified. */
+ if (create_info->key_block_size) {
kbs_specified = TRUE;
switch (create_info->key_block_size) {
case 1:
@@ -6722,127 +6814,71 @@ create_options_are_valid(
case 4:
case 8:
case 16:
- /* Valid value. */
- break;
- default:
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: invalid"
- " KEY_BLOCK_SIZE = %lu."
- " Valid values are"
- " [1, 2, 4, 8, 16]",
- create_info->key_block_size);
- ret = FALSE;
- }
- }
-
- /* If KEY_BLOCK_SIZE was specified, check for its
- dependencies. */
- if (kbs_specified && !srv_file_per_table) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: KEY_BLOCK_SIZE"
- " requires innodb_file_per_table.");
- ret = FALSE;
- }
-
- if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: KEY_BLOCK_SIZE"
- " requires innodb_file_format >"
- " Antelope.");
- ret = FALSE;
- }
-
- /* Now check for ROW_FORMAT specifier. */
- if (create_info->used_fields & HA_CREATE_USED_ROW_FORMAT) {
- switch (form->s->row_type) {
- const char* row_format_name;
- case ROW_TYPE_COMPRESSED:
- case ROW_TYPE_DYNAMIC:
- row_format_name
- = form->s->row_type == ROW_TYPE_COMPRESSED
- ? "COMPRESSED"
- : "DYNAMIC";
-
- /* These two ROW_FORMATs require srv_file_per_table
- and srv_file_format > Antelope */
+ /* Valid KEY_BLOCK_SIZE, check its dependencies. */
if (!srv_file_per_table) {
- push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ROW_FORMAT=%s"
- " requires innodb_file_per_table.",
- row_format_name);
- ret = FALSE;
+ "InnoDB: KEY_BLOCK_SIZE requires"
+ " innodb_file_per_table.");
+ ret = FALSE;
}
-
if (srv_file_format < DICT_TF_FORMAT_ZIP) {
- push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ROW_FORMAT=%s"
- " requires innodb_file_format >"
- " Antelope.",
- row_format_name);
- ret = FALSE;
- }
-
- /* Cannot specify KEY_BLOCK_SIZE with
- ROW_FORMAT = DYNAMIC.
- However, we do allow COMPRESSED to be
- specified with KEY_BLOCK_SIZE. */
- if (kbs_specified
- && form->s->row_type == ROW_TYPE_DYNAMIC) {
- push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: cannot specify"
- " ROW_FORMAT = DYNAMIC with"
- " KEY_BLOCK_SIZE.");
+ "InnoDB: KEY_BLOCK_SIZE requires"
+ " innodb_file_format > Antelope.");
ret = FALSE;
}
-
break;
-
- case ROW_TYPE_REDUNDANT:
- case ROW_TYPE_COMPACT:
- case ROW_TYPE_DEFAULT:
- /* Default is COMPACT. */
- row_format_name
- = form->s->row_type == ROW_TYPE_REDUNDANT
- ? "REDUNDANT"
- : "COMPACT";
-
- /* Cannot specify KEY_BLOCK_SIZE with these
- format specifiers. */
- if (kbs_specified) {
- push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: cannot specify"
- " ROW_FORMAT = %s with"
- " KEY_BLOCK_SIZE.",
- row_format_name);
- ret = FALSE;
- }
-
- break;
-
default:
- push_warning(thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: invalid ROW_FORMAT specifier.");
+ push_warning_printf(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: invalid KEY_BLOCK_SIZE = %lu."
+ " Valid values are [1, 2, 4, 8, 16]",
+ create_info->key_block_size);
ret = FALSE;
-
+ break;
}
}
+
+ /* Check for a valid Innodb ROW_FORMAT specifier and
+ other incompatibilities. */
+ switch (row_format) {
+ case ROW_TYPE_COMPRESSED:
+ CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE;
+ 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_GT_ANTELOPE;
+ /* fall through since dynamic also shuns KBS */
+ case ROW_TYPE_COMPACT:
+ case ROW_TYPE_REDUNDANT:
+ if (kbs_specified) {
+ push_warning_printf(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: cannot specify ROW_FORMAT = %s"
+ " with KEY_BLOCK_SIZE.",
+ get_row_format_name(row_format));
+ ret = FALSE;
+ }
+ break;
+ case ROW_TYPE_DEFAULT:
+ break;
+ case ROW_TYPE_FIXED:
+ case ROW_TYPE_PAGE:
+ case ROW_TYPE_NOT_USED:
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION, \
+ "InnoDB: invalid ROW_FORMAT specifier.");
+ ret = FALSE;
+ break;
+ }
return(ret);
}
@@ -6891,7 +6927,7 @@ ha_innobase::create(
const ulint file_format = srv_file_format;
const char* stmt;
size_t stmt_len;
- enum row_type row_type;
+ enum row_type row_format;
DBUG_ENTER("ha_innobase::create");
@@ -6967,8 +7003,7 @@ ha_innobase::create(
goto cleanup;
}
- if (create_info->key_block_size
- || (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)) {
+ if (create_info->key_block_size) {
/* Determine the page_zip.ssize corresponding to the
requested page size (key_block_size) in kilobytes. */
@@ -6989,40 +7024,40 @@ ha_innobase::create(
}
if (!srv_file_per_table) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: KEY_BLOCK_SIZE"
- " requires innodb_file_per_table.");
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: KEY_BLOCK_SIZE requires"
+ " innodb_file_per_table.");
flags = 0;
}
if (file_format < DICT_TF_FORMAT_ZIP) {
- push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: KEY_BLOCK_SIZE"
- " requires innodb_file_format >"
- " Antelope.");
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: KEY_BLOCK_SIZE requires"
+ " innodb_file_format > Antelope.");
flags = 0;
}
if (!flags) {
- push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ignoring"
- " KEY_BLOCK_SIZE=%lu.",
- create_info->key_block_size);
+ push_warning_printf(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: ignoring KEY_BLOCK_SIZE=%lu.",
+ create_info->key_block_size);
}
}
- row_type = form->s->row_type;
+ row_format = form->s->row_type;
if (flags) {
- /* if KEY_BLOCK_SIZE was specified on this statement and
- ROW_FORMAT was not, automatically change ROW_FORMAT to COMPRESSED.*/
- if ( (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)
- && !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) {
- row_type = ROW_TYPE_COMPRESSED;
- } else if (row_type != ROW_TYPE_COMPRESSED) {
+ /* if ROW_FORMAT is set to default,
+ automatically change it to COMPRESSED.*/
+ if (row_format == ROW_TYPE_DEFAULT) {
+ row_format = ROW_TYPE_COMPRESSED;
+ } else if (row_format != ROW_TYPE_COMPRESSED) {
/* ROW_FORMAT other than COMPRESSED
ignores KEY_BLOCK_SIZE. It does not
make sense to reject conflicting
@@ -7030,8 +7065,7 @@ ha_innobase::create(
such combinations can be obtained
with ALTER TABLE anyway. */
push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ignoring KEY_BLOCK_SIZE=%lu"
" unless ROW_FORMAT=COMPRESSED.",
@@ -7040,7 +7074,7 @@ ha_innobase::create(
}
} else {
/* flags == 0 means no KEY_BLOCK_SIZE.*/
- if (row_type == ROW_TYPE_COMPRESSED) {
+ if (row_format == ROW_TYPE_COMPRESSED) {
/* ROW_FORMAT=COMPRESSED without
KEY_BLOCK_SIZE implies half the
maximum KEY_BLOCK_SIZE. */
@@ -7055,49 +7089,40 @@ ha_innobase::create(
}
}
- switch (row_type) {
- const char* row_format_name;
+ switch (row_format) {
case ROW_TYPE_REDUNDANT:
break;
case ROW_TYPE_COMPRESSED:
case ROW_TYPE_DYNAMIC:
- row_format_name
- = row_type == ROW_TYPE_COMPRESSED
- ? "COMPRESSED"
- : "DYNAMIC";
-
if (!srv_file_per_table) {
push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ROW_FORMAT=%s"
- " requires innodb_file_per_table.",
- row_format_name);
+ "InnoDB: ROW_FORMAT=%s requires"
+ " innodb_file_per_table.",
+ get_row_format_name(row_format));
} else if (file_format < DICT_TF_FORMAT_ZIP) {
push_warning_printf(
- thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ROW_FORMAT=%s"
- " requires innodb_file_format >"
- " Antelope.",
- row_format_name);
+ "InnoDB: ROW_FORMAT=%s requires"
+ " innodb_file_format > Antelope.",
+ get_row_format_name(row_format));
} else {
flags |= DICT_TF_COMPACT
- | (DICT_TF_FORMAT_ZIP
- << DICT_TF_FORMAT_SHIFT);
+ | (DICT_TF_FORMAT_ZIP
+ << DICT_TF_FORMAT_SHIFT);
break;
}
/* fall through */
case ROW_TYPE_NOT_USED:
case ROW_TYPE_FIXED:
- default:
- push_warning(thd,
- MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: assuming ROW_FORMAT=COMPACT.");
+ case ROW_TYPE_PAGE:
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: assuming ROW_FORMAT=COMPACT.");
case ROW_TYPE_DEFAULT:
case ROW_TYPE_COMPACT:
flags = DICT_TF_COMPACT;
@@ -7211,23 +7236,25 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
- does a table copy too. */
+ this is an ALTER|OPTIMIZE TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. If query was one of :
+
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ OPTIMIZE TABLE t; or
+ CREATE INDEX x on t(...);
+
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
|| thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_OPTIMIZE
|| thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
&& create_info->auto_increment_value > 0) {
- /* Query was one of :
- CREATE TABLE ...AUTO_INCREMENT = x; or
- ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE INDEX x on t(...);
- Find out a table definition from the dictionary and get
- the current value of the auto increment field. Set a new
- value to the auto increment field if the value is greater
- than the maximum value in the column. */
-
auto_inc_value = create_info->auto_increment_value;
dict_table_autoinc_lock(innobase_table);
@@ -7280,6 +7307,14 @@ ha_innobase::discard_or_import_tablespace(
err = row_discard_tablespace_for_mysql(dict_table->name, trx);
} else {
err = row_import_tablespace_for_mysql(dict_table->name, trx);
+
+ /* in expanded import mode re-initialize auto_increment again */
+ if ((err == DB_SUCCESS) && srv_expand_import &&
+ (table->found_next_number_field != NULL)) {
+ dict_table_autoinc_lock(dict_table);
+ innobase_initialize_autoinc();
+ dict_table_autoinc_unlock(dict_table);
+ }
}
err = convert_error_code_to_mysql(err, dict_table->flags, NULL);
@@ -7745,6 +7780,7 @@ ha_innobase::estimate_rows_upper_bound(void)
dict_index_t* index;
ulonglong estimate;
ulonglong local_data_file_length;
+ ulint stat_n_leaf_pages;
DBUG_ENTER("estimate_rows_upper_bound");
@@ -7764,10 +7800,12 @@ ha_innobase::estimate_rows_upper_bound(void)
index = dict_table_get_first_index(prebuilt->table);
- ut_a(index->stat_n_leaf_pages > 0);
+ stat_n_leaf_pages = index->stat_n_leaf_pages;
+
+ ut_a(stat_n_leaf_pages > 0);
local_data_file_length =
- ((ulonglong) index->stat_n_leaf_pages) * UNIV_PAGE_SIZE;
+ ((ulonglong) stat_n_leaf_pages) * UNIV_PAGE_SIZE;
/* Calculate a minimum length for a clustered index record and from
@@ -7970,13 +8008,12 @@ ha_innobase::info_low(
ib_table = prebuilt->table;
if (flag & HA_STATUS_TIME) {
- if ((called_from_analyze || innobase_stats_on_metadata)
- && !share->ib_table->is_corrupt) {
+ if ((called_from_analyze || innobase_stats_on_metadata) && !share->ib_table->is_corrupt) {
/* In sql_show we call with this flag: update
then statistics so that they are up-to-date */
if (srv_use_sys_stats_table && !((ib_table->flags >> DICT_TF2_SHIFT) & DICT_TF2_TEMPORARY)
- && thd_sql_command(user_thd) == SQLCOM_ANALYZE) {
+ && called_from_analyze) {
/* If the indexes on the table don't have enough rows in SYS_STATS system table, */
/* they need to be created. */
dict_index_t* index;
@@ -7998,7 +8035,8 @@ ha_innobase::info_low(
prebuilt->trx->op_info = "updating table statistics";
dict_update_statistics(ib_table,
- (thd_sql_command(user_thd) == SQLCOM_ANALYZE)?TRUE:FALSE);
+ FALSE /* update even if stats
+ are initialized */, called_from_analyze);
prebuilt->trx->op_info = "returning various info to MySQL";
}
@@ -8017,6 +8055,9 @@ ha_innobase::info_low(
}
if (flag & HA_STATUS_VARIABLE) {
+
+ dict_table_stats_lock(ib_table, RW_S_LATCH);
+
n_rows = ib_table->stat_n_rows;
/* Because we do not protect stat_n_rows by any mutex in a
@@ -8066,12 +8107,14 @@ ha_innobase::info_low(
ib_table->stat_sum_of_other_index_sizes)
* UNIV_PAGE_SIZE;
+ dict_table_stats_unlock(ib_table, RW_S_LATCH);
+
/* Since fsp_get_available_space_in_free_extents() is
acquiring latches inside InnoDB, we do not call it if we
are asked by MySQL to avoid locking. Another reason to
avoid the call is that it uses quite a lot of CPU.
See Bug#38185. */
- if (flag & HA_STATUS_NO_LOCK) {
+ if (flag & HA_STATUS_NO_LOCK || !srv_stats_update_need_lock) {
/* We do not update delete_length if no
locking is requested so the "old" value can
remain. delete_length is initialized to 0 in
@@ -8081,21 +8124,13 @@ ha_innobase::info_low(
/* Avoid accessing the tablespace if
innodb_crash_recovery is set to a high value. */
stats.delete_length = 0;
- } else if (srv_stats_update_need_lock) {
-
- /* lock the data dictionary to avoid races with
- ibd_file_missing and tablespace_discarded */
- row_mysql_lock_data_dictionary(prebuilt->trx);
+ } else {
+ ullint avail_space;
- /* ib_table->space must be an existent tablespace */
- if (!ib_table->ibd_file_missing
- && !ib_table->tablespace_discarded) {
-
- stats.delete_length =
- fsp_get_available_space_in_free_extents(
- ib_table->space) * 1024;
- } else {
+ avail_space = fsp_get_available_space_in_free_extents(
+ ib_table->space);
+ if (avail_space == ULLINT_UNDEFINED) {
THD* thd;
thd = ha_thd();
@@ -8112,9 +8147,9 @@ ha_innobase::info_low(
ib_table->name);
stats.delete_length = 0;
+ } else {
+ stats.delete_length = avail_space * 1024;
}
-
- row_mysql_unlock_data_dictionary(prebuilt->trx);
}
stats.check_time = 0;
@@ -8143,6 +8178,8 @@ ha_innobase::info_low(
table->s->keys);
}
+ dict_table_stats_lock(ib_table, RW_S_LATCH);
+
for (i = 0; i < table->s->keys; i++) {
ulong j;
/* We could get index quickly through internal
@@ -8180,8 +8217,6 @@ ha_innobase::info_low(
break;
}
- dict_index_stat_mutex_enter(index);
-
if (index->stat_n_diff_key_vals[j + 1] == 0) {
rec_per_key = stats.records;
@@ -8190,8 +8225,6 @@ ha_innobase::info_low(
index->stat_n_diff_key_vals[j + 1]);
}
- dict_index_stat_mutex_exit(index);
-
/* Since MySQL seems to favor table scans
too much over index searches, we pretend
index selectivity is 2 times better than
@@ -8208,6 +8241,8 @@ ha_innobase::info_low(
(ulong) rec_per_key;
}
}
+
+ dict_table_stats_unlock(ib_table, RW_S_LATCH);
}
if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
@@ -11187,6 +11222,11 @@ static MYSQL_SYSVAR_ULONG(page_size, innobase_page_size,
"###EXPERIMENTAL###: The universal page size of the database. Changing for created database is not supported. Use on your own risk!",
NULL, NULL, (1 << 14), (1 << 12), (1 << UNIV_PAGE_SIZE_SHIFT_MAX), 0);
+static MYSQL_SYSVAR_ULONG(log_block_size, innobase_log_block_size,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "###EXPERIMENTAL###: The log block size of the transaction log file. Changing for created log file is not supported. Use on your own risk!",
+ NULL, NULL, (1 << 9)/*512*/, (1 << 9)/*512*/, (1 << UNIV_PAGE_SIZE_SHIFT_MAX), 0);
+
static MYSQL_SYSVAR_STR(data_home_dir, innobase_data_home_dir,
PLUGIN_VAR_READONLY,
"The common part for InnoDB table spaces.",
@@ -11405,6 +11445,16 @@ static MYSQL_SYSVAR_LONGLONG(buffer_pool_size, innobase_buffer_pool_size,
"The size of the memory buffer InnoDB uses to cache data and indexes of its tables.",
NULL, NULL, 128*1024*1024L, 32*1024*1024L, LONGLONG_MAX, 1024*1024L);
+static MYSQL_SYSVAR_UINT(buffer_pool_shm_key, srv_buffer_pool_shm_key,
+ PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
+ "[experimental] The key value of shared memory segment for the buffer pool. 0 (default) disables the feature.",
+ NULL, NULL, 0, 0, INT_MAX32, 0);
+
+static MYSQL_SYSVAR_BOOL(buffer_pool_shm_checksum, innobase_buffer_pool_shm_checksum,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "Enable buffer_pool_shm checksum validation (enabled by default).",
+ NULL, NULL, TRUE);
+
static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency,
PLUGIN_VAR_RQCMDARG,
"Helps in performance tuning in heavily concurrent environments.",
@@ -11615,17 +11665,19 @@ innodb_adaptive_checkpoint_update(
void* var_ptr,
const void* save)
{
- *(long *)var_ptr= (*(long *)save) % 3;
+ *(long *)var_ptr= (*(long *)save) % 4;
}
const char *adaptive_checkpoint_names[]=
{
"none", /* 0 */
"reflex", /* 1 */
"estimate", /* 2 */
+ "keep_average", /* 3 */
/* For compatibility of the older patch */
- "0", /* 3 ("none" + 3) */
- "1", /* 4 ("reflex" + 3) */
- "2", /* 5 ("estimate" + 3) */
+ "0", /* 4 ("none" + 3) */
+ "1", /* 5 ("reflex" + 3) */
+ "2", /* 6 ("estimate" + 3) */
+ "3", /* 7 ("keep_average" + 4) */
NullS
};
TYPELIB adaptive_checkpoint_typelib=
@@ -11635,7 +11687,7 @@ TYPELIB adaptive_checkpoint_typelib=
};
static MYSQL_SYSVAR_ENUM(adaptive_checkpoint, srv_adaptive_checkpoint,
PLUGIN_VAR_RQCMDARG,
- "Enable/Disable flushing along modified age. (none, reflex, [estimate])",
+ "Enable/Disable flushing along modified age. (none, reflex, [estimate], keep_average)",
NULL, innodb_adaptive_checkpoint_update, 2, &adaptive_checkpoint_typelib);
static MYSQL_SYSVAR_ULONG(enable_unsafe_group_commit, srv_enable_unsafe_group_commit,
@@ -11674,9 +11726,12 @@ static MYSQL_SYSVAR_ULINT(pass_corrupt_table, srv_pass_corrupt_table,
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(page_size),
+ MYSQL_SYSVAR(log_block_size),
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
MYSQL_SYSVAR(buffer_pool_size),
+ MYSQL_SYSVAR(buffer_pool_shm_key),
+ MYSQL_SYSVAR(buffer_pool_shm_checksum),
MYSQL_SYSVAR(checksums),
MYSQL_SYSVAR(fast_checksum),
MYSQL_SYSVAR(commit_concurrency),
diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc
index 3a32ed9cf36..c54b4a17fd2 100644
--- a/storage/xtradb/handler/handler0alter.cc
+++ b/storage/xtradb/handler/handler0alter.cc
@@ -1012,12 +1012,13 @@ ha_innobase::prepare_drop_index(
index->to_be_dropped = TRUE;
}
- /* If FOREIGN_KEY_CHECK = 1 you may not drop an index defined
+ /* If FOREIGN_KEY_CHECKS = 1 you may not drop an index defined
for a foreign key constraint because InnoDB requires that both
- tables contain indexes for the constraint. Note that CREATE
- INDEX id ON table does a CREATE INDEX and DROP INDEX, and we
- can ignore here foreign keys because a new index for the
- foreign key has already been created.
+ tables contain indexes for the constraint. Such index can
+ be dropped only if FOREIGN_KEY_CHECKS is set to 0.
+ Note that CREATE INDEX id ON table does a CREATE INDEX and
+ DROP INDEX, and we can ignore here foreign keys because a
+ new index for the foreign key has already been created.
We check for the foreign key constraints after marking the
candidate indexes for deletion, because when we check for an
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 0793daf7650..dead374e782 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -1451,8 +1451,16 @@ fill_innodb_trx_from_cache(
row->trx_mysql_thread_id));
/* trx_query */
- OK(field_store_string(fields[IDX_TRX_QUERY],
- row->trx_query));
+ if (row->trx_query) {
+ /* store will do appropriate character set
+ conversion check */
+ fields[IDX_TRX_QUERY]->store(
+ row->trx_query, strlen(row->trx_query),
+ row->trx_query_cs);
+ fields[IDX_TRX_QUERY]->set_notnull();
+ } else {
+ fields[IDX_TRX_QUERY]->set_null();
+ }
OK(schema_table_store_record(thd, table));
}
@@ -1709,16 +1717,7 @@ fill_innodb_locks_from_cache(
for (i = 0; i < rows_num; i++) {
i_s_locks_row_t* row;
-
- /* note that the decoded database or table name is
- never expected to be longer than NAME_LEN;
- NAME_LEN for database name
- 2 for surrounding quotes around database name
- NAME_LEN for table name
- 2 for surrounding quotes around table name
- 1 for the separating dot (.)
- 9 for the #mysql50# prefix */
- char buf[2 * NAME_LEN + 14];
+ char buf[MAX_FULL_NAME_LEN + 1];
const char* bufend;
char lock_trx_id[TRX_ID_MAX_LEN + 1];
diff --git a/storage/xtradb/handler/innodb_patch_info.h b/storage/xtradb/handler/innodb_patch_info.h
index 38b97411340..e68f12d0fec 100644
--- a/storage/xtradb/handler/innodb_patch_info.h
+++ b/storage/xtradb/handler/innodb_patch_info.h
@@ -47,5 +47,6 @@ struct innodb_enhancement {
{"innodb_fast_checksum","Using the checksum on 32bit-unit calculation","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_files_extend","allow >4GB transaction log files, and can vary universal page size of datafiles","incompatible for unpatched ver.","http://www.percona.com/docs/wiki/percona-xtradb"},
{"innodb_sys_tables_sys_indexes","Expose InnoDB SYS_TABLES and SYS_INDEXES schema tables","","http://www.percona.com/docs/wiki/percona-xtradb"},
+{"innodb_buffer_pool_shm","Put buffer pool contents to shared memory segment and reuse it at clean restart [experimental]","","http://www.percona.com/docs/wiki/percona-xtradb"},
{NULL, NULL, NULL, NULL}
};