131
131
static char* internal_innobase_data_file_path = NULL;
133
/* Possible values for system variable "innodb_stats_method". The values
134
are defined the same as its corresponding MyISAM system variable
135
"myisam_stats_method"(see "myisam_stats_method_names"), for better usability */
136
static const char* innodb_stats_method_names[] = {
143
/* Used to define an enumerate type of the system variable innodb_stats_method.
144
This is the same as "myisam_stats_method_typelib" */
145
static TYPELIB innodb_stats_method_typelib = {
146
array_elements(innodb_stats_method_names) - 1,
147
"innodb_stats_method_typelib",
148
innodb_stats_method_names,
133
152
/* The following counter is used to convey information to InnoDB
134
153
about server activity: in selects it is not sensible to call
135
154
srv_active_wake_master_thread after each fetch or search, we only do
170
189
/*============================*/
171
190
/* out: true if index name matches a
173
const trx_t* trx, /* in: InnoDB transaction handle */
192
THD* thd, /* in/out: MySQL connection */
174
193
const TABLE* form, /* in: information on table
175
194
columns and indexes */
176
195
const char* norm_name); /* in: table name */
3066
/******************************************************************
3067
Sets a field in a record to SQL NULL. Uses the record format
3068
information in table to track the null bit in record. */
3071
set_field_in_record_to_null(
3072
/*========================*/
3073
TABLE* table, /* in: MySQL table object */
3074
Field* field, /* in: MySQL field object */
3075
char* record) /* in: a row in MySQL format */
3079
null_offset = (uint) ((char*) field->null_ptr
3080
- (char*) table->record[0]);
3082
record[null_offset] = record[null_offset] | field->null_bit;
3086
3086
/*****************************************************************
3087
3087
InnoDB uses this function to compare two data fields for which the data type
4264
4263
/* The field has changed */
4266
4265
ufield = uvect->fields + n_changed;
4266
UNIV_MEM_INVALID(ufield, sizeof *ufield);
4268
4268
/* Let us use a dummy dfield to make the conversion
4269
4269
from the MySQL column format to the InnoDB format */
4271
dict_col_copy_type_noninline(prebuilt->table->cols + i,
4274
4271
if (n_len != UNIV_SQL_NULL) {
4272
dict_col_copy_type_noninline(
4273
prebuilt->table->cols + i,
4275
4276
buf = row_mysql_store_col_in_innobase_format(
4282
4283
prebuilt->table));
4283
4284
ufield->new_val.data = dfield.data;
4284
4285
ufield->new_val.len = dfield.len;
4286
ufield->new_val.type = dfield.type;
4286
4288
ufield->new_val.data = NULL;
4287
4289
ufield->new_val.len = UNIV_SQL_NULL;
4292
ufield->extern_storage = FALSE;
4290
4293
ufield->exp = NULL;
4291
4294
ufield->field_no = dict_col_get_clust_pos_noninline(
4292
4295
&prebuilt->table->cols[i], clust_index);
5266
5268
DBUG_PRINT("enter", ("table_name: %s", table_name));
5268
5270
ut_a(trx->mysql_thd != NULL);
5269
if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(table_name,
5270
(THD*) trx->mysql_thd)) {
5271
DBUG_RETURN(HA_ERR_GENERIC);
5274
5272
n_cols = form->s->fields;
5623
5623
DBUG_RETURN(HA_ERR_TO_BIG_ROW);
5626
/* Get the transaction associated with the current thd, or create one
5627
if not yet created */
5629
parent_trx = check_trx_exists(thd);
5631
/* In case MySQL calls this in the middle of a SELECT query, release
5632
possible adaptive hash latch to avoid deadlocks of threads */
5634
trx_search_latch_release_if_reserved(parent_trx);
5636
trx = trx_allocate_for_mysql();
5638
trx->mysql_thd = thd;
5639
INNOBASE_COPY_STMT(thd, trx);
5641
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5642
trx->check_foreigns = FALSE;
5645
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
5646
trx->check_unique_secondary = FALSE;
5649
if (lower_case_table_names) {
5650
srv_lower_case_table_names = TRUE;
5652
srv_lower_case_table_names = FALSE;
5655
5626
strcpy(name2, name);
5657
5628
normalize_table_name(norm_name, name2);
5659
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
5660
or lock waits can happen in it during a table create operation.
5661
Drop table etc. do this latching in row0mysql.c. */
5663
row_mysql_lock_data_dictionary(trx);
5665
5630
/* Create the table definition in InnoDB */
5669
if (form->s->row_type != ROW_TYPE_REDUNDANT) {
5670
flags |= DICT_TF_COMPACT;
5632
flags = form->s->row_type != ROW_TYPE_REDUNDANT ? DICT_TF_COMPACT : 0;
5673
5634
/* Look for a primary key */
5684
5645
/* Check for name conflicts (with reserved name) for
5685
5646
any user indices to be created. */
5686
if (innobase_index_name_is_reserved(trx, form, norm_name)) {
5647
if (innobase_index_name_is_reserved(thd, form, norm_name)) {
5651
if (IS_MAGIC_TABLE_AND_USER_DENIED_ACCESS(norm_name, thd)) {
5652
DBUG_RETURN(HA_ERR_GENERIC);
5655
/* Get the transaction associated with the current thd, or create one
5656
if not yet created */
5658
parent_trx = check_trx_exists(thd);
5660
/* In case MySQL calls this in the middle of a SELECT query, release
5661
possible adaptive hash latch to avoid deadlocks of threads */
5663
trx_search_latch_release_if_reserved(parent_trx);
5665
trx = trx_allocate_for_mysql();
5667
trx->mysql_thd = thd;
5668
INNOBASE_COPY_STMT(thd, trx);
5670
if (thd_test_options(thd, OPTION_NO_FOREIGN_KEY_CHECKS)) {
5671
trx->check_foreigns = FALSE;
5674
if (thd_test_options(thd, OPTION_RELAXED_UNIQUE_CHECKS)) {
5675
trx->check_unique_secondary = FALSE;
5678
/* Latch the InnoDB data dictionary exclusively so that no deadlocks
5679
or lock waits can happen in it during a table create operation.
5680
Drop table etc. do this latching in row0mysql.c. */
5682
row_mysql_lock_data_dictionary(trx);
5691
5684
error = create_table_def(trx, form, norm_name,
5692
5685
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
5918
5911
trx_search_latch_release_if_reserved(parent_trx);
5920
if (lower_case_table_names) {
5921
srv_lower_case_table_names = TRUE;
5923
srv_lower_case_table_names = FALSE;
5926
5913
trx = trx_allocate_for_mysql();
5928
5915
trx->mysql_thd = thd;
6071
6060
trx_search_latch_release_if_reserved(parent_trx);
6073
if (lower_case_table_names) {
6074
srv_lower_case_table_names = TRUE;
6076
srv_lower_case_table_names = FALSE;
6079
6062
trx = trx_allocate_for_mysql();
6080
6063
trx->mysql_thd = thd;
6081
6064
INNOBASE_COPY_STMT(thd, trx);
6096
6079
/* Rename the table in InnoDB */
6081
srv_lower_case_table_names = lower_case_table_names;
6098
6083
error = row_rename_table_for_mysql(norm_from, norm_to, trx);
6100
6085
/* Flush the log to reduce probability that the .frm files and
6215
6201
(const uchar*) 0),
6216
6202
(ulint) (min_key ? min_key->length : 0),
6217
6203
prebuilt->trx);
6205
? range_start->n_fields > 0
6206
: range_start->n_fields == 0);
6219
6208
row_sel_convert_mysql_key_to_innobase(
6220
6209
range_end, (byte*) key_val_buff2,
6223
6212
(const uchar*) 0),
6224
6213
(ulint) (max_key ? max_key->length : 0),
6225
6214
prebuilt->trx);
6216
? range_end->n_fields > 0
6217
: range_end->n_fields == 0);
6227
6219
mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag :
6228
6220
HA_READ_KEY_EXACT);
6365
6357
/*************************************************************************
6358
Calculate Record Per Key value. Need to exclude the NULL value if
6359
innodb_stats_method is set to "nulls_ignored" */
6364
/* out: estimated record per key
6366
dict_index_t* index, /* in: dict_index_t structure */
6367
ulint i, /* in: the column we are
6368
calculating rec per key */
6369
ha_rows records) /* in: estimated total records */
6371
ha_rows rec_per_key;
6373
ut_ad(i < dict_index_get_n_unique(index));
6375
/* Note the stat_n_diff_key_vals[] stores the diff value with
6376
n-prefix indexing, so it is always stat_n_diff_key_vals[i + 1] */
6377
if (index->stat_n_diff_key_vals[i + 1] == 0) {
6379
rec_per_key = records;
6380
} else if (srv_innodb_stats_method == SRV_STATS_NULLS_IGNORED) {
6381
ib_longlong num_null;
6383
/* Number of rows with NULL value in this
6385
num_null = records - index->stat_n_non_null_key_vals[i];
6387
/* In theory, index->stat_n_non_null_key_vals[i]
6388
should always be less than the number of records.
6389
Since this is statistics value, the value could
6390
have slight discrepancy. But we will make sure
6391
the number of null values is not a negative number. */
6392
num_null = (num_null < 0) ? 0 : num_null;
6394
/* If the number of NULL values is the same as or
6395
large than that of the distinct values, we could
6396
consider that the table consists mostly of NULL value.
6397
Set rec_per_key to 1. */
6398
if (index->stat_n_diff_key_vals[i + 1] <= num_null) {
6401
/* Need to exclude rows with NULL values from
6402
rec_per_key calculation */
6403
rec_per_key = (ha_rows)(
6404
(records - num_null)
6405
/ (index->stat_n_diff_key_vals[i + 1]
6409
rec_per_key = (ha_rows)
6410
(records / index->stat_n_diff_key_vals[i + 1]);
6413
return(rec_per_key);
6416
/*************************************************************************
6366
6417
Returns statistics information of the table to the MySQL interpreter,
6367
6418
in various fields of the handle object. */
6571
if (index->stat_n_diff_key_vals[j + 1] == 0) {
6573
rec_per_key = stats.records;
6575
rec_per_key = (ha_rows)(stats.records /
6576
index->stat_n_diff_key_vals[j + 1]);
6622
rec_per_key = innodb_rec_per_key(
6623
index, j, stats.records);
6579
6625
/* Since MySQL seems to favor table scans
6580
6626
too much over index searches, we pretend
7055
7101
case HA_EXTRA_RESET_STATE:
7056
7102
reset_template(prebuilt);
7103
thd_to_trx(ha_thd())->duplicates = 0;
7058
7105
case HA_EXTRA_NO_KEYREAD:
7059
7106
prebuilt->read_just_key = 0;
7071
7118
parameters below. We must not invoke update_thd()
7072
7119
either, because the calling threads may change.
7073
7120
CAREFUL HERE, OR MEMORY CORRUPTION MAY OCCUR! */
7074
case HA_EXTRA_IGNORE_DUP_KEY:
7121
case HA_EXTRA_INSERT_WITH_UPDATE:
7075
7122
thd_to_trx(ha_thd())->duplicates |= TRX_DUP_IGNORE;
7124
case HA_EXTRA_NO_IGNORE_DUP_KEY:
7125
thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_IGNORE;
7077
7127
case HA_EXTRA_WRITE_CAN_REPLACE:
7078
7128
thd_to_trx(ha_thd())->duplicates |= TRX_DUP_REPLACE;
7080
7130
case HA_EXTRA_WRITE_CANNOT_REPLACE:
7081
7131
thd_to_trx(ha_thd())->duplicates &= ~TRX_DUP_REPLACE;
7083
case HA_EXTRA_NO_IGNORE_DUP_KEY:
7084
thd_to_trx(ha_thd())->duplicates &=
7085
~(TRX_DUP_IGNORE | TRX_DUP_REPLACE);
7087
7133
default:/* Do nothing */
7270
7316
reset_template(prebuilt);
7272
if (lock_type == F_WRLCK) {
7318
if (lock_type == F_WRLCK
7319
|| (table->s->tmp_table
7320
&& thd_sql_command(thd) == SQLCOM_LOCK_TABLES)) {
7274
7322
/* If this is a SELECT, then it is in UPDATE TABLE ...
7275
or SELECT ... FOR UPDATE */
7323
or SELECT ... FOR UPDATE
7325
For temporary tables which are locked for READ by LOCK TABLES
7326
updates are still allowed by SQL-layer. In order to accomodate
7327
for such a situation we always request X-lock for such table
7328
at LOCK TABLES time.
7276
7330
prebuilt->select_lock_type = LOCK_X;
7277
7331
prebuilt->stored_select_lock_type = LOCK_X;
8751
8807
/*============================*/
8752
8808
/* out: true if an index name
8753
8809
matches the reserved name */
8754
const trx_t* trx, /* in: InnoDB transaction handle */
8810
THD* thd, /* in/out: MySQL connection */
8755
8811
const TABLE* form, /* in: information on table
8756
8812
columns and indexes */
8757
8813
const char* norm_name) /* in: table name */
8765
8821
if (innobase_strcasecmp(key->name,
8766
8822
innobase_index_reserve_name) == 0) {
8767
8823
/* Push warning to mysql */
8768
push_warning_printf((THD*) trx->mysql_thd,
8824
push_warning_printf(thd,
8769
8825
MYSQL_ERROR::WARN_LEVEL_WARN,
8770
8826
ER_CANT_CREATE_TABLE,
8771
8827
"Cannot Create Index with name "
8990
9046
AUTOINC_OLD_STYLE_LOCKING, /* Minimum value */
8991
9047
AUTOINC_NO_LOCKING, 0); /* Maximum value */
9049
static MYSQL_SYSVAR_ENUM(stats_method, srv_innodb_stats_method,
9050
PLUGIN_VAR_RQCMDARG,
9051
"Specifies how InnoDB index statistics collection code should "
9052
"treat NULLs. Possible values are NULLS_EQUAL (default), "
9053
"NULLS_UNEQUAL and NULLS_IGNORED",
9054
NULL, NULL, SRV_STATS_NULLS_EQUAL, &innodb_stats_method_typelib);
8993
9056
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
8994
9057
static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug,
8995
9058
PLUGIN_VAR_RQCMDARG,
9031
9094
MYSQL_SYSVAR(stats_on_metadata),
9032
9095
MYSQL_SYSVAR(use_legacy_cardinality_algorithm),
9033
9096
MYSQL_SYSVAR(adaptive_hash_index),
9097
MYSQL_SYSVAR(stats_method),
9034
9098
MYSQL_SYSVAR(status_file),
9035
9099
MYSQL_SYSVAR(support_xa),
9036
9100
MYSQL_SYSVAR(sync_spin_loops),