Commit a7bd2db6 authored by unknown's avatar unknown
Browse files

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.
parent 701f2354
Loading
Loading
Loading
Loading
+20 −16
Original line number Diff line number Diff line
@@ -759,9 +759,9 @@ lock_rec_has_to_wait(
			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 */
			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,11 +773,11 @@ 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 */
		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);
		}
@@ -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);
		}
+27 −36
Original line number Diff line number Diff line
@@ -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,21 +1517,17 @@ 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) {

			/* 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 {
@@ -1540,7 +1536,6 @@ row_ins_scan_sec_index_for_duplicate(
						LOCK_ORDINARY, rec, index,thr);
		}


		if (err != DB_SUCCESS) {

			break;
@@ -1640,19 +1635,15 @@ 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.
		        */

                        
                        /* Is the first word in MySQL query REPLACE ? */

			dict_accept(*trx->mysql_query_str, "REPLACE", &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(
					LOCK_REC_NOT_GAP,rec,cursor->index,thr);
			} else {