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) {
56
/* Drop the index tree associated with the row in
59
dict_drop_index_tree(btr_pcur_get_rec(&(node->pcur)), &mtr);
65
success = btr_pcur_restore_position(BTR_MODIFY_LEAF,
70
btr_cur = btr_pcur_get_btr_cur(&(node->pcur));
72
success = btr_cur_optimistic_delete(btr_cur, &mtr);
74
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
77
trx_undo_rec_release(node->trx, node->undo_no);
82
/* If did not succeed, try pessimistic descent to tree */
85
success = btr_pcur_restore_position(BTR_MODIFY_TREE,
89
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
91
/* The delete operation may fail if we have little
92
file space left: TODO: easiest to crash the database
93
and restart with more file space */
95
if (err == DB_OUT_OF_FILE_SPACE
96
&& n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
98
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
102
os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
107
btr_pcur_commit_specify_mtr(&(node->pcur), &mtr);
109
trx_undo_rec_release(node->trx, node->undo_no);
114
/*******************************************************************
115
Removes a secondary index entry if found. */
118
row_undo_ins_remove_sec_low(
119
/*========================*/
120
/* out: DB_SUCCESS, DB_FAIL, or
121
DB_OUT_OF_FILE_SPACE */
122
ulint mode, /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
123
depending on whether we wish optimistic or
124
pessimistic descent down the index tree */
125
dict_index_t* index, /* in: index */
126
dtuple_t* entry) /* in: index entry to remove */
138
found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
140
btr_cur = btr_pcur_get_btr_cur(&pcur);
145
btr_pcur_close(&pcur);
151
if (mode == BTR_MODIFY_LEAF) {
152
success = btr_cur_optimistic_delete(btr_cur, &mtr);
160
ut_ad(mode == BTR_MODIFY_TREE);
162
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
165
btr_pcur_close(&pcur);
171
/*******************************************************************
172
Removes a secondary index entry from the index if found. Tries first
173
optimistic, then pessimistic descent down the tree. */
176
row_undo_ins_remove_sec(
177
/*====================*/
178
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
179
dict_index_t* index, /* in: index */
180
dtuple_t* entry) /* in: index entry to insert */
185
/* Try first optimistic descent to the B-tree */
187
err = row_undo_ins_remove_sec_low(BTR_MODIFY_LEAF, index, entry);
189
if (err == DB_SUCCESS) {
194
/* Try then pessimistic descent to the B-tree */
196
err = row_undo_ins_remove_sec_low(BTR_MODIFY_TREE, index, entry);
198
/* The delete operation may fail if we have little
199
file space left: TODO: easiest to crash the database
200
and restart with more file space */
202
if (err != DB_SUCCESS && n_tries < BTR_CUR_RETRY_DELETE_N_TIMES) {
206
os_thread_sleep(BTR_CUR_RETRY_SLEEP_TIME);
214
/***************************************************************
215
Parses the row reference and other info in a fresh insert undo record. */
218
row_undo_ins_parse_undo_rec(
219
/*========================*/
220
undo_node_t* node) /* in: row undo node */
222
dict_index_t* clust_index;
232
ptr = trx_undo_rec_get_pars(node->undo_rec, &type, &dummy,
233
&dummy_extern, &undo_no, &table_id);
234
ut_ad(type == TRX_UNDO_INSERT_REC);
235
node->rec_type = type;
237
node->table = dict_table_get_on_id(table_id, node->trx);
239
if (node->table == NULL) {
244
if (node->table->ibd_file_missing) {
245
/* We skip undo operations to missing .ibd files */
251
clust_index = dict_table_get_first_index(node->table);
253
ptr = trx_undo_rec_get_row_ref(ptr, clust_index, &(node->ref),
257
/***************************************************************
258
Undoes a fresh insert of a row to a table. A fresh insert means that
259
the same clustered index unique key did not have any record, even delete
260
marked, at the time of the insert. */
265
/* out: DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
266
undo_node_t* node) /* in: row undo node */
273
ut_ad(node->state == UNDO_NODE_INSERT);
275
row_undo_ins_parse_undo_rec(node);
277
if (node->table == NULL) {
280
found = row_undo_search_clust_to_pcur(node);
284
trx_undo_rec_release(node->trx, node->undo_no);
289
node->index = dict_table_get_next_index(
290
dict_table_get_first_index(node->table));
292
while (node->index != NULL) {
293
entry = row_build_index_entry(node->row, node->index,
295
err = row_undo_ins_remove_sec(node->index, entry);
297
if (err != DB_SUCCESS) {
302
node->index = dict_table_get_next_index(node->index);
305
err = row_undo_ins_remove_clust_rec(node);