58
58
some of its fields were changed. Now, it is possible that the delete marked
59
59
version has become obsolete at the time the undo is started. */
61
/*************************************************************************
62
IMPORTANT NOTE: Any operation that generates redo MUST check that there
63
is enough space in the redo log before for that operation. This is
64
done by calling log_free_check(). The reason for checking the
65
availability of the redo log space before the start of the operation is
66
that we MUST not hold any synchonization objects when performing the
68
If you make a change in this module make sure that no codepath is
69
introduced where a call to log_free_check() is bypassed. */
71
61
/***********************************************************//**
72
62
Checks if also the previous version of the clustered index record was
73
63
modified or inserted by the same transaction, and its undo number is such
74
64
that it should be undone in the same rollback.
75
65
@return TRUE if also previous modify or insert of this row should be undone */
78
68
row_undo_mod_undo_also_prev_vers(
79
69
/*=============================*/
160
145
/***********************************************************//**
161
146
Removes a clustered index record after undo if possible.
162
This is attempted when the record was inserted by updating a
163
delete-marked record and there no longer exist transactions
164
that would see the delete-marked record. In other words, we
165
roll back the insert by purging the record.
166
147
@return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */
169
150
row_undo_mod_remove_clust_low(
170
151
/*==========================*/
171
152
undo_node_t* node, /*!< in: row undo node */
172
que_thr_t* thr, /*!< in: query thread */
153
que_thr_t* thr __attribute__((unused)), /*!< in: query thread */
173
154
mtr_t* mtr, /*!< in: mtr */
174
155
ulint mode) /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
211
191
ut_ad(mode == BTR_MODIFY_TREE);
213
/* This operation is analogous to purge, we can free also
214
inherited externally stored fields */
193
/* Note that since this operation is analogous to purge,
194
we can free also inherited externally stored fields:
195
hence the RB_NONE in the call below */
216
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
218
? RB_RECOVERY_PURGE_REC
197
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, RB_NONE, mtr);
221
199
/* The delete operation may fail if we have little
222
200
file space left: TODO: easiest to crash the database
331
307
ulint mode) /*!< in: latch mode BTR_MODIFY_LEAF or
332
308
BTR_MODIFY_TREE */
341
enum row_search_result search_result;
343
319
log_free_check();
322
found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
346
324
btr_cur = btr_pcur_get_btr_cur(&pcur);
348
ut_ad(mode == BTR_MODIFY_TREE || mode == BTR_MODIFY_LEAF);
350
search_result = row_search_index_entry(index, entry, mode,
353
switch (UNIV_EXPECT(search_result, ROW_FOUND)) {
355
327
/* In crash recovery, the secondary index record may
356
328
be missing if the UPDATE did not have time to insert
357
329
the secondary index records before the crash. When we
362
334
before it has inserted all updated secondary index
363
335
records, then the undo will not find those records. */
370
case ROW_NOT_DELETED_REF:
371
/* These are invalid outcomes, because the mode passed
372
to row_search_index_entry() did not include any of the
373
flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */
337
btr_pcur_close(&pcur);
377
343
/* We should remove the index record if no prior version of the row,
405
371
ut_ad(mode == BTR_MODIFY_TREE);
407
/* No need to distinguish RB_RECOVERY_PURGE here,
408
because we are deleting a secondary index record:
409
the distinction between RB_NORMAL and
410
RB_RECOVERY_PURGE only matters when deleting a
411
record that contains externally stored
373
/* No need to distinguish RB_RECOVERY here, because we
374
are deleting a secondary index record: the distinction
375
between RB_NORMAL and RB_RECOVERY only matters when
376
deleting a record that contains externally stored
413
378
ut_ad(!dict_index_is_clust(index));
414
379
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
475
438
BTR_MODIFY_TREE */
476
439
que_thr_t* thr, /*!< in: query thread */
477
440
dict_index_t* index, /*!< in: index */
478
const dtuple_t* entry) /*!< in: index entry */
441
dtuple_t* entry) /*!< in: index entry */
484
ulint err = DB_SUCCESS;
485
big_rec_t* dummy_big_rec;
487
trx_t* trx = thr_get_trx(thr);
488
enum row_search_result search_result;
446
ulint err = DB_SUCCESS;
447
big_rec_t* dummy_big_rec;
449
trx_t* trx = thr_get_trx(thr);
490
451
/* Ignore indexes that are being created. */
491
452
if (UNIV_UNLIKELY(*index->name == TEMP_INDEX_PREFIX)) {
496
457
log_free_check();
499
ut_ad(mode == BTR_MODIFY_TREE || mode == BTR_MODIFY_LEAF);
501
search_result = row_search_index_entry(index, entry, mode,
504
switch (search_result) {
506
case ROW_NOT_DELETED_REF:
507
/* These are invalid outcomes, because the mode passed
508
to row_search_index_entry() did not include any of the
509
flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */
460
if (UNIV_UNLIKELY(!row_search_index_entry(index, entry,
461
mode, &pcur, &mtr))) {
512
462
fputs("InnoDB: error in sec index entry del undo in\n"
513
463
"InnoDB: ", stderr);
514
464
dict_index_name_print(stderr, trx, index);
524
474
"InnoDB: Submit a detailed bug report"
525
475
" to http://bugs.mysql.com\n", stderr);
528
btr_cur = btr_pcur_get_btr_cur(&pcur);
477
btr_cur_t* btr_cur = btr_pcur_get_btr_cur(&pcur);
529
479
err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG,
530
480
btr_cur, FALSE, thr, &mtr);
531
481
ut_a(err == DB_SUCCESS);
699
648
/* Build the newest version of the index entry */
700
649
entry = row_build_index_entry(node->row, node->ext,
702
if (UNIV_UNLIKELY(!entry)) {
703
/* The server must have crashed in
704
row_upd_clust_rec_by_insert(), in
705
row_ins_index_entry_low() before
706
btr_store_big_rec_extern_fields()
707
has written the externally stored columns
708
(BLOBs) of the new clustered index entry. */
710
/* The table must be in DYNAMIC or COMPRESSED
711
format. REDUNDANT and COMPACT formats
712
store a local 768-byte prefix of each
713
externally stored column. */
714
ut_a(dict_table_get_format(index->table)
715
>= DICT_TF_FORMAT_ZIP);
717
/* This is only legitimate when
718
rolling back an incomplete transaction
719
after crash recovery. */
720
ut_a(thr_get_trx(thr)->is_recovered);
722
/* The server must have crashed before
723
completing the insert of the new
724
clustered index entry and before
725
inserting to the secondary indexes.
726
Because node->row was not yet written
727
to this index, we can ignore it. But
728
we must restore node->undo_row. */
730
/* NOTE that if we updated the fields of a
731
delete-marked secondary index record so that
732
alphabetically they stayed the same, e.g.,
733
'abc' -> 'aBc', we cannot return to the
734
original values because we do not know them.
735
But this should not cause problems because
736
in row0sel.c, in queries we always retrieve
737
the clustered index record or an earlier
738
version of it, if the secondary index record
739
through which we do the search is
742
err = row_undo_mod_del_mark_or_remove_sec(
743
node, thr, index, entry);
744
if (err != DB_SUCCESS) {
750
mem_heap_empty(heap);
652
/* NOTE that if we updated the fields of a
653
delete-marked secondary index record so that
654
alphabetically they stayed the same, e.g.,
655
'abc' -> 'aBc', we cannot return to the original
656
values because we do not know them. But this should
657
not cause problems because in row0sel.c, in queries
658
we always retrieve the clustered index record or an
659
earlier version of it, if the secondary index record
660
through which we do the search is delete-marked. */
662
err = row_undo_mod_del_mark_or_remove_sec(node, thr,
665
if (err != DB_SUCCESS) {
753
671
/* We may have to update the delete mark in the