29 #include "row0umod.ic"
75 static __attribute__((nonnull, warn_unused_result))
77 row_undo_mod_clust_low(
102 btr_cur = btr_pcur_get_btr_cur(pcur);
107 btr_pcur_restore_position(mode, pcur, mtr);
110 ut_ad(rec_get_trx_id(btr_cur_get_rec(btr_cur),
117 btr_cur_get_rec(btr_cur),
120 *rebuilt_old_pk = NULL;
129 btr_cur, offsets, offsets_heap,
130 node->update, node->cmpl_info,
139 btr_cur, offsets, offsets_heap, heap,
140 &dummy_big_rec, node->update,
143 ut_a(!dummy_big_rec);
155 static __attribute__((nonnull, warn_unused_result))
157 row_undo_mod_remove_clust_low(
168 ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
173 if (!btr_pcur_restore_position(mode, &node->pcur, mtr)
179 btr_cur = btr_pcur_get_btr_cur(&node->pcur);
183 if (!trx_id_offset) {
191 ut_ad(trx_id_col > 0);
192 ut_ad(trx_id_col != ULINT_UNDEFINED);
194 offsets = rec_get_offsets(
196 NULL, trx_id_col + 1, &heap);
199 offsets, trx_id_col, &len);
200 ut_ad(len == DATA_TRX_ID_LEN);
205 != node->new_trx_id) {
218 err = btr_cur_optimistic_delete(btr_cur, 0, mtr)
244 static __attribute__((nonnull, warn_unused_result))
258 ut_ad(node->trx->dict_operation_lock_mode);
259 #ifdef UNIV_SYNC_DEBUG
272 ut_ad(node->trx->dict_operation_lock_mode != RW_X_LATCH);
278 ulint* offsets = NULL;
284 err = row_undo_mod_clust_low(node, &offsets, &offsets_heap,
285 heap, &rebuilt_old_pk,
290 if (err != DB_SUCCESS) {
298 err = row_undo_mod_clust_low(
299 node, &offsets, &offsets_heap, heap, &rebuilt_old_pk,
301 ut_ad(err == DB_SUCCESS || err == DB_OUT_OF_FILE_SPACE);
308 if (err == DB_SUCCESS && online) {
309 #ifdef UNIV_SYNC_DEBUG
310 ut_ad(rw_lock_own(&index->
lock, RW_LOCK_SHARED)
311 || rw_lock_own(&index->
lock, RW_LOCK_EX));
313 switch (node->rec_type) {
314 case TRX_UNDO_DEL_MARK_REC:
316 btr_pcur_get_rec(pcur), index, offsets);
318 case TRX_UNDO_UPD_EXIST_REC:
320 btr_pcur_get_rec(pcur), index, offsets,
323 case TRX_UNDO_UPD_DEL_REC:
325 btr_pcur_get_rec(pcur), index, offsets,
326 true, node->trx->
id);
334 ut_ad(rec_get_trx_id(btr_pcur_get_rec(pcur), index)
335 == node->new_trx_id);
339 if (err == DB_SUCCESS && node->rec_type == TRX_UNDO_UPD_DEL_REC) {
346 err = row_undo_mod_remove_clust_low(
348 if (err != DB_SUCCESS) {
356 err = row_undo_mod_remove_clust_low(node, thr, &mtr,
359 ut_ad(err == DB_SUCCESS
360 || err == DB_OUT_OF_FILE_SPACE);
380 static __attribute__((nonnull, warn_unused_result))
382 row_undo_mod_del_mark_or_remove_sec_low(
417 goto func_exit_no_pcur;
426 btr_cur = btr_pcur_get_btr_cur(&pcur);
431 switch (UNIV_EXPECT(search_result,
ROW_FOUND)) {
464 btr_pcur_get_rec(&(node->pcur)),
465 &mtr_vers, index, entry);
468 btr_cur, TRUE, thr, &mtr);
469 ut_ad(err == DB_SUCCESS);
474 success = btr_cur_optimistic_delete(btr_cur, 0, &mtr);
516 static __attribute__((nonnull, warn_unused_result))
518 row_undo_mod_del_mark_or_remove_sec(
527 err = row_undo_mod_del_mark_or_remove_sec_low(node, thr, index,
529 if (err == DB_SUCCESS) {
534 err = row_undo_mod_del_mark_or_remove_sec_low(node, thr, index,
549 static __attribute__((nonnull, warn_unused_result))
551 row_undo_mod_del_unmark_sec_and_undo_update(
560 btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur);
589 goto func_exit_no_pcur;
601 switch (search_result) {
621 fputs(
"InnoDB: error in sec index entry del undo in\n"
625 "InnoDB: tuple ", stderr);
628 "InnoDB: record ", stderr);
629 rec_print(stderr, btr_pcur_get_rec(&pcur), index);
633 "InnoDB: Submit a detailed bug report"
634 " to http://bugs.mysql.com\n", stderr);
637 "record in index %s was not found"
638 " on rollback, trying to insert",
646 "record in index %s was not found on"
647 " rollback, and a duplicate exists",
650 err = DB_DUPLICATE_KEY;
662 flags, btr_cur, &offsets, &offsets_heap,
663 entry, &insert_rec, &big_rec,
670 &offsets, &offsets_heap,
671 entry, &insert_rec, &big_rec,
678 if (err == DB_SUCCESS) {
680 btr_cur_get_block(btr_cur),
693 btr_cur, FALSE, thr, &mtr);
694 ut_a(err == DB_SUCCESS);
699 offsets = rec_get_offsets(
700 btr_cur_get_rec(btr_cur),
701 index, NULL, ULINT_UNDEFINED, &offsets_heap);
703 btr_cur_get_rec(btr_cur), index, offsets, entry, heap);
714 flags, btr_cur, &offsets, &offsets_heap,
719 case DB_ZIP_OVERFLOW:
726 flags, btr_cur, &offsets, &offsets_heap,
727 heap, &dummy_big_rec,
729 ut_a(!dummy_big_rec);
745 static __attribute__((nonnull))
747 row_undo_mod_sec_flag_corrupted(
754 switch (trx->dict_operation_lock_mode) {
777 static __attribute__((nonnull, warn_unused_result))
779 row_undo_mod_upd_del_sec(
787 ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
788 ut_ad(!node->undo_row);
792 while (node->index != NULL) {
796 if (index->
type & DICT_FTS) {
797 dict_table_next_uncorrupted_index(node->index);
809 node->row, node->ext, index, heap);
811 if (UNIV_UNLIKELY(!entry)) {
823 err = row_undo_mod_del_mark_or_remove_sec(
824 node, thr, index, entry);
826 if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
833 dict_table_next_uncorrupted_index(node->index);
844 static __attribute__((nonnull, warn_unused_result))
846 row_undo_mod_del_mark_sec(
854 ut_ad(!node->undo_row);
858 while (node->index != NULL) {
862 if (index->
type == DICT_FTS) {
863 dict_table_next_uncorrupted_index(node->index);
875 node->row, node->ext, index, heap);
879 err = row_undo_mod_del_unmark_sec_and_undo_update(
881 if (err == DB_FAIL) {
882 err = row_undo_mod_del_unmark_sec_and_undo_update(
886 if (err == DB_DUPLICATE_KEY) {
887 row_undo_mod_sec_flag_corrupted(
896 }
else if (err != DB_SUCCESS) {
901 dict_table_next_uncorrupted_index(node->index);
912 static __attribute__((nonnull, warn_unused_result))
914 row_undo_mod_upd_exist_sec(
922 if (node->index == NULL
923 || ((node->cmpl_info & UPD_NODE_NO_ORD_CHANGE))) {
931 while (node->index != NULL) {
935 if (index->
type == DICT_FTS
936 || !row_upd_changes_ord_field_binary(
937 index, node->update, thr, node->row, node->ext)) {
938 dict_table_next_uncorrupted_index(node->index);
945 if (UNIV_UNLIKELY(!entry)) {
983 err = row_undo_mod_del_mark_or_remove_sec(
984 node, thr, index, entry);
985 if (err != DB_SUCCESS) {
1002 err = row_undo_mod_del_unmark_sec_and_undo_update(
1004 if (err == DB_FAIL) {
1005 err = row_undo_mod_del_unmark_sec_and_undo_update(
1009 if (err == DB_DUPLICATE_KEY) {
1010 row_undo_mod_sec_flag_corrupted(
1013 }
else if (err != DB_SUCCESS) {
1018 dict_table_next_uncorrupted_index(node->index);
1028 static __attribute__((nonnull))
1030 row_undo_mod_parse_undo_rec(
1038 table_id_t table_id;
1047 &dummy_extern, &undo_no, &table_id);
1048 node->rec_type =
type;
1056 if (node->table == NULL) {
1061 if (node->table->ibd_file_missing) {
1070 clust_index = dict_table_get_first_index(node->table);
1079 roll_ptr, info_bits, node->trx,
1080 node->
heap, &(node->update));
1081 node->new_trx_id = trx_id;
1082 node->cmpl_info = cmpl_info;
1112 row_undo_mod_parse_undo_rec(node, dict_locked);
1114 if (node->
table == NULL) {
1124 node->
index = dict_table_get_first_index(node->
table);
1127 node->
index = dict_table_get_next_index(node->
index);
1130 dict_table_skip_corrupt_index(node->
index);
1133 case TRX_UNDO_UPD_EXIST_REC:
1134 err = row_undo_mod_upd_exist_sec(node, thr);
1136 case TRX_UNDO_DEL_MARK_REC:
1137 err = row_undo_mod_del_mark_sec(node, thr);
1139 case TRX_UNDO_UPD_DEL_REC:
1140 err = row_undo_mod_upd_del_sec(node, thr);
1147 if (err == DB_SUCCESS) {
1149 err = row_undo_mod_clust(node, thr);