summaryrefslogtreecommitdiff
path: root/innobase/btr
diff options
context:
space:
mode:
authorunknown <aivanov@mysql.com>2005-12-06 22:02:40 +0300
committerunknown <aivanov@mysql.com>2005-12-06 22:02:40 +0300
commitb83c29766c916c67194c56d12f0b4542402e1e85 (patch)
tree12215ce7c080a1a2ab6d1de62d6cb0dd7957a223 /innobase/btr
parentc9bf8e28a86c6eec53bb20d657e667c5fe1dbe88 (diff)
downloadmariadb-git-b83c29766c916c67194c56d12f0b4542402e1e85.tar.gz
Fix BUG#14747: "Race condition can cause btr_search_drop_page_hash_index()
to crash". Changes from snapshot innodb-5.0-ss52. Note that buf_block_t::index should be protected by btr_search_latch or an s-latch or x-latch on the index page. btr_search_drop_page_hash_index(): Read block->index while holding btr_search_latch and use the cached value in the loop. Remove some redundant assertions. Also fix 13778. When FOREIGN_KEY_CHECKS=0 we still need to check that datatypes between foreign key references are compatible. Also added test cases to 9802. innobase/btr/btr0sea.c: Changes from innodb-5.0-ss52 innobase/dict/dict0dict.c: Changes from innodb-5.0-ss52 innobase/dict/dict0load.c: Changes from innodb-5.0-ss52 innobase/include/buf0buf.h: Changes from innodb-5.0-ss52 innobase/include/dict0dict.h: Changes from innodb-5.0-ss52 innobase/include/dict0load.h: Changes from innodb-5.0-ss52 innobase/include/rem0cmp.h: Changes from innodb-5.0-ss52 innobase/rem/rem0cmp.c: Changes from innodb-5.0-ss52 innobase/row/row0mysql.c: Changes from innodb-5.0-ss52 mysql-test/r/innodb.result: Changes from innodb-5.0-ss52 mysql-test/t/innodb.test: Changes from innodb-5.0-ss52 sql/ha_innodb.cc: Changes from innodb-5.0-ss52 sql/ha_innodb.h: Changes from innodb-5.0-ss52
Diffstat (limited to 'innobase/btr')
-rw-r--r--innobase/btr/btr0sea.c28
1 files changed, 10 insertions, 18 deletions
diff --git a/innobase/btr/btr0sea.c b/innobase/btr/btr0sea.c
index 7a4e92a672a..9b1e93fe700 100644
--- a/innobase/btr/btr0sea.c
+++ b/innobase/btr/btr0sea.c
@@ -904,6 +904,7 @@ btr_search_drop_page_hash_index(
ulint* folds;
ulint i;
mem_heap_t* heap;
+ dict_index_t* index;
ulint* offsets;
#ifdef UNIV_SYNC_DEBUG
@@ -932,11 +933,16 @@ btr_search_drop_page_hash_index(
n_fields = block->curr_n_fields;
n_bytes = block->curr_n_bytes;
+ index = block->index;
- ut_a(n_fields + n_bytes > 0);
+ /* NOTE: The fields of block must not be accessed after
+ releasing btr_search_latch, as the index page might only
+ be s-latched! */
rw_lock_s_unlock(&btr_search_latch);
+ ut_a(n_fields + n_bytes > 0);
+
n_recs = page_get_n_recs(page);
/* Calculate and cache fold values into an array for fast deletion
@@ -949,14 +955,6 @@ btr_search_drop_page_hash_index(
rec = page_get_infimum_rec(page);
rec = page_rec_get_next(rec);
- if (!page_rec_is_supremum(rec)) {
- ut_a(n_fields <= rec_get_n_fields(rec, block->index));
-
- if (n_bytes > 0) {
- ut_a(n_fields < rec_get_n_fields(rec, block->index));
- }
- }
-
tree_id = btr_page_get_index_id(page);
prev_fold = 0;
@@ -964,18 +962,12 @@ btr_search_drop_page_hash_index(
heap = NULL;
offsets = NULL;
- if (block->index == NULL) {
-
- mem_analyze_corruption((byte*)block);
-
- ut_a(block->index != NULL);
- }
-
while (!page_rec_is_supremum(rec)) {
/* FIXME: in a mixed tree, not all records may have enough
ordering fields: */
- offsets = rec_get_offsets(rec, block->index,
- offsets, n_fields + (n_bytes > 0), &heap);
+ offsets = rec_get_offsets(rec, index, offsets,
+ n_fields + (n_bytes > 0), &heap);
+ ut_a(rec_offs_n_fields(offsets) == n_fields + (n_bytes > 0));
fold = rec_fold(rec, offsets, n_fields, n_bytes, tree_id);
if (fold == prev_fold && prev_fold != 0) {