summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2003-01-13 15:52:39 +0200
committerunknown <heikki@hundin.mysql.fi>2003-01-13 15:52:39 +0200
commitd0551ec55be01abbefdb244daf8dc074506276f9 (patch)
tree86b36cbd88f1b66a7c790eb9c632247d03023c72
parenteaebef2ab64b65a275c6ddeb5864326d2e3b0571 (diff)
downloadmariadb-git-d0551ec55be01abbefdb244daf8dc074506276f9.tar.gz
btr0cur.h, btr0btr.h, btr0btr.c, btr0cur.c, row0purge.c:
Fix a hang associated with an index tree of height 1 and purging of BLOB fields from it innobase/row/row0purge.c: Fix a hang associated with an index tree of height 1 and purging of BLOB fields from it innobase/btr/btr0cur.c: Fix a hang associated with an index tree of height 1 and purging of BLOB fields from it innobase/btr/btr0btr.c: Fix a hang associated with an index tree of height 1 and purging of BLOB fields from it innobase/include/btr0btr.h: Fix a hang associated with an index tree of height 1 and purging of BLOB fields from it innobase/include/btr0cur.h: Fix a hang associated with an index tree of height 1 and purging of BLOB fields from it
-rw-r--r--innobase/btr/btr0btr.c7
-rw-r--r--innobase/btr/btr0cur.c10
-rw-r--r--innobase/include/btr0btr.h9
-rw-r--r--innobase/include/btr0cur.h8
-rw-r--r--innobase/row/row0purge.c11
5 files changed, 36 insertions, 9 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index a1665aefab7..51c164b7cef 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -135,7 +135,7 @@ btr_page_insert_fits(
/******************************************************************
Gets the root node of a tree and x-latches it. */
-static
+
page_t*
btr_root_get(
/*=========*/
@@ -146,9 +146,6 @@ btr_root_get(
ulint space;
ulint root_page_no;
page_t* root;
-
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_X_LOCK)
- || mtr_memo_contains(mtr, dict_tree_get_lock(tree), MTR_MEMO_S_LOCK));
space = dict_tree_get_space(tree);
root_page_no = dict_tree_get_page(tree);
@@ -334,8 +331,6 @@ btr_page_alloc(
page_t* new_page;
ulint new_page_no;
- ut_ad(mtr_memo_contains(mtr, dict_tree_get_lock(tree),
- MTR_MEMO_X_LOCK));
if (tree->type & DICT_IBUF) {
return(btr_page_alloc_for_ibuf(tree, mtr));
diff --git a/innobase/btr/btr0cur.c b/innobase/btr/btr0cur.c
index 24f0447d55d..df24689a422 100644
--- a/innobase/btr/btr0cur.c
+++ b/innobase/btr/btr0cur.c
@@ -3180,7 +3180,7 @@ btr_store_big_rec_extern_fields(
ut_ad(mtr_memo_contains(local_mtr, dict_tree_get_lock(index->tree),
MTR_MEMO_X_LOCK));
- ut_ad(mtr_memo_contains(local_mtr, buf_block_align(data),
+ ut_ad(mtr_memo_contains(local_mtr, buf_block_align(rec),
MTR_MEMO_PAGE_X_FIX));
ut_a(index->type & DICT_CLUSTERED);
@@ -3315,7 +3315,13 @@ void
btr_free_externally_stored_field(
/*=============================*/
dict_index_t* index, /* in: index of the data, the index
- tree MUST be X-latched */
+ tree MUST be X-latched; if the tree
+ height is 1, then also the root page
+ must be X-latched! (this is relevant
+ in the case this function is called
+ from purge where 'data' is located on
+ an undo log page, not an index
+ page) */
byte* data, /* in: internally stored data
+ reference to the externally
stored part */
diff --git a/innobase/include/btr0btr.h b/innobase/include/btr0btr.h
index 3cd44ab5175..8606fcd2a5c 100644
--- a/innobase/include/btr0btr.h
+++ b/innobase/include/btr0btr.h
@@ -56,6 +56,15 @@ insert buffer to speed up inserts */
#define BTR_IGNORE_SEC_UNIQUE 2048
/******************************************************************
+Gets the root node of a tree and x-latches it. */
+
+page_t*
+btr_root_get(
+/*=========*/
+ /* out: root page, x-latched */
+ dict_tree_t* tree, /* in: index tree */
+ mtr_t* mtr); /* in: mtr */
+/******************************************************************
Gets a buffer page and declares its latching order level. */
UNIV_INLINE
page_t*
diff --git a/innobase/include/btr0cur.h b/innobase/include/btr0cur.h
index 7039ceba245..1d17c0e952d 100644
--- a/innobase/include/btr0cur.h
+++ b/innobase/include/btr0cur.h
@@ -507,7 +507,13 @@ void
btr_free_externally_stored_field(
/*=============================*/
dict_index_t* index, /* in: index of the data, the index
- tree MUST be X-latched */
+ tree MUST be X-latched; if the tree
+ height is 1, then also the root page
+ must be X-latched! (this is relevant
+ in the case this function is called
+ from purge where 'data' is located on
+ an undo log page, not an index
+ page) */
byte* data, /* in: internally stored data
+ reference to the externally
stored part */
diff --git a/innobase/row/row0purge.c b/innobase/row/row0purge.c
index b64003f22d4..104d71eda2d 100644
--- a/innobase/row/row0purge.c
+++ b/innobase/row/row0purge.c
@@ -429,7 +429,18 @@ skip_secondaries:
index = dict_table_get_first_index(node->table);
mtr_x_lock(dict_tree_get_lock(index->tree), &mtr);
+
+ /* NOTE: we must also acquire an X-latch to the
+ root page of the tree. We will need it when we
+ free pages from the tree. If the tree is of height 1,
+ the tree X-latch does NOT protect the root page,
+ because it is also a leaf page. Since we will have a
+ latch on an undo log page, we would break the
+ latching order if we would only later latch the
+ root page of such a tree! */
+ btr_root_get(index->tree, &mtr);
+
/* We assume in purge of externally stored fields
that the space id of the undo log record is 0! */