diff options
author | unknown <aivanov@mysql.com> | 2006-01-16 14:32:43 +0300 |
---|---|---|
committer | unknown <aivanov@mysql.com> | 2006-01-16 14:32:43 +0300 |
commit | 7bafd119a3f73c39306a133936501a433e80bcf9 (patch) | |
tree | 42a4966dcc1d1565033773730d0782e22ce4570b /innobase/lock | |
parent | fe1970d4b9084de6e883b0dae50ab4d5d3957e54 (diff) | |
download | mariadb-git-7bafd119a3f73c39306a133936501a433e80bcf9.tar.gz |
Changes from the innodb-5.0-ss115 snapshot.
Fixed bugs:
BUG#15991: "innodb-file-per-table + symlink database + rename = crash"
BUG#15650: "DELETE with LEFT JOIN crashes server"
BUG#15308: "Problem of Order with Enum Column in Primary Key"
BUG#14189: "VARBINARY and BINARY variables: trailing space ignored"
innobase/include/data0type.h:
Changes from the innodb-5.0-ss115 snapshot.
innobase/include/data0type.ic:
Changes from the innodb-5.0-ss115 snapshot.
Fixed bug #14189. dtype_get_pad_char(): Do not pad VARBINARY
or BINARY cloumns.
innobase/include/lock0lock.h:
Changes from the innodb-5.0-ss115 snapshot.
innobase/include/os0file.h:
Changes from the innodb-5.0-ss115 snapshot.
os_file_handle_error(): Map the error codes EXDEV, ENOTDIR, and
EISDIR to the new code OS_FILE_PATH_ERROR. Treat this code as
OS_FILE_PATH_ERROR. This fixes the crash on RENAME TABLE when
the .ibd file is a symbolic link to a different file system
(bug#15991).
innobase/include/row0mysql.h:
Changes from the innodb-5.0-ss115 snapshot.
innobase/lock/lock0lock.c:
Changes from the innodb-5.0-ss115 snapshot.
lock_rec_unlock(): Initialize local variable release_lock,
in order to avoid dereferencing an uninitialized pointer
when no lock exists on rec.
innobase/os/os0file.c:
Changes from the innodb-5.0-ss115 snapshot.
os_file_handle_error(): Map the error codes EXDEV, ENOTDIR, and
EISDIR to the new code OS_FILE_PATH_ERROR. Treat this code as
OS_FILE_PATH_ERROR. This fixes the crash on RENAME TABLE when
the .ibd file is a symbolic link to a different file system
(bug#15991).
Protect the increment and decrement operations on the statistic
variables os_n_pending_writes/reads with os_file_count_mutes.
innobase/row/row0ins.c:
Changes from the innodb-5.0-ss115 snapshot.
Fixed bug #14189. row_ins_cascade_calc_update_vec(): Refuse
ON UPDATE_CASCADE when trying to change the length of of a
VARBINARY column that refers to or is referenced by a BINARY
column. BINARY columns are no longer padded on comparison,
and thus they cannot be padded on storage either.
innobase/row/row0mysql.c:
Changes from the innodb-5.0-ss115 snapshot.
Fixed bug on unlock_row. In a unlock_row we may unlock
only the latest lock granted to this transaction to the row.
innobase/row/row0sel.c:
Changes from the innodb-5.0-ss115 snapshot.
Fixed bug #15308.
Fixed bug #14189: innobase_init(): Assert that
DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number.
After review fixes for unlock bug where unlock released all
locks transaction requested for a row. Only a latest requested
lock to a row should be released. Update function comments to
reflect current state. Persistent cursor should be stored
whenever select lock type != LOCK_NONE.
innobase/trx/trx0trx.c:
Changes from the innodb-5.0-ss115 snapshot.
trx_commit_off_kernel(): Do not write empty trx->mysql_log_file_name.
mysql-test/r/innodb.result:
Changes from the innodb-5.0-ss115 snapshot.
mysql-test/t/innodb.test:
Changes from the innodb-5.0-ss115 snapshot.
sql/ha_innodb.cc:
Changes from the innodb-5.0-ss115 snapshot.
Fixed bug #15308.
Fixed bug #14189: innobase_init(): Assert that
DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number.
After review fixes for unlock bug where unlock released all
locks transaction requested for a row. Only a latest requested
lock to a row should be released. Update function comments to
reflect current state. Persistent cursor should be stored
whenever select lock type != LOCK_NONE.
mysql-test/r/innodb_unsafe_binlog.result:
Changes from the innodb-5.0-ss115 snapshot.
mysql-test/t/innodb_unsafe_binlog-master.opt:
Changes from the innodb-5.0-ss115 snapshot.
mysql-test/t/innodb_unsafe_binlog.test:
Changes from the innodb-5.0-ss115 snapshot.
Added testcases for bug #15650.
Diffstat (limited to 'innobase/lock')
-rw-r--r-- | innobase/lock/lock0lock.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 7844991613f..06475c8ef7e 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -2392,7 +2392,7 @@ lock_rec_free_all_from_discard_page( /***************************************************************** Resets the lock bits for a single record. Releases transactions waiting for lock requests here. */ - +static void lock_rec_reset_and_release_wait( /*============================*/ @@ -3760,6 +3760,75 @@ lock_table_dequeue( /*=========================== LOCK RELEASE ==============================*/ +/***************************************************************** +Removes a granted record lock of a transaction from the queue and grants +locks to other transactions waiting in the queue if they now are entitled +to a lock. */ + +void +lock_rec_unlock( +/*============*/ + trx_t* trx, /* in: transaction that has set a record + lock */ + rec_t* rec, /* in: record */ + ulint lock_mode) /* in: LOCK_S or LOCK_X */ +{ + lock_t* lock; + lock_t* release_lock = NULL; + ulint heap_no; + + ut_ad(trx && rec); + + mutex_enter(&kernel_mutex); + + heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec)); + + lock = lock_rec_get_first(rec); + + /* Find the last lock with the same lock_mode and transaction + from the record. */ + + while (lock != NULL) { + if (lock->trx == trx && lock_get_mode(lock) == lock_mode) { + release_lock = lock; + ut_a(!lock_get_wait(lock)); + } + + lock = lock_rec_get_next(rec, lock); + } + + /* If a record lock is found, release the record lock */ + + if (UNIV_LIKELY(release_lock != NULL)) { + lock_rec_reset_nth_bit(release_lock, heap_no); + } else { + mutex_exit(&kernel_mutex); + ut_print_timestamp(stderr); + fprintf(stderr, +" InnoDB: Error: unlock row could not find a %lu mode lock on the record\n", + (ulong)lock_mode); + + return; + } + + /* Check if we can now grant waiting lock requests */ + + lock = lock_rec_get_first(rec); + + while (lock != NULL) { + if (lock_get_wait(lock) + && !lock_rec_has_to_wait_in_queue(lock)) { + + /* Grant the lock */ + lock_grant(lock); + } + + lock = lock_rec_get_next(rec, lock); + } + + mutex_exit(&kernel_mutex); +} + /************************************************************************* Releases a table lock. Releases possible other transactions waiting for this lock. */ |