summaryrefslogtreecommitdiff
path: root/innobase/lock
diff options
context:
space:
mode:
authorunknown <jan@hundin.mysql.fi>2004-08-11 13:01:30 +0300
committerunknown <jan@hundin.mysql.fi>2004-08-11 13:01:30 +0300
commit11b255796818bda5f271b83d5123aba6b4a0b625 (patch)
tree63cadfc89162ff40d87519543eb9fb079a155625 /innobase/lock
parentce4e83e31deee668b035346729d2a79a5c9521be (diff)
downloadmariadb-git-11b255796818bda5f271b83d5123aba6b4a0b625.tar.gz
Take X-lock for duplicate keys in REPLACE command.
innobase/lock/lock0lock.c: Made change where lock on the supremum record is really a 'gap' type lock and gap type lock do not need to wait if it is not LOCK_INSERT_INTENSION type. innobase/row/row0ins.c: Added fuction row_ins_set_exclusive_rec_lock to set exclusive lock on a record. This function is used for locking possible duplicate key records when user has issued REPLACE-command. Because manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) for duplicate key + INSERT, we take X-lock directly for duplicate records to avoid unnecessary lock upgrades and deadlocks caused by lock upgrades.
Diffstat (limited to 'innobase/lock')
-rw-r--r--innobase/lock/lock0lock.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 92e8f224dea..2ace0822a82 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -755,9 +755,13 @@ lock_rec_has_to_wait(
ulint type_mode,/* in: precise mode of the new lock to set:
LOCK_S or LOCK_X, possibly ORed to
LOCK_GAP or LOCK_REC_NOT_GAP, LOCK_INSERT_INTENTION */
- lock_t* lock2) /* in: another record lock; NOTE that it is assumed
+ lock_t* lock2, /* in: another record lock; NOTE that it is assumed
that this has a lock bit set on the same record as
in the new lock we are setting */
+ ibool lock_is_on_supremum) /* in: TRUE if we are setting the lock
+ on the 'supremum' record of an index page: we know
+ then that the lock request is really for a 'gap' type
+ lock */
{
ut_ad(trx && lock2);
ut_ad(lock_get_type(lock2) == LOCK_REC);
@@ -769,6 +773,15 @@ lock_rec_has_to_wait(
/* We have somewhat complex rules when gap type record locks
cause waits */
+ if( lock_is_on_supremum && !(type_mode & LOCK_INSERT_INTENTION))
+ {
+ /* Lock on the supremum record is really a 'gap' type lock
+ and gap type lock do not need to wait if it
+ is not LOCK_INSERT_INTENSION type lock */
+
+ return(FALSE);
+ }
+
if ((type_mode & LOCK_REC_NOT_GAP)
&& lock_rec_get_gap(lock2)) {
/* Lock on just the record does not need to wait for
@@ -828,9 +841,10 @@ lock_has_to_wait(
lock_get_mode(lock2))) {
if (lock_get_type(lock1) == LOCK_REC) {
ut_ad(lock_get_type(lock2) == LOCK_REC);
-
+
+
return(lock_rec_has_to_wait(lock1->trx,
- lock1->type_mode, lock2));
+ lock1->type_mode, lock2,(ibool)lock_rec_get_nth_bit(lock1,1)));
}
return(TRUE);
@@ -1419,7 +1433,7 @@ lock_rec_other_has_conflicting(
lock = lock_rec_get_first(rec);
while (lock) {
- if (lock_rec_has_to_wait(trx, mode, lock)) {
+ if (lock_rec_has_to_wait(trx, mode, lock, (ibool)page_rec_is_supremum(rec))) {
return(lock);
}