50
52
#include "fil0fil.h"
51
53
#include "ibuf0ibuf.h"
53
/* Provide optional 4.x backwards compatibility for 5.0 and above */
57
/** Provide optional 4.x backwards compatibility for 5.0 and above */
54
58
UNIV_INTERN ibool row_rollback_on_timeout = FALSE;
56
/* List of tables we should drop in background. ALTER TABLE in MySQL requires
57
that the table handler can drop the table in background when there are no
58
queries to it any more. Protected by the kernel mutex. */
60
/** Chain node of the list of tables to drop in the background. */
59
61
typedef struct row_mysql_drop_struct row_mysql_drop_t;
63
/** Chain node of the list of tables to drop in the background. */
60
64
struct row_mysql_drop_struct{
62
UT_LIST_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
65
char* table_name; /*!< table name */
66
UT_LIST_NODE_T(row_mysql_drop_t)row_mysql_drop_list;
67
/*!< list chain node */
70
/** @brief List of tables we should drop in background.
72
ALTER TABLE in MySQL requires that the table handler can drop the
73
table in background when there are no queries to it any
74
more. Protected by kernel_mutex. */
65
75
static UT_LIST_BASE_NODE_T(row_mysql_drop_t) row_mysql_drop_list;
76
/** Flag: has row_mysql_drop_list been initialized? */
66
77
static ibool row_mysql_drop_list_inited = FALSE;
68
/* Magic table names for invoking various monitor threads */
79
/** Magic table names for invoking various monitor threads */
69
81
static const char S_innodb_monitor[] = "innodb_monitor";
70
82
static const char S_innodb_lock_monitor[] = "innodb_lock_monitor";
71
83
static const char S_innodb_tablespace_monitor[] = "innodb_tablespace_monitor";
72
84
static const char S_innodb_table_monitor[] = "innodb_table_monitor";
73
85
static const char S_innodb_mem_validate[] = "innodb_mem_validate";
75
/* Evaluates to true if str1 equals str2_onstack, used for comparing
88
/** Evaluates to true if str1 equals str2_onstack, used for comparing
89
the magic table names.
90
@param str1 in: string to compare
91
@param str1_len in: length of str1, in bytes, including terminating NUL
92
@param str2_onstack in: char[] array containing a NUL terminated string
93
@return TRUE if str1 equals str2_onstack */
77
94
#define STR_EQ(str1, str1_len, str2_onstack) \
78
95
((str1_len) == sizeof(str2_onstack) \
79
96
&& memcmp(str1, str2_onstack, sizeof(str2_onstack)) == 0)
81
#ifndef UNIV_HOTBACKUP
82
/***********************************************************************
83
Determine if the given name is a name reserved for MySQL system tables. */
98
/*******************************************************************//**
99
Determine if the given name is a name reserved for MySQL system tables.
100
@return TRUE if name is a MySQL system table name */
86
103
row_mysql_is_system_table(
87
104
/*======================*/
88
/* out: TRUE if name is a MySQL
92
107
if (strncmp(name, "mysql/", 6) != 0) {
98
113
|| 0 == strcmp(name + 6, "user")
99
114
|| 0 == strcmp(name + 6, "db"));
101
#endif /* !UNIV_HOTBACKUP */
103
/*************************************************************************
117
/*********************************************************************//**
104
118
If a table is not yet in the drop list, adds the table to the list of tables
105
119
which the master thread drops in background. We need this on Unix because in
106
120
ALTER TABLE MySQL may call drop table even if the table has running queries on
107
121
it. Also, if there are running foreign key checks on the table, we drop the
123
@return TRUE if the table was not yet in the drop list, and was added there */
111
126
row_add_table_to_background_drop_list(
112
127
/*==================================*/
113
/* out: TRUE if the table was not yet in the
114
drop list, and was added there */
115
const char* name); /* in: table name */
128
const char* name); /*!< in: table name */
117
/***********************************************************************
130
/*******************************************************************//**
118
131
Delays an INSERT, DELETE or UPDATE operation if the purge is lagging. */
129
/***********************************************************************
142
/*******************************************************************//**
130
143
Frees the blob heap in prebuilt when no longer needed. */
133
146
row_mysql_prebuilt_free_blob_heap(
134
147
/*==============================*/
135
row_prebuilt_t* prebuilt) /* in: prebuilt struct of a
148
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct of a
136
149
ha_innobase:: table handle */
138
151
mem_heap_free(prebuilt->blob_heap);
139
152
prebuilt->blob_heap = NULL;
142
/***********************************************************************
155
/*******************************************************************//**
143
156
Stores a >= 5.0.3 format true VARCHAR length to dest, in the MySQL row
158
@return pointer to the data, we skip the 1 or 2 bytes at the start
159
that are used to store the len */
147
162
row_mysql_store_true_var_len(
148
163
/*=========================*/
149
/* out: pointer to the data, we skip the 1 or 2 bytes
150
at the start that are used to store the len */
151
byte* dest, /* in: where to store */
152
ulint len, /* in: length, must fit in two bytes */
153
ulint lenlen) /* in: storage length of len: either 1 or 2 bytes */
164
byte* dest, /*!< in: where to store */
165
ulint len, /*!< in: length, must fit in two bytes */
166
ulint lenlen) /*!< in: storage length of len: either 1 or 2 bytes */
155
168
if (lenlen == 2) {
156
169
ut_a(len < 256 * 256);
168
181
return(dest + 1);
171
/***********************************************************************
184
/*******************************************************************//**
172
185
Reads a >= 5.0.3 format true VARCHAR length, in the MySQL row format, and
173
returns a pointer to the data. */
186
returns a pointer to the data.
187
@return pointer to the data, we skip the 1 or 2 bytes at the start
188
that are used to store the len */
176
191
row_mysql_read_true_varchar(
177
192
/*========================*/
178
/* out: pointer to the data, we skip
179
the 1 or 2 bytes at the start that are
180
used to store the len */
181
ulint* len, /* out: variable-length field length */
182
const byte* field, /* in: field in the MySQL format */
183
ulint lenlen) /* in: storage length of len: either 1
193
ulint* len, /*!< out: variable-length field length */
194
const byte* field, /*!< in: field in the MySQL format */
195
ulint lenlen) /*!< in: storage length of len: either 1
186
198
if (lenlen == 2) {
196
208
return(field + 1);
199
/***********************************************************************
211
/*******************************************************************//**
200
212
Stores a reference to a BLOB in the MySQL format. */
203
215
row_mysql_store_blob_ref(
204
216
/*=====================*/
205
byte* dest, /* in: where to store */
206
ulint col_len,/* in: dest buffer size: determines into
217
byte* dest, /*!< in: where to store */
218
ulint col_len,/*!< in: dest buffer size: determines into
207
219
how many bytes the BLOB length is stored,
208
220
the space for the length may vary from 1
210
const void* data, /* in: BLOB data; if the value to store
222
const void* data, /*!< in: BLOB data; if the value to store
211
223
is SQL NULL this should be NULL pointer */
212
ulint len) /* in: BLOB length; if the value to store
224
ulint len) /*!< in: BLOB length; if the value to store
213
225
is SQL NULL this should be 0; remember
214
226
also to set the NULL bit in the MySQL record
233
245
memcpy(dest + col_len - 8, &data, sizeof data);
236
/***********************************************************************
237
Reads a reference to a BLOB in the MySQL format. */
248
/*******************************************************************//**
249
Reads a reference to a BLOB in the MySQL format.
250
@return pointer to BLOB data */
240
253
row_mysql_read_blob_ref(
241
254
/*====================*/
242
/* out: pointer to BLOB data */
243
ulint* len, /* out: BLOB length */
244
const byte* ref, /* in: BLOB reference in the
255
ulint* len, /*!< out: BLOB length */
256
const byte* ref, /*!< in: BLOB reference in the
246
ulint col_len) /* in: BLOB reference length
258
ulint col_len) /*!< in: BLOB reference length
247
259
(not BLOB length) */
258
/******************************************************************
270
/**************************************************************//**
259
271
Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
260
272
The counterpart of this function is row_sel_field_store_in_mysql_format() in
274
@return up to which byte we used buf in the conversion */
264
277
row_mysql_store_col_in_innobase_format(
265
278
/*===================================*/
266
/* out: up to which byte we used
267
buf in the conversion */
268
dfield_t* dfield, /* in/out: dfield where dtype
279
dfield_t* dfield, /*!< in/out: dfield where dtype
269
280
information must be already set when
270
281
this function is called! */
271
byte* buf, /* in/out: buffer for a converted
282
byte* buf, /*!< in/out: buffer for a converted
272
283
integer value; this must be at least
273
284
col_len long then! */
274
ibool row_format_col, /* TRUE if the mysql_data is from
285
ibool row_format_col, /*!< TRUE if the mysql_data is from
275
286
a MySQL row, FALSE if from a MySQL
277
288
in MySQL, a true VARCHAR storage
278
289
format differs in a row and in a
279
290
key value: in a key value the length
280
291
is always stored in 2 bytes! */
281
const byte* mysql_data, /* in: MySQL column value, not
292
const byte* mysql_data, /*!< in: MySQL column value, not
282
293
SQL NULL; NOTE that dfield may also
283
294
get a pointer to mysql_data,
284
295
therefore do not discard this as long
285
296
as dfield is used! */
286
ulint col_len, /* in: MySQL column length; NOTE that
297
ulint col_len, /*!< in: MySQL column length; NOTE that
287
298
this is the storage length of the
288
299
column in the MySQL format row, not
289
300
necessarily the length of the actual
290
301
payload data; if the column is a true
291
302
VARCHAR then this is irrelevant */
292
ulint comp) /* in: nonzero=compact format */
303
ulint comp) /*!< in: nonzero=compact format */
294
305
const byte* ptr = mysql_data;
295
306
const dtype_t* dtype;
426
437
row_mysql_convert_row_to_innobase(
427
438
/*==============================*/
428
dtuple_t* row, /* in/out: Innobase row where the
439
dtuple_t* row, /*!< in/out: Innobase row where the
429
440
field type information is already
431
row_prebuilt_t* prebuilt, /* in: prebuilt struct where template
442
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct where template
432
443
must be of type ROW_MYSQL_WHOLE_ROW */
433
byte* mysql_rec) /* in: row in the MySQL format;
444
byte* mysql_rec) /*!< in: row in the MySQL format;
434
445
NOTE: do not discard as long as
435
446
row is used, as row may contain
436
447
pointers to this record! */
476
/********************************************************************
477
Handles user errors and lock waits detected by the database engine. */
487
/****************************************************************//**
488
Handles user errors and lock waits detected by the database engine.
489
@return TRUE if it was a lock wait and we should continue running the
480
493
row_mysql_handle_errors(
481
494
/*====================*/
482
/* out: TRUE if it was a lock wait and
483
we should continue running the query thread */
484
ulint* new_err,/* out: possible new error encountered in
495
ulint* new_err,/*!< out: possible new error encountered in
485
496
lock wait, or if no new error, the value
486
497
of trx->error_state at the entry of this
488
trx_t* trx, /* in: transaction */
489
que_thr_t* thr, /* in: query thread */
490
trx_savept_t* savept) /* in: savepoint or NULL */
499
trx_t* trx, /*!< in: transaction */
500
que_thr_t* thr, /*!< in: query thread */
501
trx_savept_t* savept) /*!< in: savepoint or NULL */
492
#ifndef UNIV_HOTBACKUP
495
505
handle_new_error:
583
592
trx->error_state = DB_SUCCESS;
586
#else /* UNIV_HOTBACKUP */
587
/* This function depends on MySQL code that is not included in
588
InnoDB Hot Backup builds. Besides, this function should never
589
be called in InnoDB Hot Backup. */
592
#endif /* UNIV_HOTBACKUP */
595
/************************************************************************
596
Create a prebuilt struct for a MySQL table handle. */
597
/********************************************************************//**
598
Create a prebuilt struct for a MySQL table handle.
599
@return own: a prebuilt struct */
599
602
row_create_prebuilt(
600
603
/*================*/
601
/* out, own: a prebuilt struct */
602
dict_table_t* table) /* in: Innobase table handle */
604
dict_table_t* table) /*!< in: Innobase table handle */
604
606
row_prebuilt_t* prebuilt;
605
607
mem_heap_t* heap;
738
740
mem_heap_free(prebuilt->heap);
741
/*************************************************************************
743
/*********************************************************************//**
742
744
Updates the transaction pointers in query graphs stored in the prebuilt
746
748
row_update_prebuilt_trx(
747
749
/*====================*/
748
/* out: prebuilt dtuple */
749
row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
751
trx_t* trx) /* in: transaction handle */
750
row_prebuilt_t* prebuilt, /*!< in/out: prebuilt struct
752
trx_t* trx) /*!< in: transaction handle */
753
754
if (trx->magic_n != TRX_MAGIC_N) {
792
/*************************************************************************
793
/*********************************************************************//**
793
794
Gets pointer to a prebuilt dtuple used in insertions. If the insert graph
794
795
has not yet been built in the prebuilt struct, then this function first
797
@return prebuilt dtuple; the column type information is also set in it */
798
800
row_get_prebuilt_insert_row(
799
801
/*========================*/
800
/* out: prebuilt dtuple; the column
801
type information is also set in it */
802
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
802
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
805
805
ins_node_t* node;
882
882
mutex_exit(&kernel_mutex);
885
/*************************************************************************
885
/*********************************************************************//**
886
886
Sets an AUTO_INC type lock on the table mentioned in prebuilt. The
887
887
AUTO_INC lock gives exclusive access to the auto-inc counter of the
888
888
table. The lock is reserved only for the duration of an SQL statement.
889
889
It is not compatible with another AUTO_INC or exclusive lock on the
891
@return error code or DB_SUCCESS */
893
894
row_lock_table_autoinc_for_mysql(
894
895
/*=============================*/
895
/* out: error code or DB_SUCCESS */
896
row_prebuilt_t* prebuilt) /* in: prebuilt struct in the MySQL
896
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in the MySQL
899
899
trx_t* trx = prebuilt->trx;
962
962
return((int) err);
965
/*************************************************************************
966
Sets a table lock on the table mentioned in prebuilt. */
965
/*********************************************************************//**
966
Sets a table lock on the table mentioned in prebuilt.
967
@return error code or DB_SUCCESS */
969
970
row_lock_table_for_mysql(
970
971
/*=====================*/
971
/* out: error code or DB_SUCCESS */
972
row_prebuilt_t* prebuilt, /* in: prebuilt struct in the MySQL
972
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in the MySQL
974
dict_table_t* table, /* in: table to lock, or NULL
974
dict_table_t* table, /*!< in: table to lock, or NULL
975
975
if prebuilt->table should be
977
977
prebuilt->select_lock_type */
978
ulint mode) /* in: lock mode of table
978
ulint mode) /*!< in: lock mode of table
979
979
(ignored if table==NULL) */
981
981
trx_t* trx = prebuilt->trx;
1039
1039
return((int) err);
1042
/*************************************************************************
1043
Does an insert for MySQL. */
1042
/*********************************************************************//**
1043
Does an insert for MySQL.
1044
@return error code or DB_SUCCESS */
1046
1047
row_insert_for_mysql(
1047
1048
/*=================*/
1048
/* out: error code or DB_SUCCESS */
1049
byte* mysql_rec, /* in: row in the MySQL format */
1050
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
1049
byte* mysql_rec, /*!< in: row in the MySQL format */
1050
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
1053
1053
trx_savept_t savept;
1201
/*************************************************************************
1200
/*********************************************************************//**
1202
1201
Creates an query graph node of 'update' type to be used in the MySQL
1203
@return own: update node */
1206
1206
row_create_update_node_for_mysql(
1207
1207
/*=============================*/
1208
/* out, own: update node */
1209
dict_table_t* table, /* in: table to update */
1210
mem_heap_t* heap) /* in: mem heap from which allocated */
1208
dict_table_t* table, /*!< in: table to update */
1209
mem_heap_t* heap) /*!< in: mem heap from which allocated */
1212
1211
upd_node_t* node;
1237
/*************************************************************************
1236
/*********************************************************************//**
1238
1237
Gets pointer to a prebuilt update vector used in updates. If the update
1239
1238
graph has not yet been built in the prebuilt struct, then this function
1240
@return prebuilt update vector */
1243
1243
row_get_prebuilt_update_vector(
1244
1244
/*===========================*/
1245
/* out: prebuilt update vector */
1246
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
1245
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
1249
1248
dict_table_t* table = prebuilt->table;
1270
1269
return(prebuilt->upd_node->update);
1273
/*************************************************************************
1274
Does an update or delete of a row for MySQL. */
1272
/*********************************************************************//**
1273
Does an update or delete of a row for MySQL.
1274
@return error code or DB_SUCCESS */
1277
1277
row_update_for_mysql(
1278
1278
/*=================*/
1279
/* out: error code or DB_SUCCESS */
1280
byte* mysql_rec, /* in: the row to be updated, in
1279
byte* mysql_rec, /*!< in: the row to be updated, in
1281
1280
the MySQL format */
1282
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
1281
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
1285
1284
trx_savept_t savept;
1436
1434
in the case of an UPDATE or a DELETE statement, where the row lock is of the
1438
1436
Thus, this implements a 'mini-rollback' that releases the latest record
1438
@return error code or DB_SUCCESS */
1442
1441
row_unlock_for_mysql(
1443
1442
/*=================*/
1444
/* out: error code or DB_SUCCESS */
1445
row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL
1443
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL
1447
ibool has_latches_on_recs)/* TRUE if called so that we have
1445
ibool has_latches_on_recs)/*!< TRUE if called so that we have
1448
1446
the latches on the records under pcur
1449
1447
and clust_pcur, and we do not need to
1450
1448
reposition the cursors. */
1452
dict_index_t* index;
1453
1450
btr_pcur_t* pcur = prebuilt->pcur;
1454
1451
btr_pcur_t* clust_pcur = prebuilt->clust_pcur;
1455
1452
trx_t* trx = prebuilt->trx;
1459
1454
ut_ad(prebuilt && trx);
1460
1455
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
1489
1487
rec = btr_pcur_get_rec(pcur);
1491
lock_rec_unlock(trx, btr_pcur_get_block(pcur),
1492
rec, prebuilt->select_lock_type);
1496
/* If the search was done through the clustered index, then
1497
we have not used clust_pcur at all, and we must NOT try to
1498
reset locks on clust_pcur. The values in clust_pcur may be
1501
if (dict_index_is_clust(index)) {
1507
index = btr_pcur_get_btr_cur(clust_pcur)->index;
1509
if (index != NULL && trx_new_rec_locks_contain(trx, index)) {
1513
/* Restore the cursor position and find the record */
1515
if (!has_latches_on_recs) {
1516
btr_pcur_restore_position(BTR_SEARCH_LEAF, clust_pcur,
1520
rec = btr_pcur_get_rec(clust_pcur);
1522
lock_rec_unlock(trx, btr_pcur_get_block(clust_pcur),
1523
rec, prebuilt->select_lock_type);
1488
index = btr_pcur_get_btr_cur(pcur)->index;
1490
if (prebuilt->new_rec_locks >= 2) {
1491
/* Restore the cursor position and find the record
1492
in the clustered index. */
1494
if (!has_latches_on_recs) {
1495
btr_pcur_restore_position(BTR_SEARCH_LEAF,
1499
rec = btr_pcur_get_rec(clust_pcur);
1500
index = btr_pcur_get_btr_cur(clust_pcur)->index;
1503
if (UNIV_UNLIKELY(!dict_index_is_clust(index))) {
1504
/* This is not a clustered index record. We
1505
do not know how to unlock the record. */
1509
/* If the record has been modified by this
1510
transaction, do not unlock it. */
1512
if (index->trx_id_offset) {
1513
rec_trx_id = trx_read_trx_id(rec
1514
+ index->trx_id_offset);
1516
mem_heap_t* heap = NULL;
1517
ulint offsets_[REC_OFFS_NORMAL_SIZE];
1518
ulint* offsets = offsets_;
1520
rec_offs_init(offsets_);
1521
offsets = rec_get_offsets(rec, index, offsets,
1522
ULINT_UNDEFINED, &heap);
1524
rec_trx_id = row_get_rec_trx_id(rec, index, offsets);
1526
if (UNIV_LIKELY_NULL(heap)) {
1527
mem_heap_free(heap);
1531
if (ut_dulint_cmp(rec_trx_id, trx->id) != 0) {
1532
/* We did not update the record: unlock it */
1534
rec = btr_pcur_get_rec(pcur);
1535
index = btr_pcur_get_btr_cur(pcur)->index;
1537
lock_rec_unlock(trx, btr_pcur_get_block(pcur),
1538
rec, prebuilt->select_lock_type);
1540
if (prebuilt->new_rec_locks >= 2) {
1541
rec = btr_pcur_get_rec(clust_pcur);
1542
index = btr_pcur_get_btr_cur(clust_pcur)->index;
1544
lock_rec_unlock(trx,
1545
btr_pcur_get_block(clust_pcur),
1547
prebuilt->select_lock_type);
1529
1554
trx->op_info = "";
1531
1556
return(DB_SUCCESS);
1534
/**************************************************************************
1535
Does a cascaded delete or set null in a foreign key operation. */
1559
/**********************************************************************//**
1560
Does a cascaded delete or set null in a foreign key operation.
1561
@return error code or DB_SUCCESS */
1538
1564
row_update_cascade_for_mysql(
1539
1565
/*=========================*/
1540
/* out: error code or DB_SUCCESS */
1541
que_thr_t* thr, /* in: query thread */
1542
upd_node_t* node, /* in: update node used in the cascade
1566
que_thr_t* thr, /*!< in: query thread */
1567
upd_node_t* node, /*!< in: update node used in the cascade
1543
1568
or set null operation */
1544
dict_table_t* table) /* in: table where we do the operation */
1569
dict_table_t* table) /*!< in: table where we do the operation */
1616
1642
return(dict_index_get_nth_col(clust_index, 0)->mtype == DATA_SYS);
1619
/*************************************************************************
1645
/*********************************************************************//**
1620
1646
Calculates the key number used inside MySQL for an Innobase index. We have
1621
to take into account if we generated a default clustered index for the table */
1647
to take into account if we generated a default clustered index for the table
1648
@return the key number used inside MySQL */
1624
1651
row_get_mysql_key_number_for_index(
1625
1652
/*===============================*/
1626
const dict_index_t* index)
1653
const dict_index_t* index) /*!< in: index */
1628
1655
const dict_index_t* ind;
1649
/*************************************************************************
1676
/*********************************************************************//**
1650
1677
Locks the data dictionary in shared mode from modifications, for performing
1651
1678
foreign key check, rollback, or other operation invisible to MySQL. */
1654
1681
row_mysql_freeze_data_dictionary_func(
1655
1682
/*==================================*/
1656
trx_t* trx, /* in/out: transaction */
1657
const char* file, /* in: file name */
1658
ulint line) /* in: line number */
1683
trx_t* trx, /*!< in/out: transaction */
1684
const char* file, /*!< in: file name */
1685
ulint line) /*!< in: line number */
1660
1687
ut_a(trx->dict_operation_lock_mode == 0);
1679
1706
trx->dict_operation_lock_mode = 0;
1682
/*************************************************************************
1709
/*********************************************************************//**
1683
1710
Locks the data dictionary exclusively for performing a table create or other
1684
1711
data dictionary modification operation. */
1687
1714
row_mysql_lock_data_dictionary_func(
1688
1715
/*================================*/
1689
trx_t* trx, /* in/out: transaction */
1690
const char* file, /* in: file name */
1691
ulint line) /* in: line number */
1716
trx_t* trx, /*!< in/out: transaction */
1717
const char* file, /*!< in: file name */
1718
ulint line) /*!< in: line number */
1693
1720
ut_a(trx->dict_operation_lock_mode == 0
1694
1721
|| trx->dict_operation_lock_mode == RW_X_LATCH);
1721
1748
trx->dict_operation_lock_mode = 0;
1724
#ifndef UNIV_HOTBACKUP
1725
/*************************************************************************
1751
/*********************************************************************//**
1726
1752
Creates a table for MySQL. If the name of the table ends in
1727
1753
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
1728
1754
"innodb_table_monitor", then this will also start the printing of monitor
1729
1755
output by the master thread. If the table name ends in "innodb_mem_validate",
1730
InnoDB will try to invoke mem_validate(). */
1756
InnoDB will try to invoke mem_validate().
1757
@return error code or DB_SUCCESS */
1733
1760
row_create_table_for_mysql(
1734
1761
/*=======================*/
1735
/* out: error code or DB_SUCCESS */
1736
dict_table_t* table, /* in, own: table definition
1762
dict_table_t* table, /*!< in, own: table definition
1737
1763
(will be freed) */
1738
trx_t* trx) /* in: transaction handle */
1764
trx_t* trx) /*!< in: transaction handle */
1740
1766
tab_node_t* node;
1741
1767
mem_heap_t* heap;
1919
1944
return((int) err);
1922
/*************************************************************************
1947
/*********************************************************************//**
1923
1948
Does an index creation operation for MySQL. TODO: currently failure
1924
1949
to create an index results in dropping the whole table! This is no problem
1925
currently as all indexes must be created at the same time as the table. */
1950
currently as all indexes must be created at the same time as the table.
1951
@return error number or DB_SUCCESS */
1928
1954
row_create_index_for_mysql(
1929
1955
/*=======================*/
1930
/* out: error number or DB_SUCCESS */
1931
dict_index_t* index, /* in, own: index definition
1956
dict_index_t* index, /*!< in, own: index definition
1932
1957
(will be freed) */
1933
trx_t* trx, /* in: transaction handle */
1934
const ulint* field_lengths) /* in: if not NULL, must contain
1958
trx_t* trx, /*!< in: transaction handle */
1959
const ulint* field_lengths) /*!< in: if not NULL, must contain
1935
1960
dict_index_get_n_fields(index)
1936
1961
actual field lengths for the
1937
1962
index columns, which are
2046
2071
return((int) err);
2049
/*************************************************************************
2074
/*********************************************************************//**
2050
2075
Scans a table create SQL string and adds to the data dictionary
2051
2076
the foreign key constraints declared in the string. This function
2052
2077
should be called after the indexes for a table have been created.
2053
2078
Each foreign key constraint must be accompanied with indexes in
2054
2079
bot participating tables. The indexes are allowed to contain more
2055
2080
fields than mentioned in the constraint. Check also that foreign key
2056
constraints which reference this table are ok. */
2081
constraints which reference this table are ok.
2082
@return error code or DB_SUCCESS */
2059
2085
row_table_add_foreign_constraints(
2060
2086
/*==============================*/
2061
/* out: error code or DB_SUCCESS */
2062
trx_t* trx, /* in: transaction */
2063
const char* sql_string, /* in: table create statement where
2087
trx_t* trx, /*!< in: transaction */
2088
const char* sql_string, /*!< in: table create statement where
2064
2089
foreign keys are declared like:
2065
2090
FOREIGN KEY (a, b) REFERENCES table2(c, d),
2066
2091
table2 can be written also with the
2067
2092
database name before it: test.table2 */
2068
const char* name, /* in: table full name in the
2093
const char* name, /*!< in: table full name in the
2069
2094
normalized form
2070
2095
database_name/table_name */
2071
ibool reject_fks) /* in: if TRUE, fail with error
2096
ibool reject_fks) /*!< in: if TRUE, fail with error
2072
2097
code DB_CANNOT_ADD_CONSTRAINT if
2073
2098
any foreign keys are found. */
2111
2135
return((int) err);
2114
/*************************************************************************
2138
/*********************************************************************//**
2115
2139
Drops a table for MySQL as a background operation. MySQL relies on Unix
2116
2140
in ALTER TABLE to the fact that the table handler does not remove the
2117
2141
table before all handles to it has been removed. Furhermore, the MySQL's
2118
2142
call to drop table must be non-blocking. Therefore we do the drop table
2119
2143
as a background operation, which is taken care of by the master thread
2145
@return error code or DB_SUCCESS */
2123
2148
row_drop_table_for_mysql_in_background(
2124
2149
/*===================================*/
2125
/* out: error code or DB_SUCCESS */
2126
const char* name) /* in: table name */
2150
const char* name) /*!< in: table name */
2157
2181
return((int) error);
2160
/*************************************************************************
2184
/*********************************************************************//**
2161
2185
The master thread in srv0srv.c calls this regularly to drop tables which
2162
2186
we must drop in background after queries to them have ended. Such lazy
2163
dropping of tables is needed in ALTER TABLE on Unix. */
2187
dropping of tables is needed in ALTER TABLE on Unix.
2188
@return how many tables dropped + remaining tables in list */
2166
2191
row_drop_tables_for_mysql_in_background(void)
2167
2192
/*=========================================*/
2168
/* out: how many tables dropped
2169
+ remaining tables in list */
2171
2194
row_mysql_drop_t* drop;
2172
2195
dict_table_t* table;
2253
2276
return(UT_LIST_GET_LEN(row_mysql_drop_list));
2256
/*************************************************************************
2279
/*********************************************************************//**
2257
2280
If a table is not yet in the drop list, adds the table to the list of tables
2258
2281
which the master thread drops in background. We need this on Unix because in
2259
2282
ALTER TABLE MySQL may call drop table even if the table has running queries on
2260
2283
it. Also, if there are running foreign key checks on the table, we drop the
2285
@return TRUE if the table was not yet in the drop list, and was added there */
2264
2288
row_add_table_to_background_drop_list(
2265
2289
/*==================================*/
2266
/* out: TRUE if the table was not yet in the
2267
drop list, and was added there */
2268
const char* name) /* in: table name */
2290
const char* name) /*!< in: table name */
2270
2292
row_mysql_drop_t* drop;
2310
/*************************************************************************
2332
/*********************************************************************//**
2311
2333
Discards the tablespace of a table which stored in an .ibd file. Discarding
2312
2334
means that this function deletes the .ibd file and assigns a new table id for
2313
the table. Also the flag table->ibd_file_missing is set TRUE. */
2335
the table. Also the flag table->ibd_file_missing is set TRUE.
2336
@return error code or DB_SUCCESS */
2316
2339
row_discard_tablespace_for_mysql(
2317
2340
/*=============================*/
2318
/* out: error code or DB_SUCCESS */
2319
const char* name, /* in: table name */
2320
trx_t* trx) /* in: transaction handle */
2341
const char* name, /*!< in: table name */
2342
trx_t* trx) /*!< in: transaction handle */
2322
2344
dict_foreign_t* foreign;
2499
2521
return((int) err);
2502
/*********************************************************************
2524
/*****************************************************************//**
2503
2525
Imports a tablespace. The space id in the .ibd file must match the space id
2504
of the table in the data dictionary. */
2526
of the table in the data dictionary.
2527
@return error code or DB_SUCCESS */
2507
2530
row_import_tablespace_for_mysql(
2508
2531
/*============================*/
2509
/* out: error code or DB_SUCCESS */
2510
const char* name, /* in: table name */
2511
trx_t* trx) /* in: transaction handle */
2532
const char* name, /*!< in: table name */
2533
trx_t* trx) /*!< in: transaction handle */
2513
2535
dict_table_t* table;
2637
2659
return((int) err);
2640
/*************************************************************************
2641
Truncates a table for MySQL. */
2662
/*********************************************************************//**
2663
Truncates a table for MySQL.
2664
@return error code or DB_SUCCESS */
2644
2667
row_truncate_table_for_mysql(
2645
2668
/*=========================*/
2646
/* out: error code or DB_SUCCESS */
2647
dict_table_t* table, /* in: table handle */
2648
trx_t* trx) /* in: transaction handle */
2669
dict_table_t* table, /*!< in: table handle */
2670
trx_t* trx) /*!< in: transaction handle */
2650
2672
dict_foreign_t* foreign;
2963
2987
return((int) err);
2966
/*************************************************************************
2990
/*********************************************************************//**
2967
2991
Drops a table for MySQL. If the name of the dropped table ends in
2968
2992
one of "innodb_monitor", "innodb_lock_monitor", "innodb_tablespace_monitor",
2969
2993
"innodb_table_monitor", then this will also stop the printing of monitor
2970
2994
output by the master thread. If the data dictionary was not already locked
2971
2995
by the transaction, the transaction will be committed. Otherwise, the
2972
data dictionary will remain locked. */
2996
data dictionary will remain locked.
2997
@return error code or DB_SUCCESS */
2975
3000
row_drop_table_for_mysql(
2976
3001
/*=====================*/
2977
/* out: error code or DB_SUCCESS */
2978
const char* name, /* in: table name */
2979
trx_t* trx, /* in: transaction handle */
2980
ibool drop_db)/* in: TRUE=dropping whole database */
3002
const char* name, /*!< in: table name */
3003
trx_t* trx, /*!< in: transaction handle */
3004
ibool drop_db)/*!< in: TRUE=dropping whole database */
2982
3006
dict_foreign_t* foreign;
2983
3007
dict_table_t* table;
3059
3083
table = dict_table_get_low(name);
3086
#if defined(BUILD_DRIZZLE)
3089
err = DB_TABLE_NOT_FOUND;
3090
ut_print_timestamp(stderr);
3092
fputs(" InnoDB: Error: table ", stderr);
3093
ut_print_name(stderr, trx, TRUE, name);
3094
fputs(" does not exist in the InnoDB internal\n"
3095
"InnoDB: data dictionary though MySQL is"
3096
" trying to drop it.\n"
3097
"InnoDB: Have you copied the .frm file"
3098
" of the table to the\n"
3099
"InnoDB: MySQL database directory"
3100
" from another database?\n"
3101
"InnoDB: You can look for further help from\n"
3102
"InnoDB: " REFMAN "innodb-troubleshooting.html\n",
3104
#endif /* BUILD_DRIZZLE */
3063
3105
goto funct_exit;
3339
3381
trx->op_info = "";
3341
#ifndef UNIV_HOTBACKUP
3342
3383
srv_wake_master_thread();
3343
#endif /* !UNIV_HOTBACKUP */
3345
3385
return((int) err);
3348
/***********************************************************************
3388
/*******************************************************************//**
3349
3389
Drop all foreign keys in a database, see Bug#18942.
3350
Called at the end of row_drop_database_for_mysql(). */
3390
Called at the end of row_drop_database_for_mysql().
3391
@return error code or DB_SUCCESS */
3353
3394
drop_all_foreign_keys_in_db(
3354
3395
/*========================*/
3355
/* out: error code or DB_SUCCESS */
3356
const char* name, /* in: database name which ends to '/' */
3357
trx_t* trx) /* in: transaction handle */
3396
const char* name, /*!< in: database name which ends to '/' */
3397
trx_t* trx) /*!< in: transaction handle */
3359
3399
pars_info_t* pinfo;
3408
/*************************************************************************
3409
Drops a database for MySQL. */
3448
/*********************************************************************//**
3449
Drops a database for MySQL.
3450
@return error code or DB_SUCCESS */
3412
3453
row_drop_database_for_mysql(
3413
3454
/*========================*/
3414
/* out: error code or DB_SUCCESS */
3415
const char* name, /* in: database name which ends to '/' */
3416
trx_t* trx) /* in: transaction handle */
3455
const char* name, /*!< in: database name which ends to '/' */
3456
trx_t* trx) /*!< in: transaction handle */
3418
3458
dict_table_t* table;
3419
3459
char* table_name;
3502
/*************************************************************************
3542
/*********************************************************************//**
3503
3543
Checks if a table name contains the string "/#sql" which denotes temporary
3545
@return TRUE if temporary table */
3507
3548
row_is_mysql_tmp_table_name(
3508
3549
/*========================*/
3509
/* out: TRUE if temporary table */
3510
const char* name) /* in: table name in the form
3550
const char* name) /*!< in: table name in the form
3511
3551
'database/tablename' */
3513
3553
return(strstr(name, "/#sql") != NULL);
3514
3554
/* return(strstr(name, "/@0023sql") != NULL); */
3517
/********************************************************************
3518
Delete a single constraint. */
3557
/****************************************************************//**
3558
Delete a single constraint.
3559
@return error code or DB_SUCCESS */
3521
3562
row_delete_constraint_low(
3522
3563
/*======================*/
3523
/* out: error code or DB_SUCCESS */
3524
const char* id, /* in: constraint id */
3525
trx_t* trx) /* in: transaction handle */
3564
const char* id, /*!< in: constraint id */
3565
trx_t* trx) /*!< in: transaction handle */
3527
3567
pars_info_t* info = pars_info_create();
3537
3577
, FALSE, trx));
3540
/********************************************************************
3541
Delete a single constraint. */
3580
/****************************************************************//**
3581
Delete a single constraint.
3582
@return error code or DB_SUCCESS */
3544
3585
row_delete_constraint(
3545
3586
/*==================*/
3546
/* out: error code or DB_SUCCESS */
3547
const char* id, /* in: constraint id */
3548
const char* database_name, /* in: database name, with the
3587
const char* id, /*!< in: constraint id */
3588
const char* database_name, /*!< in: database name, with the
3549
3589
trailing '/' */
3550
mem_heap_t* heap, /* in: memory heap */
3551
trx_t* trx) /* in: transaction handle */
3590
mem_heap_t* heap, /*!< in: memory heap */
3591
trx_t* trx) /*!< in: transaction handle */
3570
3610
return((int) err);
3573
/*************************************************************************
3574
Renames a table for MySQL. */
3613
/*********************************************************************//**
3614
Renames a table for MySQL.
3615
@return error code or DB_SUCCESS */
3577
3618
row_rename_table_for_mysql(
3578
3619
/*=======================*/
3579
/* out: error code or DB_SUCCESS */
3580
const char* old_name, /* in: old table name */
3581
const char* new_name, /* in: new table name */
3582
trx_t* trx, /* in: transaction handle */
3583
ibool commit) /* in: if TRUE then commit trx */
3620
const char* old_name, /*!< in: old table name */
3621
const char* new_name, /*!< in: new table name */
3622
trx_t* trx, /*!< in: transaction handle */
3623
ibool commit) /*!< in: if TRUE then commit trx */
3585
3625
dict_table_t* table;
3586
3626
ulint err = DB_ERROR;
3625
3665
table = dict_table_get_low(old_name);
3668
#if defined(BUILD_DRIZZLE)
3671
err = DB_TABLE_NOT_FOUND;
3672
ut_print_timestamp(stderr);
3674
fputs(" InnoDB: Error: table ", stderr);
3675
ut_print_name(stderr, trx, TRUE, old_name);
3676
fputs(" does not exist in the InnoDB internal\n"
3677
"InnoDB: data dictionary though MySQL is"
3678
" trying to rename the table.\n"
3679
"InnoDB: Have you copied the .frm file"
3680
" of the table to the\n"
3681
"InnoDB: MySQL database directory"
3682
" from another database?\n"
3683
"InnoDB: You can look for further help from\n"
3684
"InnoDB: " REFMAN "innodb-troubleshooting.html\n",
3686
#endif /* BUILD_DRIZZLE */
3629
3687
goto funct_exit;
3630
3688
} else if (table->ibd_file_missing) {
3631
3689
err = DB_TABLE_NOT_FOUND;
3789
3846
"InnoDB: Have you deleted the .frm file"
3790
3847
" and not used DROP TABLE?\n"
3791
3848
"InnoDB: You can look for further help from\n"
3792
"InnoDB: http://dev.mysql.com/doc/refman/5.1/en/"
3793
"innodb-troubleshooting.html\n"
3849
"InnoDB: " REFMAN "innodb-troubleshooting.html\n"
3794
3850
"InnoDB: If table ", stderr);
3795
3851
ut_print_name(stderr, trx, TRUE, new_name);
3796
3852
fputs(" is a temporary table #sql..., then"
3882
/*************************************************************************
3938
/*********************************************************************//**
3883
3939
Checks that the index contains entries in an ascending order, unique
3884
3940
constraint is not broken, and calculates the number of index entries
3885
in the read view of the current transaction. */
3941
in the read view of the current transaction.
3942
@return TRUE if ok */
3888
3945
row_scan_and_check_index(
3889
3946
/*=====================*/
3890
/* out: TRUE if ok */
3891
row_prebuilt_t* prebuilt, /* in: prebuilt struct in MySQL */
3892
dict_index_t* index, /* in: index */
3893
ulint* n_rows) /* out: number of entries seen in the
3947
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct in MySQL */
3948
dict_index_t* index, /*!< in: index */
3949
ulint* n_rows) /*!< out: number of entries seen in the
3894
3950
current consistent read */
3896
3952
dtuple_t* prev_entry = NULL;
4037
/*************************************************************************
4038
Checks a table for corruption. */
4113
/*********************************************************************//**
4114
Checks a table for corruption.
4115
@return DB_ERROR or DB_SUCCESS */
4041
4118
row_check_table_for_mysql(
4042
4119
/*======================*/
4043
/* out: DB_ERROR or DB_SUCCESS */
4044
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
4120
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct in MySQL
4047
4123
dict_table_t* table = prebuilt->table;
4149
#endif /* !UNIV_HOTBACKUP */
4151
/*************************************************************************
4152
Determines if a table is a magic monitor table. */
4225
/*********************************************************************//**
4226
Determines if a table is a magic monitor table.
4227
@return TRUE if monitor table */
4155
4230
row_is_magic_monitor_table(
4156
4231
/*=======================*/
4157
/* out: TRUE if monitor table */
4158
const char* table_name) /* in: name of the table, in the
4232
const char* table_name) /*!< in: name of the table, in the
4159
4233
form database/table_name */
4161
4235
const char* name; /* table_name without database/ */