summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnnamalai Gurusami <annamalai.gurusami@oracle.com>2013-03-06 11:49:57 +0530
committerAnnamalai Gurusami <annamalai.gurusami@oracle.com>2013-03-06 11:49:57 +0530
commit775dbed9d0928a614fb97e69c6ffda749f692845 (patch)
tree5c68489461a3b847631d9757943f62b61ceeba87
parent09f18a7d82316ff2cfbc28cacb4bd1ae35ab7092 (diff)
downloadmariadb-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.c19
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) {