Commit 0902cd6b authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent c0dd8421
......@@ -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. */
err = row_undo_mod_del_mark_or_remove_sec(node, thr,
index,
entry);
if (err != DB_SUCCESS) {
mem_heap_free(heap);
return(err);
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. */
/* 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);
/* 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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment