3131 Marko Mäkelä 2010-06-01
Merge a change from mysql-5.1-innodb:
------------------------------------------------------------
revno: 3490
revision-id: marko.makela@stripped751-1uq7bbta5n7ts0qr
parent: marko.makela@oracle.com-20100601120521-q48hk05ne4j1s2o0
committer: Marko Mäkelä <marko.makela@stripped>
branch nick: 5.1-innodb
timestamp: Tue 2010-06-01 15:07:51 +0300
message:
Minor cleanup.
lock_rec_unlock(): Cache first_lock and rewrite while() loops as for().
btr_cur_optimistic_update(): Use common error handling return.
row_create_prebuilt(): Add Valgrind instrumentation.
modified:
storage/innobase/btr/btr0cur.c
storage/innobase/lock/lock0lock.c
storage/innobase/row/row0mysql.c
3130 Marko Mäkelä 2010-06-01
Merge a change from mysql-5.1-innodb:
------------------------------------------------------------
revno: 3488
revision-id: marko.makela@oracle.com-20100601103738-upm8awahesmeh9dr
parent: vasil.dimov@stripped
committer: Marko Mäkelä <marko.makela@stripped>
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.
modified:
storage/innobase/row/row0umod.c
3129 Marko Mäkelä 2010-06-01
Merge from mysql-5.1-innodb:
------------------------------------------------------------
revno: 3478.1.3
revision-id: marko.makela@strippedoyhc1ns
parent: marko.makela@stripped14349-5kaw52sz0yh4szkb
committer: Marko Mäkelä <marko.makela@stripped>
branch nick: 5.1-innodb
timestamp: Tue 2010-05-25 15:37:48 +0300
message:
Suppress bogus Valgrind warnings about buf_buddy_relocate()
accessing uninitialized memory in Valgrind-instrumented builds.
modified:
mysql-test/valgrind.supp
storage/innobase/buf/buf0buddy.c
3128 Marko Mäkelä 2010-06-01
Merge from mysql-5.1-innodb:
------------------------------------------------------------
revno: 3478.1.4
revision-id: marko.makela@stripped525125352-hgafpmqhrrj7pv5i
parent: marko.makela@oracle.com-20100525123748-pmpehbg29oyhc1ns
committer: Marko Mäkelä <marko.makela@stripped>
branch nick: 5.1-innodb
timestamp: Tue 2010-05-25 15:53:52 +0300
message:
row_search_for_mysql(): Add assertions to track down Bug #53627.
modified:
storage/innobase/row/row0sel.c
3127 Vasil Dimov 2010-05-31
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/innobase/btr/btr0sea.c
=== modified file 'mysql-test/valgrind.supp'
--- a/mysql-test/valgrind.supp revid:vasil.dimov@strippedx2d4hma644icamh1
+++ b/mysql-test/valgrind.supp revid:marko.makela@stripped
@@ -740,3 +740,8 @@
fun:pthread_create*
}
+{
+ buf_buddy_relocate peeking (space,page) in potentially free blocks
+ Memcheck:Addr1
+ fun:buf_buddy_relocate
+}
=== modified file 'storage/innobase/btr/btr0cur.c'
--- a/storage/innobase/btr/btr0cur.c revid:vasil.dimov@stripped-20100531152341-x2d4hma644icamh1
+++ b/storage/innobase/btr/btr0cur.c revid:marko.makela@stripped-r8fnhig5m5qnnohz
@@ -2079,9 +2079,8 @@ any_extern:
err = btr_cur_upd_lock_and_undo(flags, cursor, update, cmpl_info,
thr, mtr, &roll_ptr);
if (err != DB_SUCCESS) {
-err_exit:
- mem_heap_free(heap);
- return(err);
+
+ goto err_exit;
}
/* Ok, we may do the replacement. Store on the page infimum the
@@ -2127,9 +2126,10 @@ err_exit:
page_cur_move_to_next(page_cursor);
+ err = DB_SUCCESS;
+err_exit:
mem_heap_free(heap);
-
- return(DB_SUCCESS);
+ return(err);
}
/*************************************************************//**
=== modified file 'storage/innobase/buf/buf0buddy.c'
--- a/storage/innobase/buf/buf0buddy.c revid:vasil.dimov@stripped00531152341-x2d4hma644icamh1
+++ b/storage/innobase/buf/buf0buddy.c revid:marko.makela@stripped8fnhig5m5qnnohz
@@ -446,12 +446,15 @@ buf_buddy_relocate(
pool), so there is nothing wrong about this. The
mach_read_from_4() calls here will only trigger bogus
Valgrind memcheck warnings in UNIV_DEBUG_VALGRIND builds. */
- bpage = buf_page_hash_get(
- buf_pool,
- mach_read_from_4((const byte*) src
- + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID),
- mach_read_from_4((const byte*) src
- + FIL_PAGE_OFFSET));
+ ulint space = mach_read_from_4(
+ (const byte*) src + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
+ ulint page_no = mach_read_from_4(
+ (const byte*) src + FIL_PAGE_OFFSET);
+ /* Suppress Valgrind warnings about conditional jump
+ on uninitialized value. */
+ UNIV_MEM_VALID(&space, sizeof space);
+ UNIV_MEM_VALID(&page_no, sizeof page_no);
+ bpage = buf_page_hash_get(buf_pool, space, page_no);
if (!bpage || bpage->zip.data != src) {
/* The block has probably been freshly
=== modified file 'storage/innobase/lock/lock0lock.c'
--- a/storage/innobase/lock/lock0lock.c revid:vasil.dimov@stripped
+++ b/storage/innobase/lock/lock0lock.c revid:marko.makela@strippedom-20100601120933-r8fnhig5m5qnnohz
@@ -3935,8 +3935,8 @@ lock_rec_unlock(
const rec_t* rec, /*!< in: record */
enum lock_mode lock_mode)/*!< in: LOCK_S or LOCK_X */
{
+ lock_t* first_lock;
lock_t* lock;
- lock_t* release_lock = NULL;
ulint heap_no;
ut_ad(trx && rec);
@@ -3946,48 +3946,40 @@ lock_rec_unlock(
mutex_enter(&kernel_mutex);
- lock = lock_rec_get_first(block, heap_no);
+ first_lock = lock_rec_get_first(block, heap_no);
/* Find the last lock with the same lock_mode and transaction
from the record. */
- while (lock != NULL) {
+ for (lock = first_lock; lock != NULL;
+ lock = lock_rec_get_next(heap_no, lock)) {
if (lock->trx == trx && lock_get_mode(lock) == lock_mode) {
- release_lock = lock;
ut_a(!lock_get_wait(lock));
+ lock_rec_reset_nth_bit(lock, heap_no);
+ goto released;
}
-
- lock = lock_rec_get_next(heap_no, lock);
}
- /* If a record lock is found, release the record lock */
-
- if (UNIV_LIKELY(release_lock != NULL)) {
- lock_rec_reset_nth_bit(release_lock, heap_no);
- } else {
- mutex_exit(&kernel_mutex);
- ut_print_timestamp(stderr);
- fprintf(stderr,
- " InnoDB: Error: unlock row could not"
- " find a %lu mode lock on the record\n",
- (ulong) lock_mode);
+ mutex_exit(&kernel_mutex);
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Error: unlock row could not"
+ " find a %lu mode lock on the record\n",
+ (ulong) lock_mode);
- return;
- }
+ return;
+released:
/* Check if we can now grant waiting lock requests */
- lock = lock_rec_get_first(block, heap_no);
-
- while (lock != NULL) {
+ for (lock = first_lock; lock != NULL;
+ lock = lock_rec_get_next(heap_no, lock)) {
if (lock_get_wait(lock)
&& !lock_rec_has_to_wait_in_queue(lock)) {
/* Grant the lock */
lock_grant(lock);
}
-
- lock = lock_rec_get_next(heap_no, lock);
}
mutex_exit(&kernel_mutex);
=== modified file 'storage/innobase/row/row0mysql.c'
--- a/storage/innobase/row/row0mysql.c revid:vasil.dimov@strippedx2d4hma644icamh1
+++ b/storage/innobase/row/row0mysql.c revid:marko.makela@strippedohz
@@ -625,6 +625,8 @@ row_create_prebuilt(
prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = 99999999;
+ UNIV_MEM_INVALID(&prebuilt->stored_select_lock_type,
+ sizeof prebuilt->stored_select_lock_type);
prebuilt->search_tuple = dtuple_create(
heap, 2 * dict_table_get_n_cols(table));
=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c revid:vasil.dimov@stripped2341-x2d4hma644icamh1
+++ b/storage/innobase/row/row0sel.c revid:marko.makela@strippedqnnohz
@@ -3611,6 +3611,13 @@ shortcut_fails_too_big_rec:
trx->has_search_latch = FALSE;
}
+ ut_ad(prebuilt->sql_stat_start || trx->conc_state == TRX_ACTIVE);
+ ut_ad(trx->conc_state == TRX_NOT_STARTED
+ || trx->conc_state == TRX_ACTIVE);
+ ut_ad(prebuilt->sql_stat_start
+ || prebuilt->select_lock_type != LOCK_NONE
+ || trx->read_view);
+
trx_start_if_not_started(trx);
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
=== modified file 'storage/innobase/row/row0umod.c'
--- a/storage/innobase/row/row0umod.c revid:vasil.dimov@oracle.com-20100531152341-x2d4hma644icamh1
+++ b/storage/innobase/row/row0umod.c revid:marko.makela@stripped0933-r8fnhig5m5qnnohz
@@ -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);
+ 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
@@ -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);
Attachment: [text/bzr-bundle] bzr/marko.makela@oracle.com-20100601120933-r8fnhig5m5qnnohz.bundle
| Thread |
|---|
| • bzr push into mysql-trunk-innodb branch (marko.makela:3127 to 3131) | marko.makela | 1 Jun |