Fixed a bug: deadlock without any locking, simple select and update (Bug #7975).
This commit is contained in:
parent
459fa7f1f9
commit
8fc13ecc97
@ -1055,3 +1055,4 @@ vio/viotest-ssl
|
|||||||
include/mysqld_ername.h
|
include/mysqld_ername.h
|
||||||
include/mysqld_error.h
|
include/mysqld_error.h
|
||||||
include/sql_state.h
|
include/sql_state.h
|
||||||
|
innobase/row/row0index.c
|
||||||
|
@ -51,14 +51,19 @@ innobase_invalidate_query_cache(
|
|||||||
chars count */
|
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.
|
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
|
NOTE that /mysql/innobase/row/row0ins.c must contain the
|
||||||
prototype for this function ! */
|
prototype for this function ! */
|
||||||
|
|
||||||
ibool
|
ibool
|
||||||
innobase_query_is_replace(void);
|
innobase_query_is_update(void);
|
||||||
/*===========================*/
|
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
Creates an insert node struct. */
|
Creates an insert node struct. */
|
||||||
@ -1597,12 +1602,12 @@ 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 (innobase_query_is_replace()) {
|
if (innobase_query_is_update()) {
|
||||||
|
|
||||||
/* The manual defines the REPLACE semantics that it
|
/* If the SQL-query will update or replace
|
||||||
is either an INSERT or DELETE(s) for duplicate key
|
duplicate key we will take X-lock for
|
||||||
+ INSERT. Therefore, we should take X-lock for
|
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
|
||||||
duplicates */
|
INSERT ON DUPLICATE KEY UPDATE). */
|
||||||
|
|
||||||
err = row_ins_set_exclusive_rec_lock(LOCK_ORDINARY,
|
err = row_ins_set_exclusive_rec_lock(LOCK_ORDINARY,
|
||||||
rec, index, offsets, thr);
|
rec, index, offsets, thr);
|
||||||
@ -1720,12 +1725,12 @@ row_ins_duplicate_error_in_clust(
|
|||||||
sure that in roll-forward we get the same duplicate
|
sure that in roll-forward we get the same duplicate
|
||||||
errors as in original execution */
|
errors as in original execution */
|
||||||
|
|
||||||
if (innobase_query_is_replace()) {
|
if (innobase_query_is_update()) {
|
||||||
|
|
||||||
/* The manual defines the REPLACE semantics
|
/* If the SQL-query will update or replace
|
||||||
that it is either an INSERT or DELETE(s)
|
duplicate key we will take X-lock for
|
||||||
for duplicate key + INSERT. Therefore, we
|
duplicates ( REPLACE, LOAD DATAFILE REPLACE,
|
||||||
should take X-lock for duplicates */
|
INSERT ON DUPLICATE KEY UPDATE). */
|
||||||
|
|
||||||
err = row_ins_set_exclusive_rec_lock(
|
err = row_ins_set_exclusive_rec_lock(
|
||||||
LOCK_REC_NOT_GAP,rec,cursor->index,
|
LOCK_REC_NOT_GAP,rec,cursor->index,
|
||||||
@ -1759,12 +1764,12 @@ row_ins_duplicate_error_in_clust(
|
|||||||
offsets = rec_get_offsets(rec, cursor->index, offsets,
|
offsets = rec_get_offsets(rec, cursor->index, offsets,
|
||||||
ULINT_UNDEFINED, &heap);
|
ULINT_UNDEFINED, &heap);
|
||||||
|
|
||||||
/* The manual defines the REPLACE semantics that it
|
if (innobase_query_is_update()) {
|
||||||
is either an INSERT or DELETE(s) for duplicate key
|
|
||||||
+ INSERT. Therefore, we should take X-lock for
|
|
||||||
duplicates. */
|
|
||||||
|
|
||||||
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(
|
err = row_ins_set_exclusive_rec_lock(
|
||||||
LOCK_REC_NOT_GAP, rec,
|
LOCK_REC_NOT_GAP, rec,
|
||||||
|
@ -6142,13 +6142,19 @@ innobase_get_at_most_n_mbchars(
|
|||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
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.
|
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
|
NOTE that /mysql/innobase/row/row0ins.c must contain the
|
||||||
prototype for this function ! */
|
prototype for this function ! */
|
||||||
|
|
||||||
ibool
|
ibool
|
||||||
innobase_query_is_replace(void)
|
innobase_query_is_update(void)
|
||||||
/*===========================*/
|
/*===========================*/
|
||||||
{
|
{
|
||||||
THD* thd;
|
THD* thd;
|
||||||
@ -6160,9 +6166,14 @@ innobase_query_is_replace(void)
|
|||||||
( thd->lex->sql_command == SQLCOM_LOAD &&
|
( thd->lex->sql_command == SQLCOM_LOAD &&
|
||||||
thd->lex->duplicates == DUP_REPLACE )) {
|
thd->lex->duplicates == DUP_REPLACE )) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( thd->lex->sql_command == SQLCOM_INSERT &&
|
||||||
|
thd->lex->duplicates == DUP_UPDATE ) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user