76
82
|| 0 == strcmp(name + 6, "user")
77
83
|| 0 == strcmp(name + 6, "db"));
85
#endif /* !UNIV_HOTBACKUP */
87
/*************************************************************************
88
If a table is not yet in the drop list, adds the table to the list of tables
89
which the master thread drops in background. We need this on Unix because in
90
ALTER TABLE MySQL may call drop table even if the table has running queries on
91
it. Also, if there are running foreign key checks on the table, we drop the
95
row_add_table_to_background_drop_list(
96
/*==================================*/
97
/* out: TRUE if the table was not yet in the
98
drop list, and was added there */
99
const char* name); /* in: table name */
80
101
/***********************************************************************
81
102
Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */
134
155
/***********************************************************************
135
156
Reads a >= 5.0.3 format true VARCHAR length, in the MySQL row format, and
136
157
returns a pointer to the data. */
139
160
row_mysql_read_true_varchar(
140
161
/*========================*/
141
/* out: pointer to the data, we skip the 1 or 2 bytes
142
at the start that are used to store the len */
143
ulint* len, /* out: variable-length field length */
144
byte* field, /* in: field in the MySQL format */
145
ulint lenlen) /* in: storage length of len: either 1 or 2 bytes */
162
/* out: pointer to the data, we skip
163
the 1 or 2 bytes at the start that are
164
used to store the len */
165
ulint* len, /* out: variable-length field length */
166
const byte* field, /* in: field in the MySQL format */
167
ulint lenlen) /* in: storage length of len: either 1
147
170
if (lenlen == 2) {
148
171
*len = mach_read_from_2_little_endian(field);
160
183
/***********************************************************************
161
184
Stores a reference to a BLOB in the MySQL format. */
164
187
row_mysql_store_blob_ref(
165
188
/*=====================*/
166
byte* dest, /* in: where to store */
167
ulint col_len, /* in: dest buffer size: determines into
189
byte* dest, /* in: where to store */
190
ulint col_len,/* in: dest buffer size: determines into
168
191
how many bytes the BLOB length is stored,
169
192
the space for the length may vary from 1
171
byte* data, /* in: BLOB data; if the value to store
194
const void* data, /* in: BLOB data; if the value to store
172
195
is SQL NULL this should be NULL pointer */
173
ulint len) /* in: BLOB length; if the value to store
196
ulint len) /* in: BLOB length; if the value to store
174
197
is SQL NULL this should be 0; remember
175
198
also to set the NULL bit in the MySQL record
192
215
mach_write_to_n_little_endian(dest, col_len - 8, len);
194
ut_memcpy(dest + col_len - 8, &data, sizeof(byte*));
217
memcpy(dest + col_len - 8, &data, sizeof data);
197
220
/***********************************************************************
198
221
Reads a reference to a BLOB in the MySQL format. */
201
224
row_mysql_read_blob_ref(
202
225
/*====================*/
203
/* out: pointer to BLOB data */
204
ulint* len, /* out: BLOB length */
205
byte* ref, /* in: BLOB reference in the MySQL format */
206
ulint col_len) /* in: BLOB reference length (not BLOB
226
/* out: pointer to BLOB data */
227
ulint* len, /* out: BLOB length */
228
const byte* ref, /* in: BLOB reference in the
230
ulint col_len) /* in: BLOB reference length
211
235
*len = mach_read_from_n_little_endian(ref, col_len - 8);
213
ut_memcpy(&data, ref + col_len - 8, sizeof(byte*));
237
memcpy(&data, ref + col_len - 8, sizeof data);
459
484
trx->error_state = DB_SUCCESS;
461
if ((err == DB_DUPLICATE_KEY)
462
|| (err == DB_FOREIGN_DUPLICATE_KEY)) {
464
/* Roll back the latest, possibly incomplete
465
insertion or update */
467
trx_general_rollback_for_mysql(trx, TRUE, savept);
469
} else if (err == DB_TOO_BIG_RECORD) {
471
/* Roll back the latest, possibly incomplete
472
insertion or update */
474
trx_general_rollback_for_mysql(trx, TRUE, savept);
476
/* MySQL will roll back the latest SQL statement */
477
} else if (err == DB_ROW_IS_REFERENCED
478
|| err == DB_NO_REFERENCED_ROW
479
|| err == DB_CANNOT_ADD_CONSTRAINT
480
|| err == DB_TOO_MANY_CONCURRENT_TRXS) {
482
/* Roll back the latest, possibly incomplete
483
insertion or update */
485
trx_general_rollback_for_mysql(trx, TRUE, savept);
487
/* MySQL will roll back the latest SQL statement */
488
} else if (err == DB_LOCK_WAIT) {
487
case DB_LOCK_WAIT_TIMEOUT:
488
if (row_rollback_on_timeout) {
489
trx_general_rollback_for_mysql(trx, FALSE, NULL);
493
case DB_DUPLICATE_KEY:
494
case DB_FOREIGN_DUPLICATE_KEY:
495
case DB_TOO_BIG_RECORD:
496
case DB_ROW_IS_REFERENCED:
497
case DB_NO_REFERENCED_ROW:
498
case DB_CANNOT_ADD_CONSTRAINT:
499
case DB_TOO_MANY_CONCURRENT_TRXS:
500
case DB_OUT_OF_FILE_SPACE:
502
/* Roll back the latest, possibly incomplete
503
insertion or update */
505
trx_general_rollback_for_mysql(trx, TRUE, savept);
507
/* MySQL will roll back the latest SQL statement */
490
510
srv_suspend_mysql_thread(thr);
492
512
if (trx->error_state != DB_SUCCESS) {
502
} else if (err == DB_DEADLOCK
503
|| err == DB_LOCK_TABLE_FULL
504
|| (err == DB_LOCK_WAIT_TIMEOUT
505
&& row_rollback_on_timeout)) {
523
case DB_LOCK_TABLE_FULL:
506
524
/* Roll back the whole transaction; this resolution was added
507
525
to version 3.23.43 */
509
527
trx_general_rollback_for_mysql(trx, FALSE, NULL);
511
} else if (err == DB_OUT_OF_FILE_SPACE
512
|| err == DB_LOCK_WAIT_TIMEOUT) {
514
ut_ad(!(err == DB_LOCK_WAIT_TIMEOUT
515
&& row_rollback_on_timeout));
518
/* Roll back the latest, possibly incomplete
519
insertion or update */
521
trx_general_rollback_for_mysql(trx, TRUE, savept);
523
/* MySQL will roll back the latest SQL statement */
525
} else if (err == DB_MUST_GET_MORE_FILE_SPACE) {
530
case DB_MUST_GET_MORE_FILE_SPACE:
527
531
fputs("InnoDB: The database cannot continue"
528
532
" operation because of\n"
529
533
"InnoDB: lack of space. You must add"
586
590
dict_index_t* clust_index;
591
heap = mem_heap_create(128);
593
prebuilt = mem_heap_alloc(heap, sizeof(row_prebuilt_t));
594
heap = mem_heap_create(sizeof *prebuilt + 128);
596
prebuilt = mem_heap_zalloc(heap, sizeof *prebuilt);
595
598
prebuilt->magic_n = ROW_PREBUILT_ALLOCATED;
596
599
prebuilt->magic_n2 = ROW_PREBUILT_ALLOCATED;
598
601
prebuilt->table = table;
600
prebuilt->trx = NULL;
602
603
prebuilt->sql_stat_start = TRUE;
604
prebuilt->mysql_has_locked = FALSE;
606
prebuilt->index = NULL;
608
prebuilt->used_in_HANDLER = FALSE;
610
prebuilt->n_template = 0;
611
prebuilt->mysql_template = NULL;
613
604
prebuilt->heap = heap;
614
prebuilt->ins_node = NULL;
616
prebuilt->ins_upd_rec_buff = NULL;
618
prebuilt->upd_node = NULL;
619
prebuilt->ins_graph = NULL;
620
prebuilt->upd_graph = NULL;
622
606
prebuilt->pcur = btr_pcur_create_for_mysql();
623
607
prebuilt->clust_pcur = btr_pcur_create_for_mysql();
646
626
prebuilt->clust_ref = ref;
648
for (i = 0; i < DRIZZLE_FETCH_CACHE_SIZE; i++) {
649
prebuilt->fetch_cache[i] = NULL;
652
prebuilt->n_fetch_cached = 0;
654
prebuilt->blob_heap = NULL;
656
prebuilt->old_vers_heap = NULL;
658
prebuilt->last_value = 0;
660
628
return(prebuilt);
663
631
/************************************************************************
664
632
Free a prebuilt struct for a MySQL table handle. */
667
635
row_prebuilt_free(
668
636
/*==============*/
669
row_prebuilt_t* prebuilt) /* in, own: prebuilt struct */
637
row_prebuilt_t* prebuilt, /* in, own: prebuilt struct */
638
ibool dict_locked) /* in: TRUE=data dictionary locked */
673
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED
674
|| prebuilt->magic_n2 != ROW_PREBUILT_ALLOCATED) {
643
(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED
644
|| prebuilt->magic_n2 != ROW_PREBUILT_ALLOCATED)) {
676
647
"InnoDB: Error: trying to free a corrupt\n"
677
648
"InnoDB: table handle. Magic n %lu,"
678
" magic n2 %lu, table name",
649
" magic n2 %lu, table name ",
679
650
(ulong) prebuilt->magic_n,
680
651
(ulong) prebuilt->magic_n2);
681
652
ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
768
739
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
770
741
"InnoDB: Error: trying to use a corrupt\n"
771
"InnoDB: table handle. Magic n %lu, table name",
742
"InnoDB: table handle. Magic n %lu, table name ",
772
743
(ulong) prebuilt->magic_n);
773
ut_print_name(stderr, NULL, TRUE, prebuilt->table->name);
744
ut_print_name(stderr, trx, TRUE, prebuilt->table->name);
774
745
putc('\n', stderr);
776
747
mem_analyze_corruption(prebuilt);
1088
1050
return(DB_ERROR);
1091
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
1053
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
1092
1054
fprintf(stderr,
1093
1055
"InnoDB: Error: trying to free a corrupt\n"
1094
"InnoDB: table handle. Magic n %lu, table name",
1056
"InnoDB: table handle. Magic n %lu, table name ",
1095
1057
(ulong) prebuilt->magic_n);
1096
ut_print_name(stderr, prebuilt->trx, TRUE,
1097
prebuilt->table->name);
1058
ut_print_name(stderr, trx, TRUE, prebuilt->table->name);
1098
1059
putc('\n', stderr);
1100
1061
mem_analyze_corruption(prebuilt);
1326
1287
return(DB_ERROR);
1329
if (prebuilt->magic_n != ROW_PREBUILT_ALLOCATED) {
1290
if (UNIV_UNLIKELY(prebuilt->magic_n != ROW_PREBUILT_ALLOCATED)) {
1330
1291
fprintf(stderr,
1331
1292
"InnoDB: Error: trying to free a corrupt\n"
1332
"InnoDB: table handle. Magic n %lu, table name",
1293
"InnoDB: table handle. Magic n %lu, table name ",
1333
1294
(ulong) prebuilt->magic_n);
1334
ut_print_name(stderr, prebuilt->trx, TRUE,
1335
prebuilt->table->name);
1295
ut_print_name(stderr, trx, TRUE, prebuilt->table->name);
1336
1296
putc('\n', stderr);
1338
1298
mem_analyze_corruption(prebuilt);
1727
1689
trx->dict_operation_lock_mode = 0;
1692
#ifndef UNIV_HOTBACKUP
1730
1693
/*************************************************************************
1731
Drops a table for MySQL. If the name of the table ends in
1694
Creates a table for MySQL. If the name of the table ends in
1732
1695
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
1733
1696
"innodb_table_monitor", then this will also start the printing of monitor
1734
1697
output by the master thread. If the table name ends in "innodb_mem_validate",
1735
1698
InnoDB will try to invoke mem_validate(). */
1738
1701
row_create_table_for_mysql(
1739
1702
/*=======================*/
1822
1776
of InnoDB monitor prints */
1824
1778
os_event_set(srv_lock_timeout_thread_event);
1825
} else if (table_name_len == sizeof S_innodb_lock_monitor
1826
&& !memcmp(table_name, S_innodb_lock_monitor,
1827
sizeof S_innodb_lock_monitor)) {
1779
} else if (STR_EQ(table_name, table_name_len,
1780
S_innodb_lock_monitor)) {
1829
1782
srv_print_innodb_monitor = TRUE;
1830
1783
srv_print_innodb_lock_monitor = TRUE;
1831
1784
os_event_set(srv_lock_timeout_thread_event);
1832
} else if (table_name_len == sizeof S_innodb_tablespace_monitor
1833
&& !memcmp(table_name, S_innodb_tablespace_monitor,
1834
sizeof S_innodb_tablespace_monitor)) {
1785
} else if (STR_EQ(table_name, table_name_len,
1786
S_innodb_tablespace_monitor)) {
1836
1788
srv_print_innodb_tablespace_monitor = TRUE;
1837
1789
os_event_set(srv_lock_timeout_thread_event);
1838
} else if (table_name_len == sizeof S_innodb_table_monitor
1839
&& !memcmp(table_name, S_innodb_table_monitor,
1840
sizeof S_innodb_table_monitor)) {
1790
} else if (STR_EQ(table_name, table_name_len,
1791
S_innodb_table_monitor)) {
1842
1793
srv_print_innodb_table_monitor = TRUE;
1843
1794
os_event_set(srv_lock_timeout_thread_event);
1844
} else if (table_name_len == sizeof S_innodb_mem_validate
1845
&& !memcmp(table_name, S_innodb_mem_validate,
1846
sizeof S_innodb_mem_validate)) {
1795
} else if (STR_EQ(table_name, table_name_len,
1796
S_innodb_mem_validate)) {
1847
1797
/* We define here a debugging feature intended for
1877
1827
err = trx->error_state;
1879
if (err != DB_SUCCESS) {
1880
/* We have special error handling here */
1829
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
1882
1830
trx->error_state = DB_SUCCESS;
1884
1831
trx_general_rollback_for_mysql(trx, FALSE, NULL);
1886
if (err == DB_OUT_OF_FILE_SPACE) {
1887
ut_print_timestamp(stderr);
1889
fputs(" InnoDB: Warning: cannot create table ",
1891
ut_print_name(stderr, trx, TRUE, table->name);
1892
fputs(" because tablespace full\n", stderr);
1894
if (dict_table_get_low(table->name)) {
1896
row_drop_table_for_mysql(table->name, trx,
1900
} else if (err == DB_DUPLICATE_KEY) {
1901
ut_print_timestamp(stderr);
1903
fputs(" InnoDB: Error: table ", stderr);
1904
ut_print_name(stderr, trx, TRUE, table->name);
1905
fputs(" already exists in InnoDB internal\n"
1906
"InnoDB: data dictionary. Have you deleted"
1908
"InnoDB: and not used DROP TABLE?"
1909
" Have you used DROP DATABASE\n"
1910
"InnoDB: for InnoDB tables in"
1911
" MySQL version <= 3.23.43?\n"
1912
"InnoDB: See the Restrictions section"
1913
" of the InnoDB manual.\n"
1914
"InnoDB: You can drop the orphaned table"
1915
" inside InnoDB by\n"
1916
"InnoDB: creating an InnoDB table with"
1917
" the same name in another\n"
1918
"InnoDB: database and copying the .frm file"
1919
" to the current database.\n"
1920
"InnoDB: Then MySQL thinks the table exists,"
1921
" and DROP TABLE will\n"
1922
"InnoDB: succeed.\n"
1923
"InnoDB: You can look for further help from\n"
1924
"InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
1925
"innodb-troubleshooting.html\n",
1835
case DB_OUT_OF_FILE_SPACE:
1836
ut_print_timestamp(stderr);
1837
fputs(" InnoDB: Warning: cannot create table ",
1839
ut_print_name(stderr, trx, TRUE, table->name);
1840
fputs(" because tablespace full\n", stderr);
1842
if (dict_table_get_low(table->name)) {
1844
row_drop_table_for_mysql(table->name, trx, FALSE);
1848
case DB_DUPLICATE_KEY:
1849
ut_print_timestamp(stderr);
1850
fputs(" InnoDB: Error: table ", stderr);
1851
ut_print_name(stderr, trx, TRUE, table->name);
1852
fputs(" already exists in InnoDB internal\n"
1853
"InnoDB: data dictionary. Have you deleted"
1855
"InnoDB: and not used DROP TABLE?"
1856
" Have you used DROP DATABASE\n"
1857
"InnoDB: for InnoDB tables in"
1858
" MySQL version <= 3.23.43?\n"
1859
"InnoDB: See the Restrictions section"
1860
" of the InnoDB manual.\n"
1861
"InnoDB: You can drop the orphaned table"
1862
" inside InnoDB by\n"
1863
"InnoDB: creating an InnoDB table with"
1864
" the same name in another\n"
1865
"InnoDB: database and copying the .frm file"
1866
" to the current database.\n"
1867
"InnoDB: Then MySQL thinks the table exists,"
1868
" and DROP TABLE will\n"
1869
"InnoDB: succeed.\n"
1870
"InnoDB: You can look for further help from\n"
1872
"http://dev.mysql.com/doc/refman/5.1/en/"
1873
"innodb-troubleshooting.html\n", stderr);
1929
1875
/* We may also get err == DB_ERROR if the .ibd file for the
1930
1876
table already exists */
1932
trx->error_state = DB_SUCCESS;
1935
1881
que_graph_free((que_t*) que_node_get_parent(thr));
2431
2385
ut_print_timestamp(ef);
2433
2387
fputs(" Cannot DISCARD table ", ef);
2434
ut_print_name(ef, trx, TRUE, name);
2388
ut_print_name(stderr, trx, TRUE, name);
2436
2390
"because it is referenced by ", ef);
2437
ut_print_name(ef, trx, TRUE, foreign->foreign_table_name);
2391
ut_print_name(stderr, trx, TRUE, foreign->foreign_table_name);
2438
2392
putc('\n', ef);
2439
2393
mutex_exit(&dict_foreign_err_mutex);
2686
2643
reallocated, the allocator will remove the ibuf entries for
2689
TODO: when we truncate *.ibd files (analogous to DISCARD
2690
TABLESPACE), we will have to remove we remove all entries for
2691
the table in the insert buffer tree!
2646
When we truncate *.ibd files by recreating them (analogous to
2647
DISCARD TABLESPACE), we remove all entries for the table in the
2648
insert buffer tree. This is not strictly necessary, because
2649
in 6) we will assign a new tablespace identifier, but we can
2650
free up some space in the system tablespace.
2693
2652
4) Linear readahead and random readahead: we use the same
2694
method as in 3) to discard ongoing operations. (This will only
2695
be relevant for TRUNCATE TABLE by DISCARD TABLESPACE.)
2653
method as in 3) to discard ongoing operations. (This is only
2654
relevant for TRUNCATE TABLE by DISCARD TABLESPACE.)
2697
2656
5) FOREIGN KEY operations: if
2698
2657
table->n_foreign_key_checks_running > 0, we do not allow the
2699
TRUNCATE. We also reserve the data dictionary latch. */
2658
TRUNCATE. We also reserve the data dictionary latch.
2660
6) Crash recovery: To prevent the application of pre-truncation
2661
redo log records on the truncated tablespace, we will assign
2662
a new tablespace identifier to the truncated tablespace. */
2701
2664
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
2786
2749
trx->table_id = table->id;
2751
if (table->space && !table->dir_path_of_temp_table) {
2752
/* Discard and create the single-table tablespace. */
2753
ulint space = table->space;
2754
ulint flags = fil_space_get_flags(space);
2756
if (flags != ULINT_UNDEFINED
2757
&& fil_discard_tablespace(space)) {
2759
dict_index_t* index;
2763
if (fil_create_new_single_table_tablespace(
2764
&space, table->name, FALSE, flags,
2765
FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2766
ut_print_timestamp(stderr);
2768
" InnoDB: TRUNCATE TABLE %s failed to"
2769
" create a new tablespace\n",
2771
table->ibd_file_missing = 1;
2776
recreate_space = space;
2778
/* Replace the space_id in the data dictionary cache.
2779
The persisent data dictionary (SYS_TABLES.SPACE
2780
and SYS_INDEXES.SPACE) are updated later in this
2782
table->space = space;
2783
index = dict_table_get_first_index(table);
2785
index->space = space;
2786
index = dict_table_get_next_index(index);
2790
fsp_header_init(space,
2791
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
2788
2796
/* scan SYS_INDEXES for all indexes of the table */
2789
2797
heap = mem_heap_create(800);
2862
2871
info = pars_info_create();
2873
pars_info_add_int4_literal(info, "space", (lint) table->space);
2864
2874
pars_info_add_dulint_literal(info, "old_id", table->id);
2865
2875
pars_info_add_dulint_literal(info, "new_id", new_id);
2867
2877
err = que_eval_sql(info,
2868
2878
"PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n"
2870
"UPDATE SYS_TABLES SET ID = :new_id\n"
2881
" SET ID = :new_id, SPACE = :space\n"
2871
2882
" WHERE ID = :old_id;\n"
2872
2883
"UPDATE SYS_COLUMNS SET TABLE_ID = :new_id\n"
2873
2884
" WHERE TABLE_ID = :old_id;\n"
2874
"UPDATE SYS_INDEXES SET TABLE_ID = :new_id\n"
2885
"UPDATE SYS_INDEXES"
2886
" SET TABLE_ID = :new_id, SPACE = :space\n"
2875
2887
" WHERE TABLE_ID = :old_id;\n"
2876
2888
"COMMIT WORK;\n"
2928
2939
trx_t* trx, /* in: transaction handle */
2929
2940
ibool drop_db)/* in: TRUE=dropping whole database */
2944
err = row_drop_table_for_mysql_no_commit(name, trx, drop_db);
2945
trx_commit_for_mysql(trx);
2950
/*************************************************************************
2951
Drops a table for MySQL but does not commit the transaction. If the
2952
name of the dropped table ends in one of "innodb_monitor",
2953
"innodb_lock_monitor", "innodb_tablespace_monitor",
2954
"innodb_table_monitor", then this will also stop the printing of
2955
monitor output by the master thread. */
2958
row_drop_table_for_mysql_no_commit(
2959
/*===============================*/
2960
/* out: error code or DB_SUCCESS */
2961
const char* name, /* in: table name */
2962
trx_t* trx, /* in: transaction handle */
2963
ibool drop_db)/* in: TRUE=dropping whole database */
2931
2965
dict_foreign_t* foreign;
2932
2966
dict_table_t* table;
2933
2967
ulint space_id;
3104
3137
if (table->n_foreign_key_checks_running > 0) {
3139
const char* table_name = table->name;
3108
added = row_add_table_to_background_drop_list(table);
3142
added = row_add_table_to_background_drop_list(table_name);
3111
3145
ut_print_timestamp(stderr);
3112
3146
fputs(" InnoDB: You are trying to drop table ",
3114
ut_print_name(stderr, trx, TRUE, table->name);
3148
ut_print_name(stderr, trx, TRUE, table_name);
3116
3150
"InnoDB: though there is a"
3117
3151
" foreign key check running on it.\n"
3312
3342
return((int) err);
3345
/***********************************************************************
3346
Drop all foreign keys in a database, see Bug#18942.
3347
Called at the end of row_drop_database_for_mysql(). */
3350
drop_all_foreign_keys_in_db(
3351
/*========================*/
3352
/* out: error code or DB_SUCCESS */
3353
const char* name, /* in: database name which ends to '/' */
3354
trx_t* trx) /* in: transaction handle */
3359
ut_a(name[strlen(name) - 1] == '/');
3361
pinfo = pars_info_create();
3363
pars_info_add_str_literal(pinfo, "dbname", name);
3365
/* true if for_name is not prefixed with dbname */
3366
#define TABLE_NOT_IN_THIS_DB \
3367
"SUBSTR(for_name, 0, LENGTH(:dbname)) <> :dbname"
3369
err = que_eval_sql(pinfo,
3370
"PROCEDURE DROP_ALL_FOREIGN_KEYS_PROC () IS\n"
3371
"foreign_id CHAR;\n"
3374
"DECLARE CURSOR cur IS\n"
3375
"SELECT ID, FOR_NAME FROM SYS_FOREIGN\n"
3376
"WHERE FOR_NAME >= :dbname\n"
3377
"LOCK IN SHARE MODE\n"
3378
"ORDER BY FOR_NAME;\n"
3382
"WHILE found = 1 LOOP\n"
3383
" FETCH cur INTO foreign_id, for_name;\n"
3384
" IF (SQL % NOTFOUND) THEN\n"
3386
" ELSIF (" TABLE_NOT_IN_THIS_DB ") THEN\n"
3388
" ELSIF (1=1) THEN\n"
3389
" DELETE FROM SYS_FOREIGN_COLS\n"
3390
" WHERE ID = foreign_id;\n"
3391
" DELETE FROM SYS_FOREIGN\n"
3392
" WHERE ID = foreign_id;\n"
3398
FALSE, /* do not reserve dict mutex,
3399
we are already holding it */
3315
3405
/*************************************************************************
3316
3406
Drops a database for MySQL. */
3319
3409
row_drop_database_for_mysql(
3320
3410
/*========================*/
3475
if (err == DB_SUCCESS) {
3476
/* after dropping all tables try to drop all leftover
3477
foreign keys in case orphaned ones exist */
3478
err = (int) drop_all_foreign_keys_in_db(name, trx);
3480
if (err != DB_SUCCESS) {
3481
fputs("InnoDB: DROP DATABASE ", stderr);
3482
ut_print_name(stderr, trx, TRUE, name);
3483
fprintf(stderr, " failed with error %d while "
3484
"dropping all foreign keys", err);
3385
3488
trx_commit_for_mysql(trx);
3387
3490
row_mysql_unlock_data_dictionary(trx);
3465
3568
/*************************************************************************
3466
3569
Renames a table for MySQL. */
3469
3572
row_rename_table_for_mysql(
3470
3573
/*=======================*/
3471
3574
/* out: error code or DB_SUCCESS */
3472
3575
const char* old_name, /* in: old table name */
3473
3576
const char* new_name, /* in: new table name */
3474
trx_t* trx) /* in: transaction handle */
3577
trx_t* trx, /* in: transaction handle */
3578
ibool commit) /* in: if TRUE then commit trx */
3476
3580
dict_table_t* table;
3581
ulint err = DB_ERROR;
3478
3582
mem_heap_t* heap = NULL;
3479
3583
const char** constraints_to_drop = NULL;
3480
3584
ulint n_constraints_to_drop = 0;
3739
3826
/* The following call will also rename the .ibd data file if
3740
3827
the table is stored in a single-table tablespace */
3742
ibool success = dict_table_rename_in_cache(table, new_name,
3829
if (!dict_table_rename_in_cache(table, new_name,
3746
3831
trx->error_state = DB_SUCCESS;
3747
3832
trx_general_rollback_for_mysql(trx, FALSE, NULL);
3748
3833
trx->error_state = DB_SUCCESS;
3749
ut_print_timestamp(stderr);
3750
fputs(" InnoDB: Error in table rename,"
3751
" cannot rename ", stderr);
3752
ut_print_name(stderr, trx, TRUE, old_name);
3753
fputs(" to ", stderr);
3754
ut_print_name(stderr, trx, TRUE, new_name);
3758
3834
goto funct_exit;
3937
mem_heap_empty(heap);
3940
prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, index, rec, heap);
4018
mem_heap_t* tmp_heap = NULL;
4020
/* Empty the heap on each round. But preserve offsets[]
4021
for the row_rec_to_index_entry() call, by copying them
4022
into a separate memory heap when needed. */
4023
if (UNIV_UNLIKELY(offsets != offsets_)) {
4024
ulint size = rec_offs_get_n_alloc(offsets)
4027
tmp_heap = mem_heap_create(size);
4028
offsets = mem_heap_dup(tmp_heap, offsets, size);
4031
mem_heap_empty(heap);
4033
prev_entry = row_rec_to_index_entry(ROW_COPY_DATA, rec,
4037
if (UNIV_LIKELY_NULL(tmp_heap)) {
4038
mem_heap_free(tmp_heap);
3942
4042
ret = row_search_for_mysql(buf, PAGE_CUR_G, prebuilt, 0, ROW_SEL_NEXT);
4159
#endif /* !UNIV_HOTBACKUP */
4161
/*************************************************************************
4162
Determines if a table is a magic monitor table. */
4165
row_is_magic_monitor_table(
4166
/*=======================*/
4167
/* out: TRUE if monitor table */
4168
const char* table_name) /* in: name of the table, in the
4169
form database/table_name */
4171
const char* name; /* table_name without database/ */
4174
name = strchr(table_name, '/');
4177
len = strlen(name) + 1;
4179
if (STR_EQ(name, len, S_innodb_monitor)
4180
|| STR_EQ(name, len, S_innodb_lock_monitor)
4181
|| STR_EQ(name, len, S_innodb_tablespace_monitor)
4182
|| STR_EQ(name, len, S_innodb_table_monitor)
4183
|| STR_EQ(name, len, S_innodb_mem_validate)) {