summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2017-10-02 10:22:42 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2017-10-02 10:38:35 +0300
commit028d253dd7401fa564bcf817fe81c7034f2512d2 (patch)
tree9144cfafa4a29b44b4394e45a9af7da83595fc37
parenta47d16907d089a33f95c64361b016009e7a20691 (diff)
downloadmariadb-git-028d253dd7401fa564bcf817fe81c7034f2512d2.tar.gz
MDEV-13980 InnoDB fails to discard record lock when discarding an index page
btr_cur_pessimistic_delete(): Discard a possible record lock also in the case when the record was the only one in the page. Failure to do this would corrupt the record lock data structures in a partial rollback (ROLLBACK TO SAVEPOINT or rolling back a row operation due to some error, such as a duplicate key in a unique secondary index).
-rw-r--r--storage/innobase/btr/btr0cur.c10
-rw-r--r--storage/xtradb/btr/btr0cur.c10
2 files changed, 10 insertions, 10 deletions
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index 2c1ab4bffae..e8c467409b2 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -3193,7 +3194,6 @@ btr_cur_pessimistic_delete(
ulint n_reserved;
ibool success;
ibool ret = FALSE;
- ulint level;
mem_heap_t* heap;
ulint* offsets;
@@ -3240,6 +3240,8 @@ btr_cur_pessimistic_delete(
#endif /* UNIV_ZIP_DEBUG */
}
+ lock_update_delete(block, rec);
+
if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
&& UNIV_UNLIKELY(dict_index_get_page(index)
!= buf_block_get_page_no(block))) {
@@ -3255,10 +3257,7 @@ btr_cur_pessimistic_delete(
goto return_after_reservations;
}
- lock_update_delete(block, rec);
- level = btr_page_get_level(page, mtr);
-
- if (level > 0
+ if (!page_is_leaf(page)
&& UNIV_UNLIKELY(rec == page_rec_get_next(
page_get_infimum_rec(page)))) {
@@ -3281,6 +3280,7 @@ btr_cur_pessimistic_delete(
on a page, we have to change the father node pointer
so that it is equal to the new leftmost node pointer
on the page */
+ ulint level = btr_page_get_level(page, mtr);
btr_node_ptr_delete(index, block, mtr);
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index d9c1a2ef7a8..0d015111d81 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2017, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -3376,7 +3377,6 @@ btr_cur_pessimistic_delete(
ulint n_reserved;
ibool success;
ibool ret = FALSE;
- ulint level;
mem_heap_t* heap;
ulint* offsets;
@@ -3425,6 +3425,8 @@ btr_cur_pessimistic_delete(
#endif /* UNIV_ZIP_DEBUG */
}
+ lock_update_delete(block, rec);
+
if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
&& UNIV_UNLIKELY(dict_index_get_page(index)
!= buf_block_get_page_no(block))) {
@@ -3440,10 +3442,7 @@ btr_cur_pessimistic_delete(
goto return_after_reservations;
}
- lock_update_delete(block, rec);
- level = btr_page_get_level(page, mtr);
-
- if (level > 0
+ if (!page_is_leaf(page)
&& UNIV_UNLIKELY(rec == page_rec_get_next(
page_get_infimum_rec(page)))) {
@@ -3466,6 +3465,7 @@ btr_cur_pessimistic_delete(
on a page, we have to change the father node pointer
so that it is equal to the new leftmost node pointer
on the page */
+ ulint level = btr_page_get_level(page, mtr);
btr_node_ptr_delete(index, block, mtr);