diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2017-10-02 10:22:42 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2017-10-02 10:38:35 +0300 |
commit | 028d253dd7401fa564bcf817fe81c7034f2512d2 (patch) | |
tree | 9144cfafa4a29b44b4394e45a9af7da83595fc37 /storage/xtradb | |
parent | a47d16907d089a33f95c64361b016009e7a20691 (diff) | |
download | mariadb-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).
Diffstat (limited to 'storage/xtradb')
-rw-r--r-- | storage/xtradb/btr/btr0cur.c | 10 |
1 files changed, 5 insertions, 5 deletions
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); |