1631
1630
/*********************************************************************//**
1631
Calculates the key number used inside MySQL for an Innobase index. We have
1632
to take into account if we generated a default clustered index for the table
1633
@return the key number used inside MySQL */
1636
row_get_mysql_key_number_for_index(
1637
/*===============================*/
1638
const dict_index_t* index) /*!< in: index */
1640
const dict_index_t* ind;
1646
ind = dict_table_get_first_index(index->table);
1648
while (index != ind) {
1649
ind = dict_table_get_next_index(ind);
1653
if (row_table_got_default_clust_index(index->table)) {
1661
/*********************************************************************//**
1632
1662
Locks the data dictionary in shared mode from modifications, for performing
1633
1663
foreign key check, rollback, or other operation invisible to MySQL. */
2730
2759
dict_index_t* index;
2732
dict_hdr_get_new_id(NULL, NULL, &space);
2734
if (space == ULINT_UNDEFINED
2735
|| fil_create_new_single_table_tablespace(
2736
space, table->name, FALSE, flags,
2763
if (fil_create_new_single_table_tablespace(
2764
&space, table->name, FALSE, flags,
2737
2765
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2738
2766
ut_print_timestamp(stderr);
2739
2767
fprintf(stderr,
3278
3312
mem_heap_free(heap);
3281
case DB_TOO_MANY_CONCURRENT_TRXS:
3282
/* Cannot even find a free slot for the
3283
the undo log. We can directly exit here
3284
and return the DB_TOO_MANY_CONCURRENT_TRXS
3288
case DB_OUT_OF_FILE_SPACE:
3289
err = DB_MUST_GET_MORE_FILE_SPACE;
3291
row_mysql_handle_errors(&err, trx, NULL, NULL);
3293
/* Fall through to raise error */
3296
/* No other possible error returns */
3302
3316
if (locked_dictionary) {
3312
3326
return((int) err);
3315
/*********************************************************************//**
3316
Drop all temporary tables during crash recovery. */
3319
row_mysql_drop_temp_tables(void)
3320
/*============================*/
3327
trx = trx_allocate_for_background();
3328
trx->op_info = "dropping temporary tables";
3329
row_mysql_lock_data_dictionary(trx);
3331
heap = mem_heap_create(200);
3335
btr_pcur_open_at_index_side(
3337
dict_table_get_first_index(dict_sys->sys_tables),
3338
BTR_SEARCH_LEAF, &pcur, TRUE, &mtr);
3344
const char* table_name;
3345
dict_table_t* table;
3347
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
3349
if (!btr_pcur_is_on_user_rec(&pcur)) {
3353
rec = btr_pcur_get_rec(&pcur);
3354
field = rec_get_nth_field_old(rec, 4/*N_COLS*/, &len);
3355
if (len != 4 || !(mach_read_from_4(field) & 0x80000000UL)) {
3359
/* Because this is not a ROW_FORMAT=REDUNDANT table,
3360
the is_temp flag is valid. Examine it. */
3362
field = rec_get_nth_field_old(rec, 7/*MIX_LEN*/, &len);
3364
|| !(mach_read_from_4(field) & DICT_TF2_TEMPORARY)) {
3368
/* This is a temporary table. */
3369
field = rec_get_nth_field_old(rec, 0/*NAME*/, &len);
3370
if (len == UNIV_SQL_NULL || len == 0) {
3371
/* Corrupted SYS_TABLES.NAME */
3375
table_name = mem_heap_strdupl(heap, (const char*) field, len);
3377
btr_pcur_store_position(&pcur, &mtr);
3378
btr_pcur_commit_specify_mtr(&pcur, &mtr);
3380
table = dict_load_table(table_name);
3383
row_drop_table_for_mysql(table_name, trx, FALSE);
3384
trx_commit_for_mysql(trx);
3388
btr_pcur_restore_position(BTR_SEARCH_LEAF,
3392
btr_pcur_close(&pcur);
3394
mem_heap_free(heap);
3395
row_mysql_unlock_data_dictionary(trx);
3396
trx_free_for_background(trx);
3399
3329
/*******************************************************************//**
3400
3330
Drop all foreign keys in a database, see Bug#18942.
3401
3331
Called at the end of row_drop_database_for_mysql().
3945
3875
constraint is not broken, and calculates the number of index entries
3946
3876
in the read view of the current transaction.
3947
3877
@return TRUE if ok */
3950
row_check_index_for_mysql(
3951
/*======================*/
3952
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct
3954
const dict_index_t* index, /*!< in: index */
3955
ulint* n_rows) /*!< out: number of entries
3956
seen in the consistent read */
3880
row_scan_and_check_index(
3881
/*=====================*/
3882
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL */
3883
dict_index_t* index, /*!< in: index */
3884
ulint* n_rows) /*!< out: number of entries seen in the
3885
current consistent read */
3958
3887
dtuple_t* prev_entry = NULL;
3959
3888
ulint matched_fields;
3906
if (!row_merge_is_index_usable(prebuilt->trx, index)) {
3907
/* A newly created index may lack some delete-marked
3908
records that may exist in the read view of
3909
prebuilt->trx. Thus, such indexes must not be
3910
accessed by consistent read. */
3977
3914
buf = mem_alloc(UNIV_PAGE_SIZE);
3978
3915
heap = mem_heap_create(100);
3917
/* Make a dummy template in prebuilt, which we will use
3918
in scanning the index entries */
3920
prebuilt->index = index;
3921
/* row_merge_is_index_usable() was already checked above. */
3922
prebuilt->index_usable = TRUE;
3923
prebuilt->sql_stat_start = TRUE;
3924
prebuilt->template_type = ROW_MYSQL_DUMMY_TEMPLATE;
3925
prebuilt->n_template = 0;
3926
prebuilt->need_to_access_clustered = FALSE;
3928
dtuple_set_n_fields(prebuilt->search_tuple, 0);
3930
prebuilt->select_lock_type = LOCK_NONE;
3982
3933
ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, 0);
4097
4048
/*********************************************************************//**
4049
Checks a table for corruption.
4050
@return DB_ERROR or DB_SUCCESS */
4053
row_check_table_for_mysql(
4054
/*======================*/
4055
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
4058
dict_table_t* table = prebuilt->table;
4059
dict_index_t* index;
4061
ulint n_rows_in_table = ULINT_UNDEFINED;
4062
ulint ret = DB_SUCCESS;
4063
ulint old_isolation_level;
4065
if (table->ibd_file_missing) {
4066
ut_print_timestamp(stderr);
4067
fprintf(stderr, " InnoDB: Error:\n"
4068
"InnoDB: MySQL is trying to use a table handle"
4069
" but the .ibd file for\n"
4070
"InnoDB: table %s does not exist.\n"
4071
"InnoDB: Have you deleted the .ibd file"
4072
" from the database directory under\n"
4073
"InnoDB: the MySQL datadir, or have you"
4074
" used DISCARD TABLESPACE?\n"
4075
"InnoDB: Look from\n"
4076
"InnoDB: " REFMAN "innodb-troubleshooting.html\n"
4077
"InnoDB: how you can resolve the problem.\n",
4082
prebuilt->trx->op_info = "checking table";
4084
old_isolation_level = prebuilt->trx->isolation_level;
4086
/* We must run the index record counts at an isolation level
4087
>= READ COMMITTED, because a dirty read can see a wrong number
4088
of records in some index; to play safe, we use always
4089
REPEATABLE READ here */
4091
prebuilt->trx->isolation_level = TRX_ISO_REPEATABLE_READ;
4093
/* Enlarge the fatal lock wait timeout during CHECK TABLE. */
4094
mutex_enter(&kernel_mutex);
4095
srv_fatal_semaphore_wait_threshold += 7200; /* 2 hours */
4096
mutex_exit(&kernel_mutex);
4098
index = dict_table_get_first_index(table);
4100
while (index != NULL) {
4101
/* fputs("Validating index ", stderr);
4102
ut_print_name(stderr, trx, FALSE, index->name);
4103
putc('\n', stderr); */
4105
if (!btr_validate_index(index, prebuilt->trx)) {
4108
if (!row_scan_and_check_index(prebuilt,index, &n_rows)){
4112
if (trx_is_interrupted(prebuilt->trx)) {
4113
ret = DB_INTERRUPTED;
4117
/* fprintf(stderr, "%lu entries in index %s\n", n_rows,
4120
if (index == dict_table_get_first_index(table)) {
4121
n_rows_in_table = n_rows;
4122
} else if (n_rows != n_rows_in_table) {
4126
fputs("Error: ", stderr);
4127
dict_index_name_print(stderr,
4128
prebuilt->trx, index);
4130
" contains %lu entries,"
4133
(ulong) n_rows_in_table);
4137
index = dict_table_get_next_index(index);
4140
/* Restore the original isolation level */
4141
prebuilt->trx->isolation_level = old_isolation_level;
4143
/* We validate also the whole adaptive hash index for all tables
4144
at every CHECK TABLE */
4146
if (!btr_search_validate()) {
4151
/* Restore the fatal lock wait timeout after CHECK TABLE. */
4152
mutex_enter(&kernel_mutex);
4153
srv_fatal_semaphore_wait_threshold -= 7200; /* 2 hours */
4154
mutex_exit(&kernel_mutex);
4156
prebuilt->trx->op_info = "";
4161
/*********************************************************************//**
4098
4162
Determines if a table is a magic monitor table.
4099
4163
@return TRUE if monitor table */