Fixed a bug in UPDATE statement with no index column in where condition

locks all rows (BUG #3300). When using innobase_locks_unsafe_for_binlog
option InnoDB does not take locks for those rows which do not
belong to the result set or werent changed by the query. This fix removes
unnecessary locks also from SELECT and DELETE queries.


innobase/include/row0mysql.h:
  Added prototype for row_unlock_for_mysql() function which does an unlock of 
  a row for MySQL.
innobase/include/trx0trx.h:
  Added a field trx_create_lock to a transaction structure. This field is
  TRUE if we have created a new lock for a record accessed.
innobase/lock/lock0lock.c:
  Set lock create flag if lock is created and reset this flag before 
  transaction requests a lock.
innobase/row/row0mysql.c:
  Add support for unlocking a row in InnoDB. If we are using 
  innobase_locks_unsafe_for_binlog option then all those record 
  locks obtained by SQL-query which do not belong to result set 
  or were not modified are unlocked i.e. we remove the lock from 
  those records.
sql/ha_innodb.cc:
  Added support for a unlock_row interface in InnoDB.
sql/ha_innodb.h:
  Added prototype for a function unlock_row().
This commit is contained in:
unknown 2004-11-08 14:52:15 +02:00
commit 20c82f5c01
6 changed files with 119 additions and 2 deletions

View file

@ -1186,6 +1186,57 @@ run_again:
return((int) err);
}
/*************************************************************************
Does an unlock of a row for MySQL. */
int
row_unlock_for_mysql(
/*=================*/
/* out: error code or DB_SUCCESS */
row_prebuilt_t* prebuilt) /* in: prebuilt struct in MySQL
handle */
{
rec_t* rec;
btr_pcur_t* cur = prebuilt->pcur;
trx_t* trx = prebuilt->trx;
mtr_t mtr;
ut_ad(prebuilt && trx);
ut_ad(trx->mysql_thread_id == os_thread_get_curr_id());
trx->op_info = "unlock_row";
if (srv_locks_unsafe_for_binlog) {
if (trx->trx_create_lock == TRUE) {
mtr_start(&mtr);
/* Restore a cursor position and find a record */
btr_pcur_restore_position(BTR_SEARCH_LEAF, cur, &mtr);
rec = btr_pcur_get_rec(cur);
if (rec) {
lock_rec_reset_and_release_wait(rec);
} else {
fputs("InnoDB: Error: "
"Record for the lock not found\n",
stderr);
mem_analyze_corruption((byte*) trx);
ut_error;
}
trx->trx_create_lock = FALSE;
mtr_commit(&mtr);
}
}
trx->op_info = "";
return(DB_SUCCESS);
}
/**************************************************************************
Does a cascaded delete or set null in a foreign key operation. */