summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0mysql.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row/row0mysql.cc')
-rw-r--r--storage/innobase/row/row0mysql.cc776
1 files changed, 35 insertions, 741 deletions
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 4a063c9af83..5b38b7c6c01 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1015,9 +1015,6 @@ row_create_prebuilt(
prebuilt->mysql_row_len = mysql_row_len;
- prebuilt->ins_sel_stmt = false;
- prebuilt->session = NULL;
-
prebuilt->fts_doc_id_in_read_set = 0;
prebuilt->blob_heap = NULL;
@@ -1407,282 +1404,12 @@ run_again:
return(err);
}
-/** Perform explicit rollback in absence of UNDO logs.
-@param[in] index apply rollback action on this index
-@param[in] entry entry to remove/rollback.
-@param[in,out] thr thread handler.
-@param[in,out] mtr mini transaction.
-@return error code or DB_SUCCESS */
-static
-dberr_t
-row_explicit_rollback(
- dict_index_t* index,
- const dtuple_t* entry,
- que_thr_t* thr,
- mtr_t* mtr)
-{
- btr_cur_t cursor;
- ulint flags;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets;
- mem_heap_t* heap = NULL;
- dberr_t err = DB_SUCCESS;
-
- rec_offs_init(offsets_);
- flags = BTR_NO_LOCKING_FLAG | BTR_NO_UNDO_LOG_FLAG;
-
- err = btr_cur_search_to_nth_level_with_no_latch(
- index, 0, entry, PAGE_CUR_LE,
- &cursor, __FILE__, __LINE__, mtr);
-
- offsets = rec_get_offsets(
- btr_cur_get_rec(&cursor), index, offsets_,
- ULINT_UNDEFINED, &heap);
-
- if (dict_index_is_clust(index)) {
- err = btr_cur_del_mark_set_clust_rec(
- flags, btr_cur_get_block(&cursor),
- btr_cur_get_rec(&cursor), index,
- offsets, thr, entry, mtr);
- } else {
- err = btr_cur_del_mark_set_sec_rec(
- flags, &cursor, TRUE, thr, mtr);
- }
- ut_ad(err == DB_SUCCESS);
-
- /* Void call just to set mtr modification flag
- to true failing which block is not scheduled for flush*/
- byte* log_ptr = mlog_open(mtr, 0);
- ut_ad(log_ptr == NULL);
- if (log_ptr != NULL) {
- /* To keep complier happy. */
- mlog_close(mtr, log_ptr);
- }
-
- if (heap != NULL) {
- mem_heap_free(heap);
- }
-
- return(err);
-}
-
-/** Convert a row in the MySQL format to a row in the Innobase format.
-This is specialized function used for intrinsic table with reduce branching.
-@param[in,out] row row where field values are copied.
-@param[in] prebuilt prebuilt handler
-@param[in] mysql_rec row in mysql format. */
-static
-void
-row_mysql_to_innobase(
- dtuple_t* row,
- row_prebuilt_t* prebuilt,
- const byte* mysql_rec)
-{
- ut_ad(dict_table_is_intrinsic(prebuilt->table));
-
- const byte* ptr = mysql_rec;
-
- for (ulint i = 0; i < prebuilt->n_template; i++) {
- const mysql_row_templ_t* templ;
- dfield_t* dfield;
-
- templ = prebuilt->mysql_template + i;
- dfield = dtuple_get_nth_field(row, i);
-
- /* Check if column has null value. */
- if (templ->mysql_null_bit_mask != 0) {
- if (mysql_rec[templ->mysql_null_byte_offset]
- & (byte) (templ->mysql_null_bit_mask)) {
- dfield_set_null(dfield);
- continue;
- }
- }
-
- /* Extract the column value. */
- ptr = mysql_rec + templ->mysql_col_offset;
- const dtype_t* dtype = dfield_get_type(dfield);
- ulint col_len = templ->mysql_col_len;
-
- ut_ad(dtype->mtype == DATA_INT
- || dtype->mtype == DATA_CHAR
- || dtype->mtype == DATA_MYSQL
- || dtype->mtype == DATA_VARCHAR
- || dtype->mtype == DATA_VARMYSQL
- || dtype->mtype == DATA_BINARY
- || dtype->mtype == DATA_FIXBINARY
- || dtype->mtype == DATA_FLOAT
- || dtype->mtype == DATA_DOUBLE
- || dtype->mtype == DATA_DECIMAL
- || dtype->mtype == DATA_BLOB
- || dtype->mtype == DATA_GEOMETRY
- || dtype->mtype == DATA_POINT
- || dtype->mtype == DATA_VAR_POINT);
-
-#ifdef UNIV_DEBUG
- if (dtype_get_mysql_type(dtype) == DATA_MYSQL_TRUE_VARCHAR) {
- ut_ad(templ->mysql_length_bytes > 0);
- }
-#endif /* UNIV_DEBUG */
-
- /* For now varchar field this has to be always 0 so
- memcpy of 0 bytes shouldn't affect the original col_len. */
- if (dtype->mtype == DATA_INT) {
- /* Convert and Store in big-endian. */
- byte* buf = prebuilt->ins_upd_rec_buff
- + templ->mysql_col_offset;
- byte* copy_to = buf + col_len;
- for (;;) {
- copy_to--;
- *copy_to = *ptr;
- if (copy_to == buf) {
- break;
- }
- ptr++;
- }
-
- if (!(dtype->prtype & DATA_UNSIGNED)) {
- *buf ^= 128;
- }
-
- ptr = buf;
- buf += col_len;
- } else if (dtype_get_mysql_type(dtype) ==
- DATA_MYSQL_TRUE_VARCHAR) {
-
- ut_ad(dtype->mtype == DATA_VARCHAR
- || dtype->mtype == DATA_VARMYSQL
- || dtype->mtype == DATA_BINARY);
-
- col_len = 0;
- row_mysql_read_true_varchar(
- &col_len, ptr, templ->mysql_length_bytes);
- ptr += templ->mysql_length_bytes;
- } else if (dtype->mtype == DATA_BLOB) {
- ptr = row_mysql_read_blob_ref(&col_len, ptr, col_len);
- } else if (DATA_GEOMETRY_MTYPE(dtype->mtype)) {
- /* Point, Var-Point, Geometry */
- ptr = row_mysql_read_geometry(&col_len, ptr, col_len);
- }
-
- dfield_set_data(dfield, ptr, col_len);
- }
-}
-
-/** Does an insert for MySQL using cursor interface.
-Cursor interface is low level interface that directly interacts at
-Storage Level by-passing all the locking and transaction semantics.
-For InnoDB case, this will also by-pass hidden column generation.
-@param[in] mysql_rec row in the MySQL format
-@param[in,out] prebuilt prebuilt struct in MySQL handle
-@return error code or DB_SUCCESS */
-static
-dberr_t
-row_insert_for_mysql_using_cursor(
- const byte* mysql_rec,
- row_prebuilt_t* prebuilt)
-{
- dberr_t err = DB_SUCCESS;
- ins_node_t* node = NULL;
- que_thr_t* thr = NULL;
- mtr_t mtr;
-
- /* Step-1: Get the reference of row to insert. */
- row_get_prebuilt_insert_row(prebuilt);
- node = prebuilt->ins_node;
- thr = que_fork_get_first_thr(prebuilt->ins_graph);
-
- /* Step-2: Convert row from MySQL row format to InnoDB row format. */
- row_mysql_to_innobase(node->row, prebuilt, mysql_rec);
-
- /* Step-3: Append row-id index is not unique. */
- dict_index_t* clust_index = dict_table_get_first_index(node->table);
-
- if (!dict_index_is_unique(clust_index)) {
- dict_sys_write_row_id(
- node->row_id_buf,
- dict_table_get_next_table_sess_row_id(node->table));
- }
-
- trx_write_trx_id(node->trx_id_buf,
- dict_table_get_next_table_sess_trx_id(node->table));
-
- /* Step-4: Iterate over all the indexes and insert entries. */
- dict_index_t* inserted_upto = NULL;
- node->entry = UT_LIST_GET_FIRST(node->entry_list);
- for (dict_index_t* index = UT_LIST_GET_FIRST(node->table->indexes);
- index != NULL;
- index = UT_LIST_GET_NEXT(indexes, index),
- node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry)) {
-
- node->index = index;
- err = row_ins_index_entry_set_vals(
- node->index, node->entry, node->row);
- if (err != DB_SUCCESS) {
- break;
- }
-
- if (dict_index_is_clust(index)) {
- err = row_ins_clust_index_entry(
- node->index, node->entry, thr, 0, false);
- } else {
- err = row_ins_sec_index_entry(
- node->index, node->entry, thr, false);
- }
-
- if (err == DB_SUCCESS) {
- inserted_upto = index;
- } else {
- break;
- }
- }
-
- /* Step-5: If error is encountered while inserting entries to any
- of the index then entries inserted to previous indexes are removed
- explicity. Automatic rollback is not in action as UNDO logs are
- turned-off. */
- if (err != DB_SUCCESS) {
-
- node->entry = UT_LIST_GET_FIRST(node->entry_list);
-
- mtr_start(&mtr);
- dict_disable_redo_if_temporary(node->table, &mtr);
-
- for (dict_index_t* index =
- UT_LIST_GET_FIRST(node->table->indexes);
- inserted_upto != NULL;
- index = UT_LIST_GET_NEXT(indexes, index),
- node->entry = UT_LIST_GET_NEXT(tuple_list, node->entry)) {
-
- row_explicit_rollback(index, node->entry, thr, &mtr);
-
- if (index == inserted_upto) {
- break;
- }
- }
-
- mtr_commit(&mtr);
- } else {
- /* Not protected by dict_table_stats_lock() for performance
- reasons, we would rather get garbage in stat_n_rows (which is
- just an estimate anyway) than protecting the following code
- , with a latch. */
- dict_table_n_rows_inc(node->table);
-
- srv_stats.n_rows_inserted.inc();
- }
-
- thr_get_trx(thr)->error_state = DB_SUCCESS;
- return(err);
-}
-
-/** Does an insert for MySQL using INSERT graph. This function will run/execute
-INSERT graph.
+/** Does an insert for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle
@return error code or DB_SUCCESS */
-static
dberr_t
-row_insert_for_mysql_using_ins_graph(
+row_insert_for_mysql(
const byte* mysql_rec,
row_prebuilt_t* prebuilt)
{
@@ -1896,26 +1623,6 @@ error_exit:
return(err);
}
-/** Does an insert for MySQL.
-@param[in] mysql_rec row in the MySQL format
-@param[in,out] prebuilt prebuilt struct in MySQL handle
-@return error code or DB_SUCCESS*/
-dberr_t
-row_insert_for_mysql(
- const byte* mysql_rec,
- row_prebuilt_t* prebuilt)
-{
- /* For intrinsic tables there a lot of restrictions that can be
- relaxed including locking of table, transaction handling, etc.
- Use direct cursor interface for inserting to intrinsic tables. */
- if (dict_table_is_intrinsic(prebuilt->table)) {
- return(row_insert_for_mysql_using_cursor(mysql_rec, prebuilt));
- } else {
- return(row_insert_for_mysql_using_ins_graph(
- mysql_rec, prebuilt));
- }
-}
-
/*********************************************************************//**
Builds a dummy query graph used in selects. */
void
@@ -2129,314 +1836,6 @@ public:
};
-typedef std::vector<btr_pcur_t, ut_allocator<btr_pcur_t> > cursors_t;
-
-/** Delete row from table (corresponding entries from all the indexes).
-Function will maintain cursor to the entries to invoke explicity rollback
-just incase update action following delete fails.
-
-@param[in] node update node carrying information to delete.
-@param[out] delete_entries vector of cursor to deleted entries.
-@param[in] restore_delete if true, then restore DELETE records by
- unmarking delete.
-@return error code or DB_SUCCESS */
-static
-dberr_t
-row_delete_for_mysql_using_cursor(
- const upd_node_t* node,
- cursors_t& delete_entries,
- bool restore_delete)
-{
- mtr_t mtr;
- dict_table_t* table = node->table;
- mem_heap_t* heap = mem_heap_create(1000);
- dberr_t err = DB_SUCCESS;
- dtuple_t* entry;
-
- mtr_start(&mtr);
- dict_disable_redo_if_temporary(table, &mtr);
-
- for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
- index != NULL && err == DB_SUCCESS && !restore_delete;
- index = UT_LIST_GET_NEXT(indexes, index)) {
-
- entry = row_build_index_entry(
- node->row, node->ext, index, heap);
-
- btr_pcur_t pcur;
-
- btr_pcur_open(index, entry, PAGE_CUR_LE,
- BTR_MODIFY_LEAF, &pcur, &mtr);
-
-#ifdef UNIV_DEBUG
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
- rec_offs_init(offsets_);
-
- offsets = rec_get_offsets(
- btr_cur_get_rec(btr_pcur_get_btr_cur(&pcur)),
- index, offsets, ULINT_UNDEFINED, &heap);
-
- ut_ad(!cmp_dtuple_rec(
- entry, btr_cur_get_rec(btr_pcur_get_btr_cur(&pcur)),
- offsets));
-#endif /* UNIV_DEBUG */
-
- ut_ad(!rec_get_deleted_flag(
- btr_cur_get_rec(btr_pcur_get_btr_cur(&pcur)),
- dict_table_is_comp(index->table)));
-
- ut_ad(btr_pcur_get_block(&pcur)->made_dirty_with_no_latch);
-
- if (page_rec_is_infimum(btr_pcur_get_rec(&pcur))
- || page_rec_is_supremum(btr_pcur_get_rec(&pcur))) {
- err = DB_ERROR;
- } else {
- btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur);
-
- btr_rec_set_deleted_flag(
- btr_cur_get_rec(btr_cur),
- buf_block_get_page_zip(
- btr_cur_get_block(btr_cur)),
- TRUE);
-
- /* Void call just to set mtr modification flag
- to true failing which block is not scheduled for flush*/
- byte* log_ptr = mlog_open(&mtr, 0);
- ut_ad(log_ptr == NULL);
- if (log_ptr != NULL) {
- /* To keep complier happy. */
- mlog_close(&mtr, log_ptr);
- }
-
- btr_pcur_store_position(&pcur, &mtr);
-
- delete_entries.push_back(pcur);
- }
- }
-
- if (err != DB_SUCCESS || restore_delete) {
-
- /* Rollback half-way delete action that might have been
- applied to few of the indexes. */
- cursors_t::iterator end = delete_entries.end();
- for (cursors_t::iterator it = delete_entries.begin();
- it != end;
- ++it) {
-
- ibool success = btr_pcur_restore_position(
- BTR_MODIFY_LEAF, &(*it), &mtr);
-
- if (!success) {
- ut_a(success);
- } else {
- btr_cur_t* btr_cur = btr_pcur_get_btr_cur(
- &(*it));
-
- ut_ad(btr_cur_get_block(
- btr_cur)->made_dirty_with_no_latch);
-
- btr_rec_set_deleted_flag(
- btr_cur_get_rec(btr_cur),
- buf_block_get_page_zip(
- btr_cur_get_block(btr_cur)),
- FALSE);
-
- /* Void call just to set mtr modification flag
- to true failing which block is not scheduled for
- flush. */
- byte* log_ptr = mlog_open(&mtr, 0);
- ut_ad(log_ptr == NULL);
- if (log_ptr != NULL) {
- /* To keep complier happy. */
- mlog_close(&mtr, log_ptr);
- }
- }
- }
- }
-
- mtr_commit(&mtr);
-
- mem_heap_free(heap);
-
- return(err);
-}
-
-/** Does an update of a row for MySQL by inserting new entry with update values.
-@param[in] node update node carrying information to delete.
-@param[out] delete_entries vector of cursor to deleted entries.
-@param[in] thr thread handler
-@return error code or DB_SUCCESS */
-static
-dberr_t
-row_update_for_mysql_using_cursor(
- const upd_node_t* node,
- cursors_t& delete_entries,
- que_thr_t* thr)
-{
- dberr_t err = DB_SUCCESS;
- dict_table_t* table = node->table;
- mem_heap_t* heap = mem_heap_create(1000);
- dtuple_t* entry;
- dfield_t* trx_id_field;
-
- /* Step-1: Update row-id column if table doesn't have unique index. */
- if (!dict_index_is_unique(dict_table_get_first_index(table))) {
- /* Update the row_id column. */
- dfield_t* row_id_field;
-
- row_id_field = dtuple_get_nth_field(
- node->upd_row, dict_table_get_n_cols(table) - 2);
-
- dict_sys_write_row_id(
- static_cast<byte*>(row_id_field->data),
- dict_table_get_next_table_sess_row_id(node->table));
- }
-
- /* Step-2: Update the trx_id column. */
- trx_id_field = dtuple_get_nth_field(
- node->upd_row, dict_table_get_n_cols(table) - 1);
- trx_write_trx_id(static_cast<byte*>(trx_id_field->data),
- dict_table_get_next_table_sess_trx_id(node->table));
-
-
- /* Step-3: Check if UPDATE can lead to DUPLICATE key violation.
- If yes, then avoid executing it and return error. Only after ensuring
- that UPDATE is safe execute it as we can't rollback. */
- for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
- index != NULL && err == DB_SUCCESS;
- index = UT_LIST_GET_NEXT(indexes, index)) {
-
- entry = row_build_index_entry(
- node->upd_row, node->upd_ext, index, heap);
-
- if (dict_index_is_clust(index)) {
- if (!dict_index_is_auto_gen_clust(index)) {
- err = row_ins_clust_index_entry(
- index, entry, thr,
- node->upd_ext
- ? node->upd_ext->n_ext : 0,
- true);
- }
- } else {
- err = row_ins_sec_index_entry(index, entry, thr, true);
- }
- }
-
- if (err != DB_SUCCESS) {
- /* This suggest update can't be executed safely.
- Avoid executing update. Rollback DELETE action. */
- row_delete_for_mysql_using_cursor(node, delete_entries, true);
- }
-
- /* Step-4: It is now safe to execute update if there is no error */
- for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
- index != NULL && err == DB_SUCCESS;
- index = UT_LIST_GET_NEXT(indexes, index)) {
-
- entry = row_build_index_entry(
- node->upd_row, node->upd_ext, index, heap);
-
- if (dict_index_is_clust(index)) {
- err = row_ins_clust_index_entry(
- index, entry, thr,
- node->upd_ext ? node->upd_ext->n_ext : 0,
- false);
- /* Commit the open mtr as we are processing UPDATE. */
- index->last_ins_cur->release();
- } else {
- err = row_ins_sec_index_entry(index, entry, thr, false);
- }
-
- /* Too big record is valid error and suggestion is to use
- bigger page-size or different format. */
- ut_ad(err == DB_SUCCESS
- || err == DB_TOO_BIG_RECORD
- || err == DB_OUT_OF_FILE_SPACE);
-
- if (err == DB_TOO_BIG_RECORD) {
- row_delete_for_mysql_using_cursor(
- node, delete_entries, true);
- }
- }
-
- if (heap != NULL) {
- mem_heap_free(heap);
- }
- return(err);
-}
-
-/** Does an update or delete of a row for MySQL.
-@param[in] mysql_rec row in the MySQL format
-@param[in,out] prebuilt prebuilt struct in MySQL handle
-@return error code or DB_SUCCESS */
-static
-dberr_t
-row_del_upd_for_mysql_using_cursor(
- const byte* mysql_rec,
- row_prebuilt_t* prebuilt)
-{
- dberr_t err = DB_SUCCESS;
- upd_node_t* node;
- cursors_t delete_entries;
- dict_index_t* clust_index;
- que_thr_t* thr = NULL;
-
- /* Step-0: If there is cached insert position commit it before
- starting delete/update action as this can result in btree structure
- to change. */
- thr = que_fork_get_first_thr(prebuilt->upd_graph);
- clust_index = dict_table_get_first_index(prebuilt->table);
- clust_index->last_ins_cur->release();
-
- /* Step-1: Select the appropriate cursor that will help build
- the original row and updated row. */
- node = prebuilt->upd_node;
- if (prebuilt->pcur->btr_cur.index == clust_index) {
- btr_pcur_copy_stored_position(node->pcur, prebuilt->pcur);
- } else {
- btr_pcur_copy_stored_position(node->pcur,
- prebuilt->clust_pcur);
- }
-
- ut_ad(dict_table_is_intrinsic(prebuilt->table));
- ut_ad(!prebuilt->table->n_v_cols);
-
- /* Internal table is created by optimiser. So there
- should not be any virtual columns. */
- row_upd_store_row(node, NULL, NULL);
-
- /* Step-2: Execute DELETE operation. */
- err = row_delete_for_mysql_using_cursor(node, delete_entries, false);
-
- /* Step-3: If only DELETE operation then exit immediately. */
- if (node->is_delete) {
- if (err == DB_SUCCESS) {
- dict_table_n_rows_dec(prebuilt->table);
- srv_stats.n_rows_deleted.inc();
- }
- }
-
- if (err == DB_SUCCESS && !node->is_delete) {
- /* Step-4: Complete UPDATE operation by inserting new row with
- updated data. */
- err = row_update_for_mysql_using_cursor(
- node, delete_entries, thr);
-
- if (err == DB_SUCCESS) {
- srv_stats.n_rows_updated.inc();
- }
- }
-
- thr_get_trx(thr)->error_state = DB_SUCCESS;
- cursors_t::iterator end = delete_entries.end();
- for (cursors_t::iterator it = delete_entries.begin(); it != end; ++it) {
- btr_pcur_close(&(*it));
- }
-
- return(err);
-}
-
/** Does an update or delete of a row for MySQL.
@param[in] mysql_rec row in the MySQL format
@param[in,out] prebuilt prebuilt struct in MySQL handle
@@ -2794,41 +2193,8 @@ row_update_for_mysql(
const byte* mysql_rec,
row_prebuilt_t* prebuilt)
{
- if (dict_table_is_intrinsic(prebuilt->table)) {
- return(row_del_upd_for_mysql_using_cursor(mysql_rec, prebuilt));
- } else {
- ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
- return(row_update_for_mysql_using_upd_graph(
- mysql_rec, prebuilt));
- }
-}
-
-/** Delete all rows for the given table by freeing/truncating indexes.
-@param[in,out] table table handler
-@return error code or DB_SUCCESS */
-dberr_t
-row_delete_all_rows(
- dict_table_t* table)
-{
- dberr_t err = DB_SUCCESS;
-
- /* Step-0: If there is cached insert position along with mtr
- commit it before starting delete/update action. */
- dict_table_get_first_index(table)->last_ins_cur->release();
-
- /* Step-1: Now truncate all the indexes and re-create them.
- Note: This is ddl action even though delete all rows is
- DML action. Any error during this action is ir-reversible. */
- for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
- index != NULL && err == DB_SUCCESS;
- index = UT_LIST_GET_NEXT(indexes, index)) {
-
- err = dict_truncate_index_tree_in_mem(index);
- // TODO: what happen if get an error
- ut_ad(err == DB_SUCCESS);
- }
-
- return(err);
+ ut_a(prebuilt->template_type == ROW_MYSQL_WHOLE_ROW);
+ return(row_update_for_mysql_using_upd_graph(mysql_rec, prebuilt));
}
/** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
@@ -3258,13 +2624,12 @@ row_create_index_for_mysql(
dict_index_t* index, /*!< in, own: index definition
(will be freed) */
trx_t* trx, /*!< in: transaction handle */
- const ulint* field_lengths, /*!< in: if not NULL, must contain
+ const ulint* field_lengths) /*!< in: if not NULL, must contain
dict_index_get_n_fields(index)
actual field lengths for the
index columns, which are
then checked for not being too
large. */
- dict_table_t* handler) /*!< in/out: table handler. */
{
ind_node_t* node;
mem_heap_t* heap;
@@ -3287,22 +2652,11 @@ row_create_index_for_mysql(
is_fts = (index->type == DICT_FTS);
- if (handler != NULL && dict_table_is_intrinsic(handler)) {
- table = handler;
- }
-
- if (table == NULL) {
-
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- ut_ad(mutex_own(&dict_sys->mutex));
-
- table = dict_table_open_on_name(table_name, TRUE, TRUE,
- DICT_ERR_IGNORE_NONE);
+ ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_ad(mutex_own(&dict_sys->mutex));
- } else {
- table->acquire();
- ut_ad(dict_table_is_intrinsic(table));
- }
+ table = dict_table_open_on_name(table_name, TRUE, TRUE,
+ DICT_ERR_IGNORE_NONE);
if (!dict_table_is_temporary(table)) {
trx_start_if_not_started_xa(trx, true);
@@ -3361,13 +2715,9 @@ row_create_index_for_mysql(
index_id_t index_id = index->id;
- /* add index to dictionary cache and also free index object.
- We allow instrinsic table to violate the size limits because
- they are used by optimizer for all record formats. */
+ /* add index to dictionary cache and also free index object. */
err = dict_index_add_to_cache(
- table, index, FIL_NULL,
- !dict_table_is_intrinsic(table)
- && trx_is_strict(trx));
+ table, index, FIL_NULL, trx_is_strict(trx));
if (err != DB_SUCCESS) {
goto error_handling;
@@ -3375,23 +2725,13 @@ row_create_index_for_mysql(
/* as above function has freed index object re-load it
now from dictionary cache using index_id */
- if (!dict_table_is_intrinsic(table)) {
- index = dict_index_get_if_in_cache_low(index_id);
- } else {
- index = dict_table_find_index_on_id(table, index_id);
-
- /* trx_id field is used for tracking which transaction
- created the index. For intrinsic table this is
- ir-relevant and so re-use it for tracking consistent
- view while processing SELECT as part of UPDATE. */
- index->trx_id = ULINT_UNDEFINED;
- }
+ index = dict_index_get_if_in_cache_low(index_id);
ut_a(index != NULL);
index->table = table;
err = dict_create_index_tree_in_mem(index, trx);
- if (err != DB_SUCCESS && !dict_table_is_intrinsic(table)) {
+ if (err != DB_SUCCESS) {
dict_index_remove_from_cache(table, index);
}
}
@@ -3420,7 +2760,7 @@ error_handling:
trx_rollback_to_savepoint(trx, NULL);
}
- row_drop_table_for_mysql(table_name, trx, FALSE, true, handler);
+ row_drop_table_for_mysql(table_name, trx, FALSE, true);
if (trx_is_started(trx)) {
@@ -3489,9 +2829,6 @@ row_table_add_foreign_constraints(
DEBUG_SYNC_C("table_add_foreign_constraints");
- /* Check like this shouldn't be done for table that doesn't
- have foreign keys but code still continues to run with void action.
- Disable it for intrinsic table at-least */
if (err == DB_SUCCESS) {
/* Check that also referencing constraints are ok */
dict_names_t fk_tables;
@@ -4263,23 +3600,7 @@ row_drop_table_from_cache(
is going to be destroyed below. */
trx->mod_tables.erase(table);
- if (!dict_table_is_intrinsic(table)) {
- dict_table_remove_from_cache(table);
- } else {
- for (dict_index_t* index = UT_LIST_GET_FIRST(table->indexes);
- index != NULL;
- index = UT_LIST_GET_FIRST(table->indexes)) {
-
- rw_lock_free(&index->lock);
-
- UT_LIST_REMOVE(table->indexes, index);
-
- dict_mem_index_free(index);
- }
-
- dict_mem_table_free(table);
- table = NULL;
- }
+ dict_table_remove_from_cache(table);
if (!is_temp
&& dict_load_table(tablename, true,
@@ -4355,7 +3676,6 @@ will remain locked.
because e.g. foreign key column
@param[in] nonatomic Whether it is permitted to release
and reacquire dict_operation_lock
-@param[in,out] handler Table handler
@return error code or DB_SUCCESS */
dberr_t
row_drop_table_for_mysql(
@@ -4363,18 +3683,16 @@ row_drop_table_for_mysql(
trx_t* trx,
bool drop_db,
ibool create_failed,
- bool nonatomic,
- dict_table_t* handler)
+ bool nonatomic)
{
dberr_t err;
dict_foreign_t* foreign;
- dict_table_t* table = NULL;
+ dict_table_t* table;
char* filepath = NULL;
char* tablename = NULL;
bool locked_dictionary = false;
pars_info_t* info = NULL;
mem_heap_t* heap = NULL;
- bool is_intrinsic_temp_table = false;
DBUG_ENTER("row_drop_table_for_mysql");
DBUG_PRINT("row_drop_table_for_mysql", ("table: '%s'", name));
@@ -4386,35 +3704,24 @@ row_drop_table_for_mysql(
trx->op_info = "dropping table";
- if (handler != NULL && dict_table_is_intrinsic(handler)) {
- table = handler;
- is_intrinsic_temp_table = true;
- }
-
- if (table == NULL) {
-
- if (trx->dict_operation_lock_mode != RW_X_LATCH) {
- /* Prevent foreign key checks etc. while we are
- dropping the table */
+ if (trx->dict_operation_lock_mode != RW_X_LATCH) {
+ /* Prevent foreign key checks etc. while we are
+ dropping the table */
- row_mysql_lock_data_dictionary(trx);
+ row_mysql_lock_data_dictionary(trx);
- locked_dictionary = true;
- nonatomic = true;
- }
+ locked_dictionary = true;
+ nonatomic = true;
+ }
- ut_ad(mutex_own(&dict_sys->mutex));
- ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
+ ut_ad(mutex_own(&dict_sys->mutex));
+ ut_ad(rw_lock_own(dict_operation_lock, RW_LOCK_X));
- table = dict_table_open_on_name(
- name, TRUE, FALSE,
- static_cast<dict_err_ignore_t>(
- DICT_ERR_IGNORE_INDEX_ROOT
- | DICT_ERR_IGNORE_CORRUPT));
- } else {
- table->acquire();
- ut_ad(dict_table_is_intrinsic(table));
- }
+ table = dict_table_open_on_name(
+ name, TRUE, FALSE,
+ static_cast<dict_err_ignore_t>(
+ DICT_ERR_IGNORE_INDEX_ROOT
+ | DICT_ERR_IGNORE_CORRUPT));
if (!table) {
err = DB_TABLE_NOT_FOUND;
@@ -4495,10 +3802,7 @@ row_drop_table_for_mysql(
}
}
- if (!dict_table_is_intrinsic(table)) {
- dict_table_prevent_eviction(table);
- }
-
+ dict_table_prevent_eviction(table);
dict_table_close(table, TRUE, FALSE);
/* Check if the table is referenced by foreign key constraints from
@@ -4600,16 +3904,11 @@ row_drop_table_for_mysql(
fil_wait_crypt_bg_threads(table);
if (table->get_ref_count() == 0) {
- /* We don't take lock on intrinsic table so nothing to remove.*/
- if (!dict_table_is_intrinsic(table)) {
- lock_remove_all_on_table(table, TRUE);
- }
+ lock_remove_all_on_table(table, TRUE);
ut_a(table->n_rec_locks == 0);
} else if (table->get_ref_count() > 0 || table->n_rec_locks > 0) {
ibool added;
- ut_ad(!dict_table_is_intrinsic(table));
-
added = row_add_table_to_background_drop_list(
table->name.m_name);
@@ -4641,7 +3940,7 @@ row_drop_table_for_mysql(
/* If we get this far then the table to be dropped must not have
any table or record locks on it. */
- ut_a(dict_table_is_intrinsic(table) || !lock_table_has_locks(table));
+ ut_a(!lock_table_has_locks(table));
switch (trx_get_dict_operation(trx)) {
case TRX_DICT_OP_NONE:
@@ -4974,12 +4273,7 @@ funct_exit:
trx->op_info = "";
- /* No need to immediately invoke master thread as there is no work
- generated by intrinsic table operation that needs master thread
- attention. */
- if (!is_intrinsic_temp_table) {
- srv_wake_master_thread();
- }
+ srv_wake_master_thread();
DBUG_RETURN(err);
}