From: Date: April 18 2005 11:17am Subject: bk commit into 4.1 tree (jan:1.2195) BUG#7975 List-Archive: http://lists.mysql.com/internals/24102 X-Bug: 7975 Message-Id: <200504180917.j3I9HfU7027520@hundin.mysql.fi> Below is the list of changes that have just been committed into a local 4.1 repository of jan. When jan does a push these changes will be propagated to the main repository and, within 24 hours after the push, to the public repository. For information on how to access the public repository see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html ChangeSet 1.2195 05/04/18 12:17:32 jan@stripped +2 -0 Fixed a bug: deadlock without any locking, simple select and update (Bug #7975). Backported from 5.0.3. sql/ha_innodb.cc 1.191 05/04/18 12:17:09 jan@stripped +15 -4 INSERT ON DUPLICATE KEY UPDATE will also update duplicate records and we should take X-lock in this case for duplicate records. innobase/row/row0ins.c 1.54 05/04/18 12:17:09 jan@stripped +23 -18 If the SQL-query will update or replace duplicate records we take X-lock for duplicate records. # This is a BitKeeper patch. What follows are the unified diffs for the # set of deltas contained in the patch. The rest of the patch, the part # that BitKeeper cares about, is below these diffs. # User: jan # Host: hundin.mysql.fi # Root: /home/jan/mysql-4.1 --- 1.53/innobase/row/row0ins.c Wed Jan 12 10:36:44 2005 +++ 1.54/innobase/row/row0ins.c Mon Apr 18 12:17:09 2005 @@ -51,14 +51,19 @@ 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. + +2) SQL-query in the current thread +is INSERT ON DUPLICATE KEY UPDATE. + NOTE that /mysql/innobase/row/row0ins.c must contain the prototype for this function ! */ ibool -innobase_query_is_replace(void); -/*===========================*/ +innobase_query_is_update(void); /************************************************************************* Creates an insert node struct. */ @@ -1562,12 +1567,12 @@ trx = thr_get_trx(thr); ut_ad(trx); - if (innobase_query_is_replace()) { + if (innobase_query_is_update()) { - /* 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 */ + /* 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( LOCK_ORDINARY,rec,index,thr); @@ -1675,12 +1680,12 @@ sure that in roll-forward we get the same duplicate errors as in original execution */ - if (innobase_query_is_replace()) { + if (innobase_query_is_update()) { - /* 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 */ + /* 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( LOCK_REC_NOT_GAP,rec,cursor->index, @@ -1713,12 +1718,12 @@ if (rec != page_get_supremum_rec(page)) { - /* 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. */ + if (innobase_query_is_update()) { - 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( LOCK_REC_NOT_GAP, --- 1.190/sql/ha_innodb.cc Wed Apr 13 20:19:24 2005 +++ 1.191/sql/ha_innodb.cc Mon Apr 18 12:17:09 2005 @@ -5653,13 +5653,19 @@ 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. + +2) SQL-query in the current thread +is INSERT ON DUPLICATE KEY UPDATE. + NOTE that /mysql/innobase/row/row0ins.c must contain the prototype for this function ! */ ibool -innobase_query_is_replace(void) +innobase_query_is_update(void) /*===========================*/ { THD* thd; @@ -5671,9 +5677,14 @@ ( thd->lex->sql_command == SQLCOM_LOAD && thd->lex->duplicates == DUP_REPLACE )) { return true; - } else { - return false; } + + if ( thd->lex->sql_command == SQLCOM_INSERT && + thd->lex->duplicates == DUP_UPDATE ) { + return true; + } + + return false; } }