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
This commit is contained in:
parent
20bf30c2a6
commit
833c75da1c
@ -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
|
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
|
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 {
|
do {
|
||||||
const rec_t* rec = btr_pcur_get_rec(&pcur);
|
const rec_t* rec = btr_pcur_get_rec(&pcur);
|
||||||
const buf_block_t* block = btr_pcur_get_block(&pcur);
|
const buf_block_t* block = btr_pcur_get_block(&pcur);
|
||||||
|
ulint lock_type;
|
||||||
|
|
||||||
if (page_rec_is_infimum(rec)) {
|
if (page_rec_is_infimum(rec)) {
|
||||||
|
|
||||||
@ -1707,6 +1708,16 @@ row_ins_scan_sec_index_for_duplicate(
|
|||||||
offsets = rec_get_offsets(rec, index, offsets,
|
offsets = rec_get_offsets(rec, index, offsets,
|
||||||
ULINT_UNDEFINED, &heap);
|
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 (allow_duplicates) {
|
||||||
|
|
||||||
/* If the SQL-query will update or replace
|
/* If the SQL-query will update or replace
|
||||||
@ -1715,13 +1726,11 @@ row_ins_scan_sec_index_for_duplicate(
|
|||||||
INSERT ON DUPLICATE KEY UPDATE). */
|
INSERT ON DUPLICATE KEY UPDATE). */
|
||||||
|
|
||||||
err = row_ins_set_exclusive_rec_lock(
|
err = row_ins_set_exclusive_rec_lock(
|
||||||
LOCK_ORDINARY, block,
|
lock_type, block, rec, index, offsets, thr);
|
||||||
rec, index, offsets, thr);
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
err = row_ins_set_shared_rec_lock(
|
err = row_ins_set_shared_rec_lock(
|
||||||
LOCK_ORDINARY, block,
|
lock_type, block, rec, index, offsets, thr);
|
||||||
rec, index, offsets, thr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (err) {
|
switch (err) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user