Commit 38255a2c authored by jan@hundin.mysql.fi's avatar jan@hundin.mysql.fi

This change includes optimization for a lock wait rules and a new behaviour for

a REPLACE command. 
parent d35df170
...@@ -759,9 +759,9 @@ lock_rec_has_to_wait( ...@@ -759,9 +759,9 @@ lock_rec_has_to_wait(
that this has a lock bit set on the same record as that this has a lock bit set on the same record as
in the new lock we are setting */ in the new lock we are setting */
ibool lock_is_on_supremum) /* in: TRUE if we are setting the lock ibool lock_is_on_supremum) /* in: TRUE if we are setting the lock
on the 'supremum' record of an index page: we know on the 'supremum' record of an index
then that the lock request is really for a 'gap' type page: we know then that the lock request
lock */ is really for a 'gap' type lock */
{ {
ut_ad(trx && lock2); ut_ad(trx && lock2);
ut_ad(lock_get_type(lock2) == LOCK_REC); ut_ad(lock_get_type(lock2) == LOCK_REC);
...@@ -773,11 +773,11 @@ lock_rec_has_to_wait( ...@@ -773,11 +773,11 @@ lock_rec_has_to_wait(
/* We have somewhat complex rules when gap type record locks /* We have somewhat complex rules when gap type record locks
cause waits */ cause waits */
if( lock_is_on_supremum && !(type_mode & LOCK_INSERT_INTENTION)) if (( lock_is_on_supremum || (type_mode & LOCK_GAP))
{ && !(type_mode & LOCK_INSERT_INTENTION)) {
/* Lock on the supremum record is really a 'gap' type lock /* Gap type locks without LOCK_INSERT_INTENTION flag
and gap type lock do not need to wait if it do not need to wait for anything. This is because different
is not LOCK_INSERT_INTENSION type lock */ users can have conflicting lock types on gaps. */
return(FALSE); return(FALSE);
} }
...@@ -842,9 +842,12 @@ lock_has_to_wait( ...@@ -842,9 +842,12 @@ lock_has_to_wait(
if (lock_get_type(lock1) == LOCK_REC) { if (lock_get_type(lock1) == LOCK_REC) {
ut_ad(lock_get_type(lock2) == 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, 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); return(TRUE);
...@@ -1433,7 +1436,8 @@ lock_rec_other_has_conflicting( ...@@ -1433,7 +1436,8 @@ lock_rec_other_has_conflicting(
lock = lock_rec_get_first(rec); lock = lock_rec_get_first(rec);
while (lock) { 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); return(lock);
} }
......
...@@ -1029,7 +1029,7 @@ records */ ...@@ -1029,7 +1029,7 @@ records */
static static
ulint ulint
row_ins_set_exclusive_rec_lock( row_ins_set_exclusive_rec_lock(
/*========================*/ /*============================*/
/* out: DB_SUCCESS or error code */ /* out: DB_SUCCESS or error code */
ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or ulint type, /* in: LOCK_ORDINARY, LOCK_GAP, or
LOCK_REC_NOT_GAP type lock */ LOCK_REC_NOT_GAP type lock */
...@@ -1517,21 +1517,17 @@ row_ins_scan_sec_index_for_duplicate( ...@@ -1517,21 +1517,17 @@ row_ins_scan_sec_index_for_duplicate(
/* Try to place a lock on the index record */ /* Try to place a lock on the index record */
/* The manual defines the REPLACE semantics that it trx = thr_get_trx(thr);
is either an INSERT or DELETE(s) for duplicate key ut_ad(trx);
+ 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)
dict_accept(*trx->mysql_query_str, "REPLACE", &success); dict_accept(*trx->mysql_query_str, "REPLACE", &success);
if (success) { if (success) {
/* 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( err = row_ins_set_exclusive_rec_lock(
LOCK_ORDINARY,rec,index,thr); LOCK_ORDINARY,rec,index,thr);
} else { } else {
...@@ -1540,7 +1536,6 @@ row_ins_scan_sec_index_for_duplicate( ...@@ -1540,7 +1536,6 @@ row_ins_scan_sec_index_for_duplicate(
LOCK_ORDINARY, rec, index,thr); LOCK_ORDINARY, rec, index,thr);
} }
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
break; break;
...@@ -1640,19 +1635,15 @@ row_ins_duplicate_error_in_clust( ...@@ -1640,19 +1635,15 @@ 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 */
/* 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.
*/
/* Is the first word in MySQL query REPLACE ? */
dict_accept(*trx->mysql_query_str, "REPLACE", &success); dict_accept(*trx->mysql_query_str, "REPLACE", &success);
if (success) { if (success) {
/* 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( err = row_ins_set_exclusive_rec_lock(
LOCK_REC_NOT_GAP,rec,cursor->index,thr); LOCK_REC_NOT_GAP,rec,cursor->index,thr);
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment