1
/******************************************************
6
Created 2/25/1997 Heikki Tuuri
7
*******************************************************/
12
#include "row0uins.ic"
15
#include "dict0dict.h"
16
#include "dict0boot.h"
17
#include "dict0crea.h"
21
#include "mach0data.h"
29
#include "ibuf0ibuf.h"
32
/*******************************************************************
33
Removes a clustered index record. The pcur in node was positioned on the
34
record, now it is detached. */
37
row_undo_ins_remove_clust_rec(
38
/*==========================*/
39
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
40
undo_node_t* node) /* in: undo node */
50
success = btr_pcur_restore_position(BTR_MODIFY_LEAF, &(node->pcur),
54
if (ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
55
ut_ad(node->trx->dict_operation_lock_mode == RW_X_LATCH);
57
/* Drop the index tree associated with the row in
60
dict_drop_index_tree(btr_pcur_get_rec(&(node->pcur)), &mtr);
66
success = btr_pcur_restore_position(BTR_MODIFY_LEAF,
71
btr_cur = btr_pcur_get_btr_cur(&(node->pcur));
73
success = btr_cur_optimistic_delete(btr_cur, &mtr);
75
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
78
trx_undo_rec_release(node->trx, node->undo_no);
83
/* If did not succeed, try pessimistic descent to tree */
86
success = btr_pcur_restore_position(BTR_MODIFY_TREE,
90
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
92
/* The delete operation may fail if we have little
93
file space left: TODO: easiest to crash the database
94
and restart with more file space */
96
if (err == DB_OUT_OF_FILE_SPACE
97
&& n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
99
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
103
os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
108
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
110
trx_undo_rec_release(node->trx, node->undo_no);
115
/*******************************************************************
116
Removes a secondary index entry if found. */
119
row_undo_ins_remove_sec_low(
120
/*========================*/
121
/* out: DB_SUCCESS, DB_FAIL, or
122
DB_OUT_OF_FILE_SPACE */
123
ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
124
depending on whether we wish optimistic or
125
pessimistic descent down the index tree */
126
dict_index_t* index, /* in: index */
127
dtuple_t* entry) /* in: index entry to remove */
139
found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
141
btr_cur = btr_pcur_get_btr_cur(&pcur);
146
btr_pcur_close(&pcur);
152
if (mode == BTR_MODIFY_LEAF) {
153
success = btr_cur_optimistic_delete(btr_cur, &mtr);
161
ut_ad(mode == BTR_MODIFY_TREE);
163
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
166
btr_pcur_close(&pcur);
172
/*******************************************************************
173
Removes a secondary index entry from the index if found. Tries first
174
optimistic, then pessimistic descent down the tree. */
177
row_undo_ins_remove_sec(
178
/*====================*/
179
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
180
dict_index_t* index, /* in: index */
181
dtuple_t* entry) /* in: index entry to insert */
186
/* Try first optimistic descent to the B-tree */
188
err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry);
190
if (err == DB_SUCCESS) {
195
/* Try then pessimistic descent to the B-tree */
197
err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry);
199
/* The delete operation may fail if we have little
200
file space left: TODO: easiest to crash the database
201
and restart with more file space */
203
if (err != DB_SUCCESS && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
207
os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
215
/***************************************************************
216
Parses the row reference and other info in a fresh insert undo record. */
219
row_undo_ins_parse_undo_rec(
220
/*========================*/
221
undo_node_t* node) /* in: row undo node */
223
dict_index_t* clust_index;
233
ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &dummy,
234
&dummy_extern, &undo_no, &table_id);
235
ut_ad(type == TRX_UNDO_INSERT_REC);
236
node->rec_type = type;
239
node->table = dict_table_get_on_id(table_id, node->trx);
241
/* Skip the UNDO if we can't find the table or the .ibd file. */
242
if (UNIV_UNLIKELY(node->table == NULL)) {
243
} else if (UNIV_UNLIKELY(node->table->ibd_file_missing)) {
246
clust_index = dict_table_get_first_index(node->table);
248
ptr = trx_undo_rec_get_row_ref(
249
ptr, clust_index, &node->ref, node->heap);
253
/***************************************************************
254
Undoes a fresh insert of a row to a table. A fresh insert means that
255
the same clustered index unique key did not have any record, even delete
256
marked, at the time of the insert. */
261
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
262
undo_node_t* node) /* in: row undo node */
265
ut_ad(node->state == UNDO_NODE_INSERT);
267
row_undo_ins_parse_undo_rec(node);
269
if (!node->table || !row_undo_search_clust_to_pcur(node)) {
270
trx_undo_rec_release(node->trx, node->undo_no);
275
/* Iterate over all the indexes and undo the insert.*/
277
/* Skip the clustered index (the first index) */
278
node->index = dict_table_get_next_index(
279
dict_table_get_first_index(node->table));
281
while (node->index != NULL) {
285
entry = row_build_index_entry(node->row, node->ext,
286
node->index, node->heap);
288
err = row_undo_ins_remove_sec(node->index, entry);
290
if (err != DB_SUCCESS) {
295
node->index = dict_table_get_next_index(node->index);
298
return(row_undo_ins_remove_clust_rec(node));