mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge a change from mysql-5.1-innodb:
------------------------------------------------------------ revno: 3488 revision-id: marko.makela@oracle.com-20100601103738-upm8awahesmeh9dr parent: vasil.dimov@oracle.com-20100531163540-9fu3prbn2asqwdi5 committer: Marko Mäkelä <marko.makela@oracle.com> branch nick: 5.1-innodb timestamp: Tue 2010-06-01 13:37:38 +0300 message: Bug#53812: assert row/row0umod.c line 660 in txn rollback after crash recovery row_undo_mod_upd_exist_sec(): Tolerate a failure to build the index entry for a DYNAMIC or COMPRESSED table during crash recovery.
This commit is contained in:
parent
c0dd84217c
commit
0902cd6bdd
1 changed files with 47 additions and 17 deletions
|
@ -682,24 +682,55 @@ row_undo_mod_upd_exist_sec(
|
|||
/* Build the newest version of the index entry */
|
||||
entry = row_build_index_entry(node->row, node->ext,
|
||||
index, heap);
|
||||
ut_a(entry);
|
||||
/* NOTE that if we updated the fields of a
|
||||
delete-marked secondary index record so that
|
||||
alphabetically they stayed the same, e.g.,
|
||||
'abc' -> 'aBc', we cannot return to the original
|
||||
values because we do not know them. But this should
|
||||
not cause problems because in row0sel.c, in queries
|
||||
we always retrieve the clustered index record or an
|
||||
earlier version of it, if the secondary index record
|
||||
through which we do the search is delete-marked. */
|
||||
if (UNIV_UNLIKELY(!entry)) {
|
||||
/* The server must have crashed in
|
||||
row_upd_clust_rec_by_insert(), in
|
||||
row_ins_index_entry_low() before
|
||||
btr_store_big_rec_extern_fields()
|
||||
has written the externally stored columns
|
||||
(BLOBs) of the new clustered index entry. */
|
||||
|
||||
err = row_undo_mod_del_mark_or_remove_sec(node, thr,
|
||||
index,
|
||||
entry);
|
||||
if (err != DB_SUCCESS) {
|
||||
mem_heap_free(heap);
|
||||
/* The table must be in DYNAMIC or COMPRESSED
|
||||
format. REDUNDANT and COMPACT formats
|
||||
store a local 768-byte prefix of each
|
||||
externally stored column. */
|
||||
ut_a(dict_table_get_format(index->table)
|
||||
>= DICT_TF_FORMAT_ZIP);
|
||||
|
||||
return(err);
|
||||
/* This is only legitimate when
|
||||
rolling back an incomplete transaction
|
||||
after crash recovery. */
|
||||
ut_a(thr_get_trx(thr)->is_recovered);
|
||||
|
||||
/* The server must have crashed before
|
||||
completing the insert of the new
|
||||
clustered index entry and before
|
||||
inserting to the secondary indexes.
|
||||
Because node->row was not yet written
|
||||
to this index, we can ignore it. But
|
||||
we must restore node->undo_row. */
|
||||
} else {
|
||||
/* NOTE that if we updated the fields of a
|
||||
delete-marked secondary index record so that
|
||||
alphabetically they stayed the same, e.g.,
|
||||
'abc' -> 'aBc', we cannot return to the
|
||||
original values because we do not know them.
|
||||
But this should not cause problems because
|
||||
in row0sel.c, in queries we always retrieve
|
||||
the clustered index record or an earlier
|
||||
version of it, if the secondary index record
|
||||
through which we do the search is
|
||||
delete-marked. */
|
||||
|
||||
err = row_undo_mod_del_mark_or_remove_sec(
|
||||
node, thr, index, entry);
|
||||
if (err != DB_SUCCESS) {
|
||||
mem_heap_free(heap);
|
||||
|
||||
return(err);
|
||||
}
|
||||
|
||||
mem_heap_empty(heap);
|
||||
}
|
||||
|
||||
/* We may have to update the delete mark in the
|
||||
|
@ -708,7 +739,6 @@ row_undo_mod_upd_exist_sec(
|
|||
the secondary index record if we updated its fields
|
||||
but alphabetically they stayed the same, e.g.,
|
||||
'abc' -> 'aBc'. */
|
||||
mem_heap_empty(heap);
|
||||
entry = row_build_index_entry(node->undo_row,
|
||||
node->undo_ext,
|
||||
index, heap);
|
||||
|
|
Loading…
Reference in a new issue