summaryrefslogtreecommitdiff
path: root/innobase
diff options
context:
space:
mode:
authorunknown <jan@hundin.mysql.fi>2004-08-12 13:38:10 +0300
committerunknown <jan@hundin.mysql.fi>2004-08-12 13:38:10 +0300
commita7bd2db6184ff809ba0da235ab91b22edee3da97 (patch)
treec84eabb3549018fae4e8e4265a3c652b67d34b78 /innobase
parent701f2354f83aa868debf39671059d70f854adb42 (diff)
downloadmariadb-git-a7bd2db6184ff809ba0da235ab91b22edee3da97.tar.gz
This change includes optimization for a lock wait rules and a new behaviour for
a REPLACE command. innobase/lock/lock0lock.c: Gap type locks without LOCK_INSERT_INTENSION flag do not need to wait for anything. This is because different users can have conflicting lock types on gaps. innobase/row/row0ins.c: The manual defines the REPLACE semantics that it is either an INSERT or DELETE(s) for duplicate key + INSERT. Therefore, we take X-lock for duplicates.
Diffstat (limited to 'innobase')
-rw-r--r--innobase/lock/lock0lock.c36
-rw-r--r--innobase/row/row0ins.c63
2 files changed, 47 insertions, 52 deletions
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c
index 2ace0822a82..2d326f7392f 100644
--- a/innobase/lock/lock0lock.c
+++ b/innobase/lock/lock0lock.c
@@ -758,10 +758,10 @@ lock_rec_has_to_wait(
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 */
+ 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);
@@ -773,15 +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 (( lock_is_on_supremum || (type_mode & LOCK_GAP))
+ && !(type_mode & LOCK_INSERT_INTENTION)) {
+ /* Gap type locks without LOCK_INSERT_INTENTION flag
+ do not need to wait for anything. This is because different
+ users can have conflicting lock types on gaps. */
+
+ 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
@@ -842,9 +842,12 @@ lock_has_to_wait(
if (lock_get_type(lock1) == LOCK_REC) {
ut_ad(lock_get_type(lock2) == LOCK_REC);
-
+ /* If this lock request is for a supremum record
+ then the second bit on the lock bitmap is set */
+
return(lock_rec_has_to_wait(lock1->trx,
- lock1->type_mode, lock2,(ibool)lock_rec_get_nth_bit(lock1,1)));
+ lock1->type_mode, lock2,
+ lock_rec_get_nth_bit(lock1,1)));
}
return(TRUE);
@@ -1433,7 +1436,8 @@ lock_rec_other_has_conflicting(
lock = lock_rec_get_first(rec);
while (lock) {
- if (lock_rec_has_to_wait(trx, mode, lock, (ibool)page_rec_is_supremum(rec))) {
+ if (lock_rec_has_to_wait(trx, mode, lock,
+ page_rec_is_supremum(rec))) {
return(lock);
}
diff --git a/innobase/row/row0ins.c b/innobase/row/row0ins.c
index 58ef7d1685c..611ffbcffca 100644
--- a/innobase/row/row0ins.c
+++ b/innobase/row/row0ins.c
@@ -1029,7 +1029,7 @@ records */
static
ulint
row_ins_set_exclusive_rec_lock(
-/*========================*/
+/*============================*/
/* out: DB_SUCCESS or error code */
ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP type lock */
@@ -1517,30 +1517,25 @@ row_ins_scan_sec_index_for_duplicate(
/* Try to place a lock on the index record */
- /* 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.
- */
-
- trx = thr_get_trx(thr);*/* Get Transaction */
-
- /* Is the first word in MySQL query REPLACE ? */
-
- ut_ad(trx)
+ trx = thr_get_trx(thr);
+ ut_ad(trx);
dict_accept(*trx->mysql_query_str, "REPLACE", &success);
- if (success) {
+ if (success) {
- err = row_ins_set_exclusive_rec_lock(
- LOCK_ORDINARY,rec,index,thr);
+ /* 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 */
+
+ err = row_ins_set_exclusive_rec_lock(
+ LOCK_ORDINARY,rec,index,thr);
} else {
- err = row_ins_set_shared_rec_lock(
- LOCK_ORDINARY, rec, index,thr);
+ err = row_ins_set_shared_rec_lock(
+ LOCK_ORDINARY, rec, index,thr);
}
-
if (err != DB_SUCCESS) {
break;
@@ -1640,25 +1635,21 @@ row_ins_duplicate_error_in_clust(
sure that in roll-forward we get the same duplicate
errors as in original execution */
- /* 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.
- */
+ dict_accept(*trx->mysql_query_str, "REPLACE", &success);
-
- /* Is the first word in MySQL query REPLACE ? */
+ if (success) {
- dict_accept(*trx->mysql_query_str, "REPLACE", &success);
-
- if (success) {
-
- err = row_ins_set_exclusive_rec_lock(
- LOCK_REC_NOT_GAP,rec,cursor->index,thr);
- } else {
-
- err = row_ins_set_shared_rec_lock(
- LOCK_REC_NOT_GAP,rec, cursor->index, thr);
+ /* 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 */
+
+ err = row_ins_set_exclusive_rec_lock(
+ LOCK_REC_NOT_GAP,rec,cursor->index,thr);
+ } else {
+
+ err = row_ins_set_shared_rec_lock(
+ LOCK_REC_NOT_GAP,rec, cursor->index, thr);
}
if (err != DB_SUCCESS) {
@@ -2304,4 +2295,4 @@ error_handling:
}
return(thr);
-}
+}