Commit 775dbed9 authored by Annamalai Gurusami's avatar Annamalai Gurusami

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
parent 09f18a7d
/*****************************************************************************
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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment