List:Commits« Previous MessageNext Message »
From:marko.makela Date:June 1 2010 11:19am
Subject:bzr push into mysql-5.1-innodb branch (marko.makela:3487 to 3488) Bug#53812
View as plain text  
 3488 Marko Mäkelä	2010-06-01
      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.

    modified:
      storage/innodb_plugin/row/row0umod.c
 3487 Vasil Dimov	2010-05-31
      Merge a change from mysql-trunk-innodb:
      
        ------------------------------------------------------------
        revno: 3127
        revision-id: vasil.dimov@stripped1
        parent: vasil.dimov@strippedpjwl4rbgfpfj13c
        committer: Vasil Dimov <vasil.dimov@stripped>
        branch nick: mysql-trunk-innodb
        timestamp: Mon 2010-05-31 18:23:41 +0300
        message:
          Fix Bug #53947 InnoDB: Assertion failure in thread 4224 in file .\sync\sync0sync.c line 324
          
          Destroy the rw-lock object before freeing the memory it is occupying.
          If we do not do this, then the mutex that is contained in the rw-lock
          object btr_search_latch_temp->mutex gets "freed" and subsequently
          mutex_free() from sync_close() hits a mutex whose memory has been
          freed and crashes.
          
          Approved by:	Heikki (via IRC)
          Discussed with:	Calvin

    modified:
      storage/innodb_plugin/btr/btr0sea.c
=== modified file 'storage/innodb_plugin/row/row0umod.c'
--- a/storage/innodb_plugin/row/row0umod.c	revid:vasil.dimov@stripped3540-9fu3prbn2asqwdi5
+++ b/storage/innodb_plugin/row/row0umod.c	revid:marko.makela@strippedawahesmeh9dr
@@ -657,24 +657,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);
+			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. */
 
-				return(err);
+				/* 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
@@ -683,7 +714,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);

Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20100601103738-upm8awahesmeh9dr.bundle
Thread
bzr push into mysql-5.1-innodb branch (marko.makela:3487 to 3488) Bug#53812marko.makela1 Jun