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
);