mirror of
https://github.com/MariaDB/server.git
synced 2026-04-26 18:25:30 +02:00
Fixed a bug: deadlock without any locking, simple select and update (Bug #7975).
Backported from 5.0.3. innobase/row/row0ins.c: If the SQL-query will update or replace duplicate records we take X-lock for duplicate records. sql/ha_innodb.cc: INSERT ON DUPLICATE KEY UPDATE will also update duplicate records and we should take X-lock in this case for duplicate records.
This commit is contained in:
parent
b51f70b81e
commit
56ea770272
2 changed files with 38 additions and 22 deletions
|
|
@ -51,14 +51,19 @@ innobase_invalidate_query_cache(
|
|||
chars count */
|
||||
|
||||
/**********************************************************************
|
||||
This function returns true if SQL-query in the current thread
|
||||
This function returns true if
|
||||
|
||||
1) SQL-query in the current thread
|
||||
is either REPLACE or LOAD DATA INFILE REPLACE.
|
||||
|
||||
2) SQL-query in the current thread
|
||||
is INSERT ON DUPLICATE KEY UPDATE.
|
||||
|
||||
NOTE that /mysql/innobase/row/row0ins.c must contain the
|
||||
prototype for this function ! */
|
||||
|
||||
ibool
|
||||
innobase_query_is_replace(void);
|
||||
/*===========================*/
|
||||
innobase_query_is_update(void);
|
||||
|
||||
/*************************************************************************
|
||||
Creates an insert node struct. */
|
||||
|
|
@ -1562,12 +1567,12 @@ row_ins_scan_sec_index_for_duplicate(
|
|||
trx = thr_get_trx(thr);
|
||||
ut_ad(trx);
|
||||
|
||||
if (innobase_query_is_replace()) {
|
||||
if (innobase_query_is_update()) {
|
||||
|
||||
/* The manual defines the REPLACE semantics that it
|
||||
is either an INSERT or DELETE(s) for duplicate key
|
||||
+ INSERT. Therefore, we should take X-lock for
|
||||
duplicates */
|
||||
/* If the SQL-query will update or replace
|
||||
duplicate key we will take X-lock for
|
||||
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
|
||||
INSERT ON DUPLICATE KEY UPDATE). */
|
||||
|
||||
err = row_ins_set_exclusive_rec_lock(
|
||||
LOCK_ORDINARY,rec,index,thr);
|
||||
|
|
@ -1675,12 +1680,12 @@ row_ins_duplicate_error_in_clust(
|
|||
sure that in roll-forward we get the same duplicate
|
||||
errors as in original execution */
|
||||
|
||||
if (innobase_query_is_replace()) {
|
||||
if (innobase_query_is_update()) {
|
||||
|
||||
/* The manual defines the REPLACE semantics
|
||||
that it is either an INSERT or DELETE(s)
|
||||
for duplicate key + INSERT. Therefore, we
|
||||
should take X-lock for duplicates */
|
||||
/* If the SQL-query will update or replace
|
||||
duplicate key we will take X-lock for
|
||||
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
|
||||
INSERT ON DUPLICATE KEY UPDATE). */
|
||||
|
||||
err = row_ins_set_exclusive_rec_lock(
|
||||
LOCK_REC_NOT_GAP,rec,cursor->index,
|
||||
|
|
@ -1713,12 +1718,12 @@ row_ins_duplicate_error_in_clust(
|
|||
if (rec != page_get_supremum_rec(page)) {
|
||||
|
||||
|
||||
/* The manual defines the REPLACE semantics that it
|
||||
is either an INSERT or DELETE(s) for duplicate key
|
||||
+ INSERT. Therefore, we should take X-lock for
|
||||
duplicates. */
|
||||
if (innobase_query_is_update()) {
|
||||
|
||||
if (innobase_query_is_replace()) {
|
||||
/* If the SQL-query will update or replace
|
||||
duplicate key we will take X-lock for
|
||||
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
|
||||
INSERT ON DUPLICATE KEY UPDATE). */
|
||||
|
||||
err = row_ins_set_exclusive_rec_lock(
|
||||
LOCK_REC_NOT_GAP,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue