diff options
author | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2013-03-06 11:49:57 +0530 |
---|---|---|
committer | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2013-03-06 11:49:57 +0530 |
commit | 775dbed9d0928a614fb97e69c6ffda749f692845 (patch) | |
tree | 5c68489461a3b847631d9757943f62b61ceeba87 | |
parent | 09f18a7d82316ff2cfbc28cacb4bd1ae35ab7092 (diff) | |
download | mariadb-git-775dbed9d0928a614fb97e69c6ffda749f692845.tar.gz |
Bug #16133801 UNEXPLAINABLE INNODB UNIQUE INDEX LOCKS ON DELETE +
INSERT WITH SAME VALUES
Problem:
When a transaction is in READ COMMITTED isolation level, gap locks are still
taken in the secondary index, when row is inserted. This happens when the
secondary index is scanned for duplicate.
The function row_ins_scan_sec_index_for_duplicate() always calls the
function row_ins_set_shared_rec_lock() with LOCK_ORDINARY irrespective of
the transaction isolation level.
Solution:
The function row_ins_scan_sec_index_for_duplicate() calls the
function row_ins_set_shared_rec_lock() with LOCK_ORDINARY or
LOCK_REC_NOT_GAP based on the transaction isolation level.
rb://2035 approved by Krunal and Marko
-rw-r--r-- | storage/innobase/row/row0ins.c | 19 |
1 files changed, 14 insertions, 5 deletions
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 21afa9eff0d..8312ef38311 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -1698,6 +1698,7 @@ row_ins_scan_sec_index_for_duplicate( do { const rec_t* rec = btr_pcur_get_rec(&pcur); const buf_block_t* block = btr_pcur_get_block(&pcur); + ulint lock_type; if (page_rec_is_infimum(rec)) { @@ -1707,6 +1708,16 @@ row_ins_scan_sec_index_for_duplicate( offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap); + /* If the transaction isolation level is no stronger than + READ COMMITTED, then avoid gap locks. */ + if (!page_rec_is_supremum(rec) + && thr_get_trx(thr)->isolation_level + <= TRX_ISO_READ_COMMITTED) { + lock_type = LOCK_REC_NOT_GAP; + } else { + lock_type = LOCK_ORDINARY; + } + if (allow_duplicates) { /* If the SQL-query will update or replace @@ -1715,13 +1726,11 @@ row_ins_scan_sec_index_for_duplicate( INSERT ON DUPLICATE KEY UPDATE). */ err = row_ins_set_exclusive_rec_lock( - LOCK_ORDINARY, block, - rec, index, offsets, thr); + lock_type, block, rec, index, offsets, thr); } else { err = row_ins_set_shared_rec_lock( - LOCK_ORDINARY, block, - rec, index, offsets, thr); + lock_type, block, rec, index, offsets, thr); } switch (err) { |