11
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
17
*****************************************************************************/
95
93
((str1_len) == sizeof(str2_onstack) \
96
94
&& memcmp(str1, str2_onstack, sizeof(str2_onstack)) == 0)
96
/*******************************************************************//**
97
Determine if the given name is a name reserved for MySQL system tables.
98
@return TRUE if name is a MySQL system table name */
101
row_mysql_is_system_table(
102
/*======================*/
105
if (strncmp(name, "mysql/", 6) != 0) {
110
return(0 == strcmp(name + 6, "host")
111
|| 0 == strcmp(name + 6, "user")
112
|| 0 == strcmp(name + 6, "db"));
98
115
/*********************************************************************//**
99
116
If a table is not yet in the drop list, adds the table to the list of tables
100
117
which the master thread drops in background. We need this on Unix because in
251
268
/**************************************************************//**
252
Pad a column with spaces. */
257
ulint mbminlen, /*!< in: minimum size of a character,
259
byte* pad, /*!< out: padded buffer */
260
ulint len) /*!< in: number of bytes to pad */
264
switch (UNIV_EXPECT(mbminlen, 1)) {
269
memset(pad, 0x20, len);
278
} while (pad < pad_end);
281
/* space=0x00000020 */
289
} while (pad < pad_end);
294
/**************************************************************//**
295
269
Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
296
270
The counterpart of this function is row_sel_field_store_in_mysql_format() in
383
357
/* Remove trailing spaces from old style VARCHAR
386
/* Handle Unicode strings differently. */
360
/* Handle UCS2 strings differently. */
387
361
ulint mbminlen = dtype_get_mbminlen(dtype);
389
363
ptr = mysql_data;
395
/* space=0x00000020 */
396
/* Trim "half-chars", just in case. */
400
&& ptr[col_len - 4] == 0x00
401
&& ptr[col_len - 3] == 0x00
402
&& ptr[col_len - 2] == 0x00
403
&& ptr[col_len - 1] == 0x20) {
408
366
/* space=0x0020 */
409
367
/* Trim "half-chars", just in case. */
921
868
/*********************************************************************//**
922
Unlocks AUTO_INC type locks that were possibly reserved by a trx. This
923
function should be called at the the end of an SQL statement, by the
924
connection thread that owns the transaction (trx->mysql_thd). */
869
Unlocks AUTO_INC type locks that were possibly reserved by a trx. */
927
872
row_unlock_table_autoinc_for_mysql(
928
873
/*===============================*/
929
874
trx_t* trx) /*!< in/out: transaction */
931
if (lock_trx_holds_autoinc_locks(trx)) {
932
mutex_enter(&kernel_mutex);
934
lock_release_autoinc_locks(trx);
936
mutex_exit(&kernel_mutex);
876
mutex_enter(&kernel_mutex);
878
lock_release_autoinc_locks(trx);
880
mutex_exit(&kernel_mutex);
940
883
/*********************************************************************//**
1497
1425
/*********************************************************************//**
1498
This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
1499
session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
1500
Before calling this function row_search_for_mysql() must have
1501
initialized prebuilt->new_rec_locks to store the information which new
1502
record locks really were set. This function removes a newly set
1503
clustered index record lock under prebuilt->pcur or
1504
prebuilt->clust_pcur. Thus, this implements a 'mini-rollback' that
1505
releases the latest clustered index record lock we set.
1506
@return error code or DB_SUCCESS */
1426
This can only be used when srv_locks_unsafe_for_binlog is TRUE or
1427
this session is using a READ COMMITTED isolation level. Before
1428
calling this function we must use trx_reset_new_rec_lock_info() and
1429
trx_register_new_rec_lock() to store the information which new record locks
1430
really were set. This function removes a newly set lock under prebuilt->pcur,
1431
and also under prebuilt->clust_pcur. Currently, this is only used and tested
1432
in the case of an UPDATE or a DELETE statement, where the row lock is of the
1434
Thus, this implements a 'mini-rollback' that releases the latest record
1436
@return error code or DB_SUCCESS */
1509
1439
row_unlock_for_mysql(
1510
1440
/*=================*/
1511
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct in MySQL
1441
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
1513
ibool has_latches_on_recs)/*!< in: TRUE if called so
1514
that we have the latches on
1515
the records under pcur and
1516
clust_pcur, and we do not need
1517
to reposition the cursors. */
1443
ibool has_latches_on_recs)/*!< TRUE if called so that we have
1444
the latches on the records under pcur
1445
and clust_pcur, and we do not need to
1446
reposition the cursors. */
1519
1448
btr_pcur_t* pcur = prebuilt->pcur;
1520
1449
btr_pcur_t* clust_pcur = prebuilt->clust_pcur;
1643
1572
trx = thr_get_trx(thr);
1645
/* Increment fk_cascade_depth to record the recursive call depth on
1646
a single update/delete that affects multiple tables chained
1647
together with foreign key relations. */
1648
thr->fk_cascade_depth++;
1650
if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
1651
return (DB_FOREIGN_EXCEED_MAX_CASCADE);
1654
1574
thr->run_node = node;
1655
1575
thr->prev_node = node;
1657
1577
row_upd_step(thr);
1659
/* The recursive call for cascading update/delete happens
1660
in above row_upd_step(), reset the counter once we come
1661
out of the recursive call, so it does not accumulate for
1662
different row deletes */
1663
thr->fk_cascade_depth = 0;
1665
1579
err = trx->error_state;
1667
1581
/* Note that the cascade node is a subnode of another InnoDB
1729
1643
/*********************************************************************//**
1644
Calculates the key number used inside MySQL for an Innobase index. We have
1645
to take into account if we generated a default clustered index for the table
1646
@return the key number used inside MySQL */
1649
row_get_mysql_key_number_for_index(
1650
/*===============================*/
1651
const dict_index_t* index) /*!< in: index */
1653
const dict_index_t* ind;
1659
ind = dict_table_get_first_index(index->table);
1661
while (index != ind) {
1662
ind = dict_table_get_next_index(ind);
1666
if (row_table_got_default_clust_index(index->table)) {
1674
/*********************************************************************//**
1730
1675
Locks the data dictionary in shared mode from modifications, for performing
1731
1676
foreign key check, rollback, or other operation invisible to MySQL. */
1845
1792
trx->op_info = "creating table";
1794
if (row_mysql_is_system_table(table->name)) {
1797
"InnoDB: Error: trying to create a MySQL system"
1798
" table %s of type InnoDB.\n"
1799
"InnoDB: MySQL system tables must be"
1800
" of the MyISAM type!\n",
1805
/* Check that no reserved column names are used. */
1806
for (i = 0; i < dict_table_get_n_user_cols(table); i++) {
1807
if (dict_col_name_is_reserved(
1808
dict_table_get_col_name(table, i))) {
1847
1814
trx_start_if_not_started(trx);
1849
1816
/* The table name is prefixed with the database name and a '/'.
1941
1906
case DB_DUPLICATE_KEY:
1907
ut_print_timestamp(stderr);
1908
fputs(" InnoDB: Error: table ", stderr);
1909
ut_print_name(stderr, trx, TRUE, table->name);
1910
fputs(" already exists in InnoDB internal\n"
1911
"InnoDB: data dictionary. Have you deleted"
1913
"InnoDB: and not used DROP TABLE?"
1914
" Have you used DROP DATABASE\n"
1915
"InnoDB: for InnoDB tables in"
1916
" MySQL version <= 3.23.43?\n"
1917
"InnoDB: See the Restrictions section"
1918
" of the InnoDB manual.\n"
1919
"InnoDB: You can drop the orphaned table"
1920
" inside InnoDB by\n"
1921
"InnoDB: creating an InnoDB table with"
1922
" the same name in another\n"
1923
"InnoDB: database and copying the .frm file"
1924
" to the current database.\n"
1925
"InnoDB: Then MySQL thinks the table exists,"
1926
" and DROP TABLE will\n"
1927
"InnoDB: succeed.\n"
1928
"InnoDB: You can look for further help from\n"
1929
"InnoDB: " REFMAN "innodb-troubleshooting.html\n",
1942
1932
/* We may also get err == DB_ERROR if the .ibd file for the
1943
1933
table already exists */
2121
2110
trx_set_dict_operation(trx, TRX_DICT_OP_TABLE);
2123
err = dict_create_foreign_constraints(trx, sql_string, sql_length,
2112
err = dict_create_foreign_constraints(trx, sql_string, name,
2125
2114
if (err == DB_SUCCESS) {
2126
2115
/* Check that also referencing constraints are ok */
2127
err = dict_load_foreigns(name, FALSE, TRUE);
2116
err = dict_load_foreigns(name, TRUE);
2130
2119
if (err != DB_SUCCESS) {
2818
2807
trx->table_id = table->id;
2820
/* Lock all index trees for this table, as we will
2821
truncate the table/index and possibly change their metadata.
2822
All DML/DDL are blocked by table level lock, with
2823
a few exceptions such as queries into information schema
2824
about the table, MySQL could try to access index stats
2825
for this kind of query, we need to use index locks to
2827
dict_table_x_lock_indexes(table);
2829
2809
if (table->space && !table->dir_path_of_temp_table) {
2830
2810
/* Discard and create the single-table tablespace. */
2831
2811
ulint space = table->space;
2837
2817
dict_index_t* index;
2839
dict_hdr_get_new_id(NULL, NULL, &space);
2841
if (space == ULINT_UNDEFINED
2842
|| fil_create_new_single_table_tablespace(
2843
space, table->name, FALSE, flags,
2821
if (fil_create_new_single_table_tablespace(
2822
&space, table->name, FALSE, flags,
2844
2823
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2845
dict_table_x_unlock_indexes(table);
2846
2824
ut_print_timestamp(stderr);
2847
2825
fprintf(stderr,
2848
2826
" InnoDB: TRUNCATE TABLE %s failed to"
2947
2925
mem_heap_free(heap);
2949
/* Done with index truncation, release index tree locks,
2950
subsequent work relates to table level metadata change */
2951
dict_table_x_unlock_indexes(table);
2953
dict_hdr_get_new_id(&new_id, NULL, NULL);
2927
new_id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
2955
2929
info = pars_info_create();
2957
2931
pars_info_add_int4_literal(info, "space", (lint) table->space);
2958
pars_info_add_ull_literal(info, "old_id", table->id);
2959
pars_info_add_ull_literal(info, "new_id", new_id);
2932
pars_info_add_dulint_literal(info, "old_id", table->id);
2933
pars_info_add_dulint_literal(info, "new_id", new_id);
2961
2935
err = que_eval_sql(info,
2962
2936
"PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n"
3332
3312
space_id = table->space;
3334
3314
if (table->dir_path_of_temp_table != NULL) {
3335
3316
name_or_path = mem_heap_strdup(
3336
3317
heap, table->dir_path_of_temp_table);
3339
3320
name_or_path = name;
3340
is_temp = (table->flags >> DICT_TF2_SHIFT)
3341
& DICT_TF2_TEMPORARY;
3344
3323
dict_table_remove_from_cache(table);
3346
if (dict_load_table(name, TRUE) != NULL) {
3325
if (dict_load_table(name) != NULL) {
3347
3326
ut_print_timestamp(stderr);
3348
3327
fputs(" InnoDB: Error: not able to remove table ",
3390
3369
mem_heap_free(heap);
3393
case DB_TOO_MANY_CONCURRENT_TRXS:
3394
/* Cannot even find a free slot for the
3395
the undo log. We can directly exit here
3396
and return the DB_TOO_MANY_CONCURRENT_TRXS
3400
case DB_OUT_OF_FILE_SPACE:
3401
err = DB_MUST_GET_MORE_FILE_SPACE;
3403
row_mysql_handle_errors(&err, trx, NULL, NULL);
3405
/* Fall through to raise error */
3408
/* No other possible error returns */
3414
3373
if (locked_dictionary) {
3424
3383
return((int) err);
3427
/*********************************************************************//**
3428
Drop all temporary tables during crash recovery. */
3431
row_mysql_drop_temp_tables(void)
3432
/*============================*/
3439
trx = trx_allocate_for_background();
3440
trx->op_info = "dropping temporary tables";
3441
row_mysql_lock_data_dictionary(trx);
3443
heap = mem_heap_create(200);
3447
btr_pcur_open_at_index_side(
3449
dict_table_get_first_index(dict_sys->sys_tables),
3450
BTR_SEARCH_LEAF, &pcur, TRUE, &mtr);
3456
const char* table_name;
3457
dict_table_t* table;
3459
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
3461
if (!btr_pcur_is_on_user_rec(&pcur)) {
3465
rec = btr_pcur_get_rec(&pcur);
3466
field = rec_get_nth_field_old(rec, 4/*N_COLS*/, &len);
3467
if (len != 4 || !(mach_read_from_4(field) & 0x80000000UL)) {
3471
/* Because this is not a ROW_FORMAT=REDUNDANT table,
3472
the is_temp flag is valid. Examine it. */
3474
field = rec_get_nth_field_old(rec, 7/*MIX_LEN*/, &len);
3476
|| !(mach_read_from_4(field) & DICT_TF2_TEMPORARY)) {
3480
/* This is a temporary table. */
3481
field = rec_get_nth_field_old(rec, 0/*NAME*/, &len);
3482
if (len == UNIV_SQL_NULL || len == 0) {
3483
/* Corrupted SYS_TABLES.NAME */
3487
table_name = mem_heap_strdupl(heap, (const char*) field, len);
3489
btr_pcur_store_position(&pcur, &mtr);
3490
btr_pcur_commit_specify_mtr(&pcur, &mtr);
3492
table = dict_load_table(table_name, TRUE);
3495
row_drop_table_for_mysql(table_name, trx, FALSE);
3496
trx_commit_for_mysql(trx);
3500
btr_pcur_restore_position(BTR_SEARCH_LEAF,
3504
btr_pcur_close(&pcur);
3506
mem_heap_free(heap);
3507
row_mysql_unlock_data_dictionary(trx);
3508
trx_free_for_background(trx);
3511
3386
/*******************************************************************//**
3512
3387
Drop all foreign keys in a database, see Bug#18942.
3513
3388
Called at the end of row_drop_database_for_mysql().
4057
3938
constraint is not broken, and calculates the number of index entries
4058
3939
in the read view of the current transaction.
4059
3940
@return TRUE if ok */
4062
row_check_index_for_mysql(
4063
/*======================*/
4064
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct
4066
const dict_index_t* index, /*!< in: index */
4067
ulint* n_rows) /*!< out: number of entries
4068
seen in the consistent read */
3943
row_scan_and_check_index(
3944
/*=====================*/
3945
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL */
3946
dict_index_t* index, /*!< in: index */
3947
ulint* n_rows) /*!< out: number of entries seen in the
3948
current consistent read */
4070
3950
dtuple_t* prev_entry = NULL;
4071
3951
ulint matched_fields;
3969
if (!row_merge_is_index_usable(prebuilt->trx, index)) {
3970
/* A newly created index may lack some delete-marked
3971
records that may exist in the read view of
3972
prebuilt->trx. Thus, such indexes must not be
3973
accessed by consistent read. */
4089
3977
buf = mem_alloc(UNIV_PAGE_SIZE);
4090
3978
heap = mem_heap_create(100);
3980
/* Make a dummy template in prebuilt, which we will use
3981
in scanning the index entries */
3983
prebuilt->index = index;
3984
/* row_merge_is_index_usable() was already checked above. */
3985
prebuilt->index_usable = TRUE;
3986
prebuilt->sql_stat_start = TRUE;
3987
prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
3988
prebuilt->n_template = 0;
3989
prebuilt->need_to_access_clustered = FALSE;
3991
dtuple_set_n_fields(prebuilt->search_tuple, 0);
3993
prebuilt->select_lock_type = LOCK_NONE;
4094
3996
ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, 0);
4209
4111
/*********************************************************************//**
4112
Checks a table for corruption.
4113
@return DB_ERROR or DB_SUCCESS */
4116
row_check_table_for_mysql(
4117
/*======================*/
4118
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
4121
dict_table_t* table = prebuilt->table;
4122
dict_index_t* index;
4124
ulint n_rows_in_table = ULINT_UNDEFINED;
4125
ulint ret = DB_SUCCESS;
4126
ulint old_isolation_level;
4128
if (table->ibd_file_missing) {
4129
ut_print_timestamp(stderr);
4130
fprintf(stderr, " InnoDB: Error:\n"
4131
"InnoDB: MySQL is trying to use a table handle"
4132
" but the .ibd file for\n"
4133
"InnoDB: table %s does not exist.\n"
4134
"InnoDB: Have you deleted the .ibd file"
4135
" from the database directory under\n"
4136
"InnoDB: the MySQL datadir, or have you"
4137
" used DISCARD TABLESPACE?\n"
4138
"InnoDB: Look from\n"
4139
"InnoDB: " REFMAN "innodb-troubleshooting.html\n"
4140
"InnoDB: how you can resolve the problem.\n",
4145
prebuilt->trx->op_info = "checking table";
4147
old_isolation_level = prebuilt->trx->isolation_level;
4149
/* We must run the index record counts at an isolation level
4150
>= READ COMMITTED, because a dirty read can see a wrong number
4151
of records in some index; to play safe, we use always
4152
REPEATABLE READ here */
4154
prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
4156
/* Enlarge the fatal lock wait timeout during CHECK TABLE. */
4157
mutex_enter(&kernel_mutex);
4158
srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
4159
mutex_exit(&kernel_mutex);
4161
index = dict_table_get_first_index(table);
4163
while (index != NULL) {
4164
/* fputs("Validating index ", stderr);
4165
ut_print_name(stderr, trx, FALSE, index->name);
4166
putc('\n', stderr); */
4168
if (!btr_validate_index(index, prebuilt->trx)) {
4171
if (!row_scan_and_check_index(prebuilt,index, &n_rows)){
4175
if (trx_is_interrupted(prebuilt->trx)) {
4179
/* fprintf(stderr, "%lu entries in index %s\n", n_rows,
4182
if (index == dict_table_get_first_index(table)) {
4183
n_rows_in_table = n_rows;
4184
} else if (n_rows != n_rows_in_table) {
4188
fputs("Error: ", stderr);
4189
dict_index_name_print(stderr,
4190
prebuilt->trx, index);
4192
" contains %lu entries,"
4195
(ulong) n_rows_in_table);
4199
index = dict_table_get_next_index(index);
4202
/* Restore the original isolation level */
4203
prebuilt->trx->isolation_level = old_isolation_level;
4205
/* We validate also the whole adaptive hash index for all tables
4206
at every CHECK TABLE */
4208
if (!btr_search_validate()) {
4213
/* Restore the fatal lock wait timeout after CHECK TABLE. */
4214
mutex_enter(&kernel_mutex);
4215
srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
4216
mutex_exit(&kernel_mutex);
4218
prebuilt->trx->op_info = "";
4223
/*********************************************************************//**
4210
4224
Determines if a table is a magic monitor table.
4211
4225
@return TRUE if monitor table */