diff options
author | unknown <aivanov@mysql.com> | 2006-03-10 19:22:21 +0300 |
---|---|---|
committer | unknown <aivanov@mysql.com> | 2006-03-10 19:22:21 +0300 |
commit | 050f14ac371e03dc96b96e8a9b0cd8fa8e3a23e0 (patch) | |
tree | 8105d79f7267d8af93861befd1899063f1ad42c2 /storage/innobase/lock | |
parent | 1cef1679a47bfbf744d656646770193ba07c30fe (diff) | |
download | mariadb-git-050f14ac371e03dc96b96e8a9b0cd8fa8e3a23e0.tar.gz |
Applied innodb-5.1-ss269 snapshot.
Fixed BUGS:
#3300: "UPDATE statement with no index column in where condition locks
all rows"
Implement semi-consistent read to reduce lock conflicts at the cost
of breaking serializability.
ha_innobase::unlock_row(): reset the "did semi consistent read" flag
ha_innobase::was_semi_consistent_read(),
ha_innobase::try_semi_consistent_read(): new methods
row_prebuilt_t, row_create_prebuilt(): add field row_read_type for
keeping track of semi-consistent reads
row_vers_build_for_semi_consistent_read(),
row_sel_build_committed_vers_for_mysql(): new functions
row_search_for_mysql(): implement semi-consistent reads
#9802: "Foreign key checks disallow alter table".
Added test cases.
#12456: "Cursor shows incorrect data - DML does not affect,
probably caching"
This patch implements a high-granularity read view to be used with
cursors. In this high-granularity consistent read view modifications
done by the creating transaction after the cursor is created or
future transactions are not visible. But those modifications that
transaction did before the cursor was created are visible.
#12701: "Support >4GB buffer pool and log files on 64-bit Windows"
Do not call os_file_create_tmpfile() at runtime. Instead, create all
tempfiles at startup and guard access to them with mutexes.
#13778: "If FOREIGN_KEY_CHECKS=0, one can create inconsistent FOREIGN KEYs".
When FOREIGN_KEY_CHECKS=0 we still need to check that datatypes between
foreign key references are compatible.
#14189: "VARBINARY and BINARY variables: trailing space ignored with InnoDB"
innobase_init(): Assert that
DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number.
dtype_get_pad_char(): Do not pad VARBINARY or BINARY columns.
row_ins_cascade_calc_update_vec(): Refuse ON UPDATE CASCADE when trying
to change the length 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.
#14747: "Race condition can cause btr_search_drop_page_hash_index() to crash"
Note that buf_block_t::index should be protected by btr_search_latch
or an s-latch or x-latch on the index page.
btr_search_drop_page_hash_index(): Read block->index while holding
btr_search_latch and use the cached value in the loop. Remove some
redundant assertions.
#15108: "mysqld crashes when innodb_log_file_size is set > 4G"
#15308: "Problem of Order with Enum Column in Primary Key"
#15550: "mysqld crashes in printing a FOREIGN KEY error in InnoDB"
row_ins_foreign_report_add_err(): When printing the parent record,
use the index in the parent table rather than the index in the child table.
#15653: "Slow inserts to InnoDB if many thousands of .ibd files"
Keep track on unflushed modifications to file spaces. When there are tens
of thousands of file spaces, flushing all files in fil_flush_file_spaces()
would be very slow.
fil_flush_file_spaces(): Only flush unflushed file spaces.
fil_space_t, fil_system_t: Add a list of unflushed spaces.
#15991: "innodb-file-per-table + symlink database + rename = cr"
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.
#16157: "InnoDB crashes when main location settings are empty"
This patch is from Heikki.
#16298: "InnoDB segfaults in INSERTs in upgrade of 4.0 -> 5.0 tables
with VARCHAR BINARY"
dict_load_columns(): Set the charset-collation code
DATA_MYSQL_BINARY_CHARSET_COLL for those binary string columns
that lack a charset-collation code, i.e., the tables were created
with an older version of MySQL/InnoDB than 4.1.2.
#16229: "MySQL/InnoDB uses full explicit table locks in trigger processing"
Take a InnoDB table lock only if user has explicitly requested a table
lock. Added some additional comments to store_lock() and external_lock().
#16387: "InnoDB crash when dropping a foreign key <table>_ibfk_0"
Do not mistake TABLENAME_ibfk_0 for auto-generated id.
dict_table_get_highest_foreign_id(): Ignore foreign constraint
identifiers starting with the pattern TABLENAME_ibfk_0.
#16582: "InnoDB: Error in an adaptive hash index pointer to page"
Account for a race condition when dropping the adaptive hash index
for a B-tree page.
btr_search_drop_page_hash_index(): Retry the operation if a hash index
with different parameters was built meanwhile. Add diagnostics for the
case that hash node pointers to the page remain.
btr_search_info_update_hash(), btr_search_info_update_slow():
Document the parameter "info" as in/out.
#16814: "SHOW INNODB STATUS format error in LATEST FOREIGN KEY ERROR
section"
Add a missing newline to the LAST FOREIGN KEY ERROR section in SHOW
INNODB STATUS output.
dict_foreign_error_report(): Always print a newline after invoking
dict_print_info_on_foreign_key_in_create_format().
#16827: "Better InnoDB error message if ibdata files omitted from my.cnf"
#17126: "CHECK TABLE on InnoDB causes a short hang during check of adaptive
hash"
CHECK TABLE blocking other queries, by releasing the btr_search_latch
periodically during the adaptive hash table validation.
#17405: "Valgrind: conditional jump or move depends on unititialised values"
buf_block_init(): Reset magic_n, buf_fix_count and io_fix to avoid
testing uninitialized variables.
mysql-test/r/innodb.result:
Applied innodb-5.1-ss269 snapshot.
mysql-test/t/innodb.test:
Applied innodb-5.1-ss269 snapshot.
sql/ha_innodb.cc:
Applied innodb-5.1-ss269 snapshot.
sql/ha_innodb.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/btr/btr0btr.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/btr/btr0cur.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/btr/btr0pcur.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/btr/btr0sea.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/buf/buf0buf.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/buf/buf0flu.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/buf/buf0lru.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/buf/buf0rea.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/data/data0data.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/data/data0type.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0boot.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0crea.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0dict.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0load.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/dict/dict0mem.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/dyn/dyn0dyn.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/eval/eval0eval.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/eval/eval0proc.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/fil/fil0fil.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/fsp/fsp0fsp.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/fut/fut0lst.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/ha/ha0ha.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/ha/hash0hash.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/ibuf/ibuf0ibuf.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0btr.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0btr.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0cur.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0cur.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0pcur.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0pcur.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0sea.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0sea.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/btr0types.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0buf.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0buf.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0flu.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0flu.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/buf0lru.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/data0data.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/data0data.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/data0type.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/data0type.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/db0err.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0boot.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0boot.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0crea.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0dict.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0dict.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0load.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dict0mem.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dyn0dyn.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/dyn0dyn.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/eval0eval.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/eval0eval.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/eval0proc.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/eval0proc.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/fil0fil.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/fsp0fsp.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/fut0lst.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ha0ha.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/hash0hash.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/hash0hash.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ibuf0ibuf.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ibuf0ibuf.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/lock0lock.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/lock0types.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/log0log.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/log0log.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/log0recv.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mach0data.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mach0data.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0dbg.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0dbg.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0mem.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0mem.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mem0pool.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mtr0log.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mtr0mtr.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/mtr0mtr.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0file.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0proc.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0sync.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0sync.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/os0thread.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0cur.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0cur.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0page.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0page.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/page0types.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0grm.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0opt.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0pars.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0sym.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/pars0types.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/que0que.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/que0que.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/que0types.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/read0read.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/read0read.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/rem0cmp.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/rem0cmp.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/rem0rec.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/rem0rec.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0ins.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0mysql.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0purge.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0row.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0row.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0sel.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0sel.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0types.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0uins.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0umod.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0undo.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0upd.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0upd.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/row0vers.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/srv0srv.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/srv0start.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0arr.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0rw.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0rw.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0sync.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/sync0sync.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0purge.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0purge.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0rec.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0roll.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0rseg.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0rseg.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0sys.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0sys.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0trx.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0trx.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0types.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0undo.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0undo.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/trx0xa.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/univ.i:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/usr0sess.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/usr0types.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0byte.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0byte.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0dbg.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0lst.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0mem.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0mem.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0rnd.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0rnd.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0sort.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0ut.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/include/ut0ut.ic:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/lock/lock0lock.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/log/log0log.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/log/log0recv.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/mach/mach0data.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/mem/mem0dbg.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/mem/mem0mem.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/mem/mem0pool.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/mtr/mtr0log.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/mtr/mtr0mtr.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/os/os0file.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/os/os0proc.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/os/os0sync.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/os/os0thread.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/page/page0cur.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/page/page0page.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/lexyy.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0grm.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0grm.h:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0grm.y:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0lex.l:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0opt.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0pars.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/pars/pars0sym.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/que/que0que.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/read/read0read.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/rem/rem0cmp.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/rem/rem0rec.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0ins.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0mysql.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0purge.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0row.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0sel.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0uins.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0umod.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0undo.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0upd.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/row/row0vers.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/srv/srv0que.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/srv/srv0srv.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/srv/srv0start.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/sync/sync0arr.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/sync/sync0rw.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/sync/sync0sync.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/thr/thr0loc.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0purge.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0rec.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0roll.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0rseg.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0sys.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0trx.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/trx/trx0undo.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/usr/usr0sess.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0byte.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0dbg.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0mem.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0rnd.c:
Applied innodb-5.1-ss269 snapshot.
storage/innobase/ut/ut0ut.c:
Applied innodb-5.1-ss269 snapshot.
mysql-test/r/innodb_unsafe_binlog.result:
New BitKeeper file ``mysql-test/r/innodb_unsafe_binlog.result''
mysql-test/t/innodb_unsafe_binlog-master.opt:
New BitKeeper file ``mysql-test/t/innodb_unsafe_binlog-master.opt''
mysql-test/t/innodb_unsafe_binlog.test:
New BitKeeper file ``mysql-test/t/innodb_unsafe_binlog.test''
storage/innobase/pars/make_bison.sh:
New BitKeeper file ``storage/innobase/pars/make_bison.sh''
Diffstat (limited to 'storage/innobase/lock')
-rw-r--r-- | storage/innobase/lock/lock0lock.c | 715 |
1 files changed, 359 insertions, 356 deletions
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c index a3d388f981d..1152e0c89ea 100644 --- a/storage/innobase/lock/lock0lock.c +++ b/storage/innobase/lock/lock0lock.c @@ -64,7 +64,7 @@ bitmap */ /* An explicit record lock affects both the record and the gap before it. An implicit x-lock does not affect the gap, it only locks the index -record from read or update. +record from read or update. If a transaction has modified or inserted an index record, then it owns an implicit x-lock on the record. On a secondary index record, @@ -298,11 +298,11 @@ locks on the inserted record. */ /* LOCK COMPATIBILITY MATRIX * IS IX S X AI - * IS + + + - + - * IX + + - - + - * S + - + - - - * X - - - - - - * AI + + - - - + * IS + + + - + + * IX + + - - + + * S + - + - - + * X - - - - - + * AI + + - - - * * Note that for rows, InnoDB only acquires S or X locks. * For tables, InnoDB normally acquires IS or IX locks. @@ -324,7 +324,7 @@ typedef struct lock_table_struct lock_table_t; struct lock_table_struct{ dict_table_t* table; /* database table in dictionary cache */ UT_LIST_NODE_T(lock_t) - locks; /* list of locks on the same table */ + locks; /* list of locks on the same table */ }; /* Record lock for a page */ @@ -340,7 +340,7 @@ struct lock_rec_struct{ /* Lock struct */ struct lock_struct{ trx_t* trx; /* transaction owning the lock */ - UT_LIST_NODE_T(lock_t) + UT_LIST_NODE_T(lock_t) trx_locks; /* list of the locks of the transaction */ ulint type_mode; /* lock type, mode, LOCK_GAP or @@ -396,7 +396,7 @@ lock_deadlock_recursive( ulint* cost, /* in/out: number of calculation steps thus far: if this exceeds LOCK_MAX_N_STEPS_... we return LOCK_VICTIM_IS_START */ - uint depth); /* in: recursion depth: if this exceeds + ulint depth); /* in: recursion depth: if this exceeds LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we return LOCK_VICTIM_IS_START */ @@ -442,7 +442,7 @@ lock_rec_get_nth_bit( b = (ulint)*((byte*)lock + sizeof(lock_t) + byte_index); return(ut_bit_get_nth(b, bit_index)); -} +} /*************************************************************************/ @@ -464,7 +464,7 @@ lock_check_trx_id_sanity( kernel mutex */ { ibool is_ok = TRUE; - + ut_ad(rec_offs_validate(rec, index, offsets)); if (!has_kernel_mutex) { @@ -485,14 +485,14 @@ lock_check_trx_id_sanity( fprintf(stderr, "\n" "InnoDB: is %lu %lu which is higher than the global trx id counter %lu %lu!\n" "InnoDB: The table is corrupt. You have to do dump + drop + reimport.\n", - (ulong) ut_dulint_get_high(trx_id), - (ulong) ut_dulint_get_low(trx_id), - (ulong) ut_dulint_get_high(trx_sys->max_trx_id), - (ulong) ut_dulint_get_low(trx_sys->max_trx_id)); + (ulong) ut_dulint_get_high(trx_id), + (ulong) ut_dulint_get_low(trx_id), + (ulong) ut_dulint_get_high(trx_sys->max_trx_id), + (ulong) ut_dulint_get_low(trx_sys->max_trx_id)); is_ok = FALSE; } - + if (!has_kernel_mutex) { mutex_exit(&kernel_mutex); } @@ -525,7 +525,7 @@ lock_clust_rec_cons_read_sees( kernel mutex here! */ trx_id = row_get_rec_trx_id(rec, index, offsets); - + return(read_view_sees_trx_id(view, trx_id)); } @@ -549,9 +549,9 @@ lock_sec_rec_cons_read_sees( read_view_t* view) /* in: consistent read view */ { dulint max_trx_id; - + UT_NOT_USED(index); - + ut_ad(!(index->type & DICT_CLUSTERED)); ut_ad(page_rec_is_user_rec(rec)); @@ -675,7 +675,7 @@ lock_get_src_table( /* This presumably is the source table. */ src = tab_lock->table; if (UT_LIST_GET_LEN(src->locks) != 1 || - UT_LIST_GET_FIRST(src->locks) != lock) { + UT_LIST_GET_FIRST(src->locks) != lock) { /* We only support the case when there is only one lock on this table. */ return(NULL); @@ -769,9 +769,9 @@ lock_set_lock_and_trx_wait( { ut_ad(lock); ut_ad(trx->wait_lock == NULL); - + trx->wait_lock = lock; - lock->type_mode = lock->type_mode | LOCK_WAIT; + lock->type_mode = lock->type_mode | LOCK_WAIT; } /************************************************************************** @@ -789,7 +789,7 @@ lock_reset_lock_and_trx_wait( /* Reset the back pointer in trx to this waiting lock request */ (lock->trx)->wait_lock = NULL; - lock->type_mode = lock->type_mode & ~LOCK_WAIT; + lock->type_mode = lock->type_mode & ~LOCK_WAIT; } /************************************************************************* @@ -914,18 +914,18 @@ lock_mode_compatible( return(FALSE); } else if (mode1 == LOCK_AUTO_INC && (mode2 == LOCK_IS - || mode2 == LOCK_IX)) { + || mode2 == LOCK_IX)) { return(TRUE); } else if (mode1 == LOCK_IS && (mode2 == LOCK_IS - || mode2 == LOCK_IX - || mode2 == LOCK_AUTO_INC - || mode2 == LOCK_S)) { + || mode2 == LOCK_IX + || mode2 == LOCK_AUTO_INC + || mode2 == LOCK_S)) { return(TRUE); } else if (mode1 == LOCK_IX && (mode2 == LOCK_IS - || mode2 == LOCK_AUTO_INC - || mode2 == LOCK_IX)) { + || mode2 == LOCK_AUTO_INC + || mode2 == LOCK_IX)) { return(TRUE); } @@ -956,23 +956,23 @@ lock_rec_has_to_wait( ut_ad(lock_get_type(lock2) == LOCK_REC); if (trx != lock2->trx - && !lock_mode_compatible(LOCK_MODE_MASK & type_mode, - lock_get_mode(lock2))) { + && !lock_mode_compatible(LOCK_MODE_MASK & type_mode, + lock_get_mode(lock2))) { /* We have somewhat complex rules when gap type record locks cause waits */ if ((lock_is_on_supremum || (type_mode & LOCK_GAP)) - && !(type_mode & LOCK_INSERT_INTENTION)) { + && !(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 + do not need to wait for anything. This is because + different users can have conflicting lock types on gaps. */ - + return(FALSE); } - + if (!(type_mode & LOCK_INSERT_INTENTION) && lock_rec_get_gap(lock2)) { @@ -984,7 +984,7 @@ lock_rec_has_to_wait( if ((type_mode & LOCK_GAP) && lock_rec_get_rec_not_gap(lock2)) { - + /* Lock on gap does not need to wait for a LOCK_REC_NOT_GAP type lock */ @@ -1003,7 +1003,7 @@ lock_rec_has_to_wait( Also, insert intention locks do not disturb each other. */ - + return(FALSE); } @@ -1030,13 +1030,13 @@ lock_has_to_wait( if (lock1->trx != lock2->trx && !lock_mode_compatible(lock_get_mode(lock1), - lock_get_mode(lock2))) { + lock_get_mode(lock2))) { 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, lock_rec_get_nth_bit(lock1,1))); @@ -1067,7 +1067,7 @@ Sets the nth bit of a record lock to TRUE. */ UNIV_INLINE void lock_rec_set_nth_bit( -/*==================*/ +/*=================*/ lock_t* lock, /* in: record lock */ ulint i) /* in: index of the bit */ { @@ -1075,22 +1075,22 @@ lock_rec_set_nth_bit( ulint bit_index; byte* ptr; ulint b; - + ut_ad(lock); ut_ad(lock_get_type(lock) == LOCK_REC); ut_ad(i < lock->un_member.rec_lock.n_bits); - + byte_index = i / 8; bit_index = i % 8; ptr = (byte*)lock + sizeof(lock_t) + byte_index; - + b = (ulint)*ptr; b = ut_bit_set_nth(b, bit_index, TRUE); *ptr = (byte)b; -} +} /************************************************************************** Looks for a set bit in a record lock bitmap. Returns ULINT_UNDEFINED, @@ -1130,22 +1130,22 @@ lock_rec_reset_nth_bit( ulint bit_index; byte* ptr; ulint b; - + ut_ad(lock); ut_ad(lock_get_type(lock) == LOCK_REC); ut_ad(i < lock->un_member.rec_lock.n_bits); - + byte_index = i / 8; bit_index = i % 8; ptr = (byte*)lock + sizeof(lock_t) + byte_index; - + b = (ulint)*ptr; b = ut_bit_set_nth(b, bit_index, FALSE); *ptr = (byte)b; -} +} /************************************************************************* Gets the first or next record lock on a page. */ @@ -1166,7 +1166,7 @@ lock_rec_get_next_on_page( space = lock->un_member.rec_lock.space; page_no = lock->un_member.rec_lock.page_no; - + for (;;) { lock = HASH_GET_NEXT(hash, lock); @@ -1175,13 +1175,13 @@ lock_rec_get_next_on_page( break; } - if ((lock->un_member.rec_lock.space == space) - && (lock->un_member.rec_lock.page_no == page_no)) { + if ((lock->un_member.rec_lock.space == space) + && (lock->un_member.rec_lock.page_no == page_no)) { break; } } - + return(lock); } @@ -1205,8 +1205,8 @@ lock_rec_get_first_on_page_addr( lock = HASH_GET_FIRST(lock_sys->rec_hash, lock_rec_hash(space, page_no)); while (lock) { - if ((lock->un_member.rec_lock.space == space) - && (lock->un_member.rec_lock.page_no == page_no)) { + if ((lock->un_member.rec_lock.space == space) + && (lock->un_member.rec_lock.page_no == page_no)) { break; } @@ -1216,7 +1216,7 @@ lock_rec_get_first_on_page_addr( return(lock); } - + /************************************************************************* Returns TRUE if there are explicit record locks on a page. */ @@ -1239,7 +1239,7 @@ lock_rec_expl_exist_on_page( } mutex_exit(&kernel_mutex); - + return(ret); } @@ -1261,7 +1261,7 @@ lock_rec_get_first_on_page( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - + hash = buf_frame_get_lock_hash_val(ptr); lock = HASH_GET_FIRST(lock_sys->rec_hash, hash); @@ -1270,8 +1270,8 @@ lock_rec_get_first_on_page( space = buf_frame_get_space_id(ptr); page_no = buf_frame_get_page_no(ptr); - if ((lock->un_member.rec_lock.space == space) - && (lock->un_member.rec_lock.page_no == page_no)) { + if ((lock->un_member.rec_lock.space == space) + && (lock->un_member.rec_lock.page_no == page_no)) { break; } @@ -1363,7 +1363,7 @@ lock_rec_bitmap_reset( n_bytes = lock_rec_get_n_bits(lock) / 8; ut_ad((lock_rec_get_n_bits(lock) % 8) == 0); - + for (i = 0; i < n_bytes; i++) { *ptr = 0; @@ -1386,7 +1386,7 @@ lock_rec_copy( ut_ad(lock_get_type(lock) == LOCK_REC); - size = sizeof(lock_t) + lock_rec_get_n_bits(lock) / 8; + size = sizeof(lock_t) + lock_rec_get_n_bits(lock) / 8; dupl_lock = mem_heap_alloc(heap, size); @@ -1409,7 +1409,7 @@ lock_rec_get_prev( lock_t* lock; ulint space; ulint page_no; - lock_t* found_lock = NULL; + lock_t* found_lock = NULL; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -1423,7 +1423,7 @@ lock_rec_get_prev( for (;;) { ut_ad(lock); - + if (lock == in_lock) { return(found_lock); @@ -1435,7 +1435,7 @@ lock_rec_get_prev( } lock = lock_rec_get_next_on_page(lock); - } + } } /*============= FUNCTIONS FOR ANALYZING TABLE LOCK QUEUE ================*/ @@ -1464,12 +1464,12 @@ lock_table_has( while (lock != NULL) { if (lock->trx == trx - && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)) { + && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)) { - /* The same trx already has locked the table in + /* The same trx already has locked the table in a mode stronger or equal to the mode given */ - ut_ad(!lock_get_wait(lock)); + ut_ad(!lock_get_wait(lock)); return(lock); } @@ -1479,7 +1479,7 @@ lock_table_has( return(NULL); } - + /*============= FUNCTIONS FOR ANALYZING RECORD LOCK QUEUE ================*/ /************************************************************************* @@ -1503,25 +1503,25 @@ lock_rec_has_expl( ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_ad((precise_mode & LOCK_MODE_MASK) == LOCK_S - || (precise_mode & LOCK_MODE_MASK) == LOCK_X); + || (precise_mode & LOCK_MODE_MASK) == LOCK_X); ut_ad(!(precise_mode & LOCK_INSERT_INTENTION)); - + lock = lock_rec_get_first(rec); while (lock) { if (lock->trx == trx - && lock_mode_stronger_or_eq(lock_get_mode(lock), - precise_mode & LOCK_MODE_MASK) - && !lock_get_wait(lock) - && (!lock_rec_get_rec_not_gap(lock) - || (precise_mode & LOCK_REC_NOT_GAP) - || page_rec_is_supremum(rec)) - && (!lock_rec_get_gap(lock) + && lock_mode_stronger_or_eq(lock_get_mode(lock), + precise_mode & LOCK_MODE_MASK) + && !lock_get_wait(lock) + && (!lock_rec_get_rec_not_gap(lock) + || (precise_mode & LOCK_REC_NOT_GAP) + || page_rec_is_supremum(rec)) + && (!lock_rec_get_gap(lock) || (precise_mode & LOCK_GAP) || page_rec_is_supremum(rec)) - && (!lock_rec_get_insert_intention(lock))) { + && (!lock_rec_get_insert_intention(lock))) { - return(lock); + return(lock); } lock = lock_rec_get_next(rec, lock); @@ -1529,7 +1529,8 @@ lock_rec_has_expl( return(NULL); } - + +#ifndef UNIV_HOTBACKUP /************************************************************************* Checks if some other transaction has a lock request in the queue. */ static @@ -1542,12 +1543,12 @@ lock_rec_other_has_expl_req( into account, or 0 if not */ ulint wait, /* in: LOCK_WAIT if also waiting locks are taken into account, or 0 if not */ - rec_t* rec, /* in: record to look at */ + rec_t* rec, /* in: record to look at */ trx_t* trx) /* in: transaction, or NULL if requests by all transactions are taken into account */ { lock_t* lock; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ @@ -1559,12 +1560,12 @@ lock_rec_other_has_expl_req( while (lock) { if (lock->trx != trx - && (gap || - !(lock_rec_get_gap(lock) || page_rec_is_supremum(rec))) - && (wait || !lock_get_wait(lock)) - && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)) { + && (gap || + !(lock_rec_get_gap(lock) || page_rec_is_supremum(rec))) + && (wait || !lock_get_wait(lock)) + && lock_mode_stronger_or_eq(lock_get_mode(lock), mode)) { - return(lock); + return(lock); } lock = lock_rec_get_next(rec, lock); @@ -1572,6 +1573,7 @@ lock_rec_other_has_expl_req( return(NULL); } +#endif /* !UNIV_HOTBACKUP */ /************************************************************************* Checks if some other transaction has a conflicting explicit lock request @@ -1584,7 +1586,7 @@ lock_rec_other_has_conflicting( ulint mode, /* in: LOCK_S or LOCK_X, possibly ORed to LOCK_GAP or LOC_REC_NOT_GAP, LOCK_INSERT_INTENTION */ - rec_t* rec, /* in: record to look at */ + rec_t* rec, /* in: record to look at */ trx_t* trx) /* in: our transaction */ { lock_t* lock; @@ -1600,7 +1602,7 @@ lock_rec_other_has_conflicting( return(lock); } - + lock = lock_rec_get_next(rec, lock); } @@ -1632,12 +1634,12 @@ lock_rec_find_similar_on_page( while (lock != NULL) { if (lock->trx == trx - && lock->type_mode == type_mode - && lock_rec_get_n_bits(lock) > heap_no) { - + && lock->type_mode == type_mode + && lock_rec_get_n_bits(lock) > heap_no) { + return(lock); } - + lock = lock_rec_get_next_on_page(lock); } @@ -1658,7 +1660,7 @@ lock_sec_rec_some_has_impl_off_kernel( const ulint* offsets)/* in: rec_get_offsets(rec, index) */ { page_t* page; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ @@ -1676,18 +1678,18 @@ lock_sec_rec_some_has_impl_off_kernel( if (!(ut_dulint_cmp(page_get_max_trx_id(page), trx_list_get_min_trx_id()) >= 0) - && !recv_recovery_is_on()) { + && !recv_recovery_is_on()) { return(NULL); } /* Ok, in this case it is possible that some transaction has an implicit x-lock. We have to look in the clustered index. */ - + if (!lock_check_trx_id_sanity(page_get_max_trx_id(page), rec, index, offsets, TRUE)) { buf_page_print(page); - + /* The page is corrupt: try to avoid a crash by returning NULL */ return(NULL); @@ -1719,7 +1721,7 @@ lock_rec_create( ulint space; ulint n_bits; ulint n_bytes; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ @@ -1729,7 +1731,7 @@ lock_rec_create( page_no = buf_frame_get_page_no(page); heap_no = rec_get_heap_no(rec, page_is_comp(page)); - ut_ad(!!page_is_comp(page) == index->table->comp); + ut_ad(!!page_is_comp(page) == dict_table_is_comp(index->table)); /* If rec is the supremum record, then we reset the gap and LOCK_REC_NOT_GAP bits, as all locks on the supremum are @@ -1753,7 +1755,7 @@ lock_rec_create( lock->type_mode = (type_mode & ~LOCK_TYPE_MASK) | LOCK_REC; lock->index = index; - + lock->un_member.rec_lock.space = space; lock->un_member.rec_lock.page_no = page_no; lock->un_member.rec_lock.n_bits = n_bytes * 8; @@ -1772,7 +1774,7 @@ lock_rec_create( lock_set_lock_and_trx_wait(lock, trx); } - + return(lock); } @@ -1801,7 +1803,7 @@ lock_rec_enqueue_waiting( { lock_t* lock; trx_t* trx; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ @@ -1816,7 +1818,7 @@ lock_rec_enqueue_waiting( return(DB_QUE_THR_SUSPENDED); } - + trx = thr_get_trx(thr); if (trx->dict_operation) { @@ -1829,13 +1831,13 @@ lock_rec_enqueue_waiting( "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } - + /* Enqueue the lock request that will wait to be granted */ lock = lock_rec_create(type_mode | LOCK_WAIT, rec, index, trx); /* Check if a deadlock occurs: if yes, remove the lock request and return an error code */ - + if (lock_deadlock_occurs(lock, trx)) { lock_reset_lock_and_trx_wait(lock); @@ -1866,8 +1868,8 @@ lock_rec_enqueue_waiting( ut_print_name(stderr, trx, index->name); } #endif /* UNIV_DEBUG */ - - return(DB_LOCK_WAIT); + + return(DB_LOCK_WAIT); } /************************************************************************* @@ -1892,18 +1894,18 @@ lock_rec_add_to_queue( lock_t* similar_lock = NULL; ulint heap_no; ibool somebody_waits = FALSE; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_ad((type_mode & (LOCK_WAIT | LOCK_GAP)) - || ((type_mode & LOCK_MODE_MASK) != LOCK_S) - || !lock_rec_other_has_expl_req(LOCK_X, 0, LOCK_WAIT, - rec, trx)); + || ((type_mode & LOCK_MODE_MASK) != LOCK_S) + || !lock_rec_other_has_expl_req(LOCK_X, 0, LOCK_WAIT, + rec, trx)); ut_ad((type_mode & (LOCK_WAIT | LOCK_GAP)) - || ((type_mode & LOCK_MODE_MASK) != LOCK_X) - || !lock_rec_other_has_expl_req(LOCK_S, 0, LOCK_WAIT, - rec, trx)); + || ((type_mode & LOCK_MODE_MASK) != LOCK_X) + || !lock_rec_other_has_expl_req(LOCK_S, 0, LOCK_WAIT, + rec, trx)); type_mode = type_mode | LOCK_REC; @@ -1917,7 +1919,7 @@ lock_rec_add_to_queue( /* There should never be LOCK_REC_NOT_GAP on a supremum record, but let us play safe */ - + type_mode = type_mode & ~(LOCK_GAP | LOCK_REC_NOT_GAP); } @@ -1970,11 +1972,11 @@ lock_rec_lock_fast( ORed to either LOCK_GAP or LOCK_REC_NOT_GAP */ rec_t* rec, /* in: record */ dict_index_t* index, /* in: index of record */ - que_thr_t* thr) /* in: query thread */ + que_thr_t* thr) /* in: query thread */ { lock_t* lock; ulint heap_no; - trx_t* trx; + trx_t* trx; #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); @@ -1988,9 +1990,9 @@ lock_rec_lock_fast( ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == 0 || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP); - + heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec)); - + lock = lock_rec_get_first_on_page(rec); trx = thr_get_trx(thr); @@ -1998,25 +2000,25 @@ lock_rec_lock_fast( if (lock == NULL) { if (!impl) { lock_rec_create(mode, rec, index, trx); - + if (srv_locks_unsafe_for_binlog) { trx_register_new_rec_lock(trx, index); } } - + return(TRUE); } - + if (lock_rec_get_next_on_page(lock)) { return(FALSE); } if (lock->trx != trx - || lock->type_mode != (mode | LOCK_REC) - || lock_rec_get_n_bits(lock) <= heap_no) { + || lock->type_mode != (mode | LOCK_REC) + || lock_rec_get_n_bits(lock) <= heap_no) { - return(FALSE); + return(FALSE); } if (!impl) { @@ -2052,7 +2054,7 @@ lock_rec_lock_slow( ORed to either LOCK_GAP or LOCK_REC_NOT_GAP */ rec_t* rec, /* in: record */ dict_index_t* index, /* in: index of record */ - que_thr_t* thr) /* in: query thread */ + que_thr_t* thr) /* in: query thread */ { trx_t* trx; ulint err; @@ -2069,9 +2071,9 @@ lock_rec_lock_slow( ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == 0 || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP); - + trx = thr_get_trx(thr); - + if (lock_rec_has_expl(mode, rec, trx)) { /* The trx already has a strong enough lock on rec: do nothing */ @@ -2082,7 +2084,7 @@ lock_rec_lock_slow( /* If another transaction has a non-gap conflicting request in the queue, as this transaction does not have a lock strong enough already granted on the record, we have to wait. */ - + err = lock_rec_enqueue_waiting(mode, rec, index, thr); if (srv_locks_unsafe_for_binlog) { @@ -2124,7 +2126,7 @@ lock_rec_lock( ORed to either LOCK_GAP or LOCK_REC_NOT_GAP */ rec_t* rec, /* in: record */ dict_index_t* index, /* in: index of record */ - que_thr_t* thr) /* in: query thread */ + que_thr_t* thr) /* in: query thread */ { ulint err; @@ -2140,7 +2142,7 @@ lock_rec_lock( ut_ad(mode - (LOCK_MODE_MASK & mode) == LOCK_GAP || mode - (LOCK_MODE_MASK & mode) == LOCK_REC_NOT_GAP || mode - (LOCK_MODE_MASK & mode) == 0); - + if (lock_rec_lock_fast(impl, mode, rec, index, thr)) { /* We try a simplified and faster subroutine for the most @@ -2171,9 +2173,9 @@ lock_rec_has_to_wait_in_queue( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - ut_ad(lock_get_wait(wait_lock)); + ut_ad(lock_get_wait(wait_lock)); ut_ad(lock_get_type(wait_lock) == LOCK_REC); - + space = wait_lock->un_member.rec_lock.space; page_no = wait_lock->un_member.rec_lock.page_no; heap_no = lock_rec_find_set_bit(wait_lock); @@ -2183,9 +2185,9 @@ lock_rec_has_to_wait_in_queue( while (lock != wait_lock) { if (lock_rec_get_nth_bit(lock, heap_no) - && lock_has_to_wait(wait_lock, lock)) { + && lock_has_to_wait(wait_lock, lock)) { - return(TRUE); + return(TRUE); } lock = lock_rec_get_next_on_page(lock); @@ -2209,23 +2211,23 @@ lock_grant( lock_reset_lock_and_trx_wait(lock); - if (lock_get_mode(lock) == LOCK_AUTO_INC) { + if (lock_get_mode(lock) == LOCK_AUTO_INC) { - if (lock->trx->auto_inc_lock != NULL) { - fprintf(stderr, - "InnoDB: Error: trx already had an AUTO-INC lock!\n"); - } + if (lock->trx->auto_inc_lock != NULL) { + fprintf(stderr, + "InnoDB: Error: trx already had an AUTO-INC lock!\n"); + } - /* Store pointer to lock to trx so that we know to - release it at the end of the SQL statement */ + /* Store pointer to lock to trx so that we know to + release it at the end of the SQL statement */ - lock->trx->auto_inc_lock = lock; - } + lock->trx->auto_inc_lock = lock; + } #ifdef UNIV_DEBUG if (lock_print_waits) { fprintf(stderr, "Lock wait for trx %lu ends\n", - (ulong) ut_dulint_get_low(lock->trx->id)); + (ulong) ut_dulint_get_low(lock->trx->id)); } #endif /* UNIV_DEBUG */ @@ -2233,8 +2235,8 @@ lock_grant( as a victim, then our original transaction may not be in the TRX_QUE_LOCK_WAIT state, and there is no need to end the lock wait for it */ - - if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) { + + if (lock->trx->que_state == TRX_QUE_LOCK_WAIT) { trx_end_lock_wait(lock->trx); } } @@ -2265,7 +2267,7 @@ lock_rec_cancel( trx_end_lock_wait(lock->trx); } - + /***************************************************************** Removes a record lock request, waiting or granted, from the queue and grants locks to other transactions in the queue if they now are entitled @@ -2283,7 +2285,7 @@ lock_rec_dequeue_from_page( ulint page_no; lock_t* lock; trx_t* trx; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ @@ -2304,7 +2306,7 @@ lock_rec_dequeue_from_page( lock = lock_rec_get_first_on_page_addr(space, page_no); - while (lock != NULL) { + while (lock != NULL) { if (lock_get_wait(lock) && !lock_rec_has_to_wait_in_queue(lock)) { @@ -2314,7 +2316,7 @@ lock_rec_dequeue_from_page( lock = lock_rec_get_next_on_page(lock); } -} +} /***************************************************************** Removes a record lock request, waiting or granted, from the queue. */ @@ -2328,14 +2330,14 @@ lock_rec_discard( ulint space; ulint page_no; trx_t* trx; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ ut_ad(lock_get_type(in_lock) == LOCK_REC); trx = in_lock->trx; - + space = in_lock->un_member.rec_lock.space; page_no = in_lock->un_member.rec_lock.page_no; @@ -2359,11 +2361,11 @@ lock_rec_free_all_from_discard_page( ulint page_no; lock_t* lock; lock_t* next_lock; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - + space = buf_frame_get_space_id(page); page_no = buf_frame_get_page_no(page); @@ -2374,12 +2376,12 @@ lock_rec_free_all_from_discard_page( ut_ad(!lock_get_wait(lock)); next_lock = lock_rec_get_next_on_page(lock); - + lock_rec_discard(lock); - + lock = next_lock; } -} +} /*============= RECORD LOCK MOVING AND INHERITING ===================*/ @@ -2400,7 +2402,7 @@ lock_rec_reset_and_release_wait( #endif /* UNIV_SYNC_DEBUG */ heap_no = rec_get_heap_no(rec, page_rec_is_comp(rec)); - + lock = lock_rec_get_first(rec); while (lock != NULL) { @@ -2412,7 +2414,7 @@ lock_rec_reset_and_release_wait( lock = lock_rec_get_next(rec, lock); } -} +} /***************************************************************** Makes a record to inherit the locks (except LOCK_INSERT_INTENTION type) @@ -2431,7 +2433,7 @@ lock_rec_inherit_to_gap( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - + lock = lock_rec_get_first(rec); /* If srv_locks_unsafe_for_binlog is TRUE, we do not want locks set @@ -2441,17 +2443,17 @@ lock_rec_inherit_to_gap( while (lock != NULL) { if (!lock_rec_get_insert_intention(lock) - && !(srv_locks_unsafe_for_binlog - && lock_get_mode(lock) == LOCK_X)) { - + && !(srv_locks_unsafe_for_binlog + && lock_get_mode(lock) == LOCK_X)) { + lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock) - | LOCK_GAP, - heir, lock->index, lock->trx); - } - + | LOCK_GAP, + heir, lock->index, lock->trx); + } + lock = lock_rec_get_next(rec, lock); } -} +} /***************************************************************** Makes a record to inherit the gap locks (except LOCK_INSERT_INTENTION type) @@ -2469,22 +2471,22 @@ lock_rec_inherit_to_gap_if_gap_lock( #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - + lock = lock_rec_get_first(rec); while (lock != NULL) { if (!lock_rec_get_insert_intention(lock) - && (page_rec_is_supremum(rec) - || !lock_rec_get_rec_not_gap(lock))) { - + && (page_rec_is_supremum(rec) + || !lock_rec_get_rec_not_gap(lock))) { + lock_rec_add_to_queue(LOCK_REC | lock_get_mode(lock) - | LOCK_GAP, - heir, lock->index, lock->trx); - } + | LOCK_GAP, + heir, lock->index, lock->trx); + } lock = lock_rec_get_next(rec, lock); } -} +} /***************************************************************** Moves the locks of a record to another record and resets the lock bits of @@ -2501,25 +2503,25 @@ lock_rec_move( lock_t* lock; ulint heap_no; ulint type_mode; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ heap_no = rec_get_heap_no(donator, comp); - + lock = lock_rec_get_first(donator); ut_ad(lock_rec_get_first(receiver) == NULL); while (lock != NULL) { type_mode = lock->type_mode; - + lock_rec_reset_nth_bit(lock, heap_no); if (lock_get_wait(lock)) { lock_reset_lock_and_trx_wait(lock); - } + } /* Note that we FIRST reset the bit, and then set the lock: the function works also if donator == receiver */ @@ -2530,7 +2532,7 @@ lock_rec_move( } ut_ad(lock_rec_get_first(donator) == NULL); -} +} /***************************************************************** Updates the lock table when we have reorganized a page. NOTE: we copy @@ -2565,13 +2567,13 @@ lock_move_reorganize_page( } heap = mem_heap_create(256); - + /* Copy first all the locks on the page to heap and reset the bitmaps in the original locks; chain the copies of the locks using the trx_locks field in them. */ UT_LIST_INIT(old_locks); - + while (lock != NULL) { /* Make a copy of the lock */ @@ -2584,13 +2586,13 @@ lock_move_reorganize_page( if (lock_get_wait(lock)) { lock_reset_lock_and_trx_wait(lock); - } + } lock = lock_rec_get_next_on_page(lock); } sup = page_get_supremum_rec(page); - + lock = UT_LIST_GET_FIRST(old_locks); comp = page_is_comp(page); @@ -2601,7 +2603,7 @@ lock_move_reorganize_page( supremum of the page; the infimum may carry locks if an update of a record is occurring on the page, and its locks were temporarily stored on the infimum */ - + page_cur_set_before_first(page, &cur1); page_cur_set_before_first(old_page, &cur2); @@ -2649,9 +2651,9 @@ lock_move_reorganize_page( mem_heap_free(heap); -/* ut_ad(lock_rec_validate_page(buf_frame_get_space_id(page), +/* ut_ad(lock_rec_validate_page(buf_frame_get_space_id(page), buf_frame_get_page_no(page))); */ -} +} /***************************************************************** Moves the explicit locks on user records to another page if a record @@ -2683,13 +2685,13 @@ lock_move_rec_list_end( does not reuse locks if there are waiters in the queue. */ sup = page_get_supremum_rec(page); - + lock = lock_rec_get_first_on_page(page); comp = page_is_comp(page); while (lock != NULL) { - + page_cur_position(rec, &cur1); if (page_cur_is_before_first(&cur1)) { @@ -2698,7 +2700,7 @@ lock_move_rec_list_end( page_cur_set_before_first(new_page, &cur2); page_cur_move_to_next(&cur2); - + /* Copy lock requests on user records to new page and reset the lock bits on the old */ @@ -2717,7 +2719,7 @@ lock_move_rec_list_end( if (lock_get_wait(lock)) { lock_reset_lock_and_trx_wait(lock); - } + } lock_rec_add_to_queue(type_mode, page_cur_get_rec(&cur2), @@ -2730,14 +2732,14 @@ lock_move_rec_list_end( lock = lock_rec_get_next_on_page(lock); } - + lock_mutex_exit_kernel(); /* ut_ad(lock_rec_validate_page(buf_frame_get_space_id(page), buf_frame_get_page_no(page))); ut_ad(lock_rec_validate_page(buf_frame_get_space_id(new_page), buf_frame_get_page_no(new_page))); */ -} +} /***************************************************************** Moves the explicit locks on user records to another page if a record @@ -2770,7 +2772,7 @@ lock_move_rec_list_start( ut_ad(page == buf_frame_align(rec)); while (lock != NULL) { - + page_cur_set_before_first(page, &cur1); page_cur_move_to_next(&cur1); @@ -2795,7 +2797,7 @@ lock_move_rec_list_start( if (lock_get_wait(lock)) { lock_reset_lock_and_trx_wait(lock); - } + } lock_rec_add_to_queue(type_mode, page_cur_get_rec(&cur2), @@ -2808,14 +2810,14 @@ lock_move_rec_list_start( lock = lock_rec_get_next_on_page(lock); } - + lock_mutex_exit_kernel(); /* ut_ad(lock_rec_validate_page(buf_frame_get_space_id(page), buf_frame_get_page_no(page))); ut_ad(lock_rec_validate_page(buf_frame_get_space_id(new_page), buf_frame_get_page_no(new_page))); */ -} +} /***************************************************************** Updates the lock table when a page is split to the right. */ @@ -2836,7 +2838,7 @@ lock_update_split_right( lock_rec_move(page_get_supremum_rec(right_page), page_get_supremum_rec(left_page), comp); - + /* Inherit the locks to the supremum of left page from the successor of the infimum on right page */ @@ -2844,7 +2846,7 @@ lock_update_split_right( page_rec_get_next(page_get_infimum_rec(right_page))); lock_mutex_exit_kernel(); -} +} /***************************************************************** Updates the lock table when a page is merged to the right. */ @@ -2858,7 +2860,7 @@ lock_update_merge_right( discarded */ { lock_mutex_enter_kernel(); - + /* Inherit the locks from the supremum of the left page to the original successor of infimum on the right page, to which the left page was merged */ @@ -2869,7 +2871,7 @@ lock_update_merge_right( waiting transactions */ lock_rec_reset_and_release_wait(page_get_supremum_rec(left_page)); - + lock_rec_free_all_from_discard_page(left_page); lock_mutex_exit_kernel(); @@ -2937,7 +2939,7 @@ lock_update_split_left( page_t* left_page) /* in: left page */ { lock_mutex_enter_kernel(); - + /* Inherit the locks to the supremum of the left page from the successor of the infimum on the right page */ @@ -2985,7 +2987,7 @@ lock_update_merge_left( /* Move the locks from the supremum of right page to the supremum of the left page */ - + lock_rec_move(left_supremum, page_get_supremum_rec(right_page), comp); lock_rec_free_all_from_discard_page(right_page); @@ -3003,13 +3005,13 @@ lock_rec_reset_and_inherit_gap_locks( rec_t* heir, /* in: heir record */ rec_t* rec) /* in: record */ { - mutex_enter(&kernel_mutex); + mutex_enter(&kernel_mutex); lock_rec_reset_and_release_wait(heir); - + lock_rec_inherit_to_gap(heir, rec); - mutex_exit(&kernel_mutex); + mutex_exit(&kernel_mutex); } /***************************************************************** @@ -3024,7 +3026,7 @@ lock_update_discard( rec_t* rec; lock_mutex_enter_kernel(); - + if (NULL == lock_rec_get_first_on_page(page)) { /* No locks exist on page, nothing to do */ @@ -3032,7 +3034,7 @@ lock_update_discard( return; } - + /* Inherit all the locks on the page to the record and reset all the locks on the page */ @@ -3049,7 +3051,7 @@ lock_update_discard( break; } - + rec = page_rec_get_next(rec); } @@ -3092,11 +3094,11 @@ lock_update_delete( /* Reset the lock bits on rec and release waiting transactions */ - lock_rec_reset_and_release_wait(rec); + lock_rec_reset_and_release_wait(rec); lock_mutex_exit_kernel(); } - + /************************************************************************* Stores on the page infimum record the explicit locks of another record. This function is used to store the lock state of a record when it is @@ -3116,10 +3118,10 @@ lock_rec_store_on_page_infimum( ut_ad(page == buf_frame_align(rec)); lock_mutex_enter_kernel(); - + lock_rec_move(page_get_infimum_rec(page), rec, page_is_comp(page)); - lock_mutex_exit_kernel(); + lock_mutex_exit_kernel(); } /************************************************************************* @@ -3132,7 +3134,7 @@ lock_rec_restore_from_page_infimum( rec_t* rec, /* in: record whose lock state is restored */ page_t* page) /* in: page (rec is not necessarily on this page) whose infimum stored the lock state; lock bits are - reset on the infimum */ + reset on the infimum */ { ulint comp; lock_mutex_enter_kernel(); @@ -3140,7 +3142,7 @@ lock_rec_restore_from_page_infimum( ut_ad(!comp == !page_rec_is_comp(rec)); lock_rec_move(rec, page_get_infimum_rec(page), comp); - + lock_mutex_exit_kernel(); } @@ -3206,7 +3208,7 @@ retry: return(TRUE); } - + return(FALSE); } @@ -3230,7 +3232,7 @@ lock_deadlock_recursive( ulint* cost, /* in/out: number of calculation steps thus far: if this exceeds LOCK_MAX_N_STEPS_... we return LOCK_VICTIM_IS_START */ - uint depth) /* in: recursion depth: if this exceeds + ulint depth) /* in: recursion depth: if this exceeds LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK, we return LOCK_VICTIM_IS_START */ { @@ -3238,12 +3240,12 @@ lock_deadlock_recursive( ulint bit_no = ULINT_UNDEFINED; trx_t* lock_trx; ulint ret; - + ut_a(trx && start && wait_lock); #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - + if (trx->deadlock_mark == 1) { /* We have already exhaustively searched the subtree starting from this trx */ @@ -3296,7 +3298,7 @@ lock_deadlock_recursive( /* We came back to the recursion starting point: a deadlock detected */ FILE* ef = lock_latest_err_file; - + rewind(ef); ut_print_timestamp(ef); @@ -3306,28 +3308,28 @@ lock_deadlock_recursive( fputs( "*** (1) WAITING FOR THIS LOCK TO BE GRANTED:\n", ef); - + if (lock_get_type(wait_lock) == LOCK_REC) { lock_rec_print(ef, wait_lock); } else { lock_table_print(ef, wait_lock); } - + fputs("*** (2) TRANSACTION:\n", ef); trx_print(ef, lock->trx, 3000); fputs("*** (2) HOLDS THE LOCK(S):\n", ef); - + if (lock_get_type(lock) == LOCK_REC) { lock_rec_print(ef, lock); } else { lock_table_print(ef, lock); } - + fputs( "*** (2) WAITING FOR THIS LOCK TO BE GRANTED:\n", ef); - + if (lock_get_type(start->wait_lock) == LOCK_REC) { lock_rec_print(ef, start->wait_lock); @@ -3347,20 +3349,20 @@ lock_deadlock_recursive( back it */ return(LOCK_VICTIM_IS_START); - } + } lock_deadlock_found = TRUE; /* Let us choose the transaction of wait_lock as a victim to try to avoid deadlocking our recursion starting point transaction */ - + fputs("*** WE ROLL BACK TRANSACTION (1)\n", ef); - + wait_lock->trx->was_chosen_as_deadlock_victim = TRUE; - + lock_cancel_waiting_and_release(wait_lock); /* Since trx and wait_lock are no longer @@ -3372,7 +3374,7 @@ lock_deadlock_recursive( return(LOCK_VICTIM_IS_OTHER); } - + if (lock_trx->que_state == TRX_QUE_LOCK_WAIT) { /* Another trx ahead has requested lock in an @@ -3468,7 +3470,7 @@ lock_table_remove_low( UT_LIST_REMOVE(trx_locks, trx->trx_locks, lock); UT_LIST_REMOVE(un_member.tab_lock.locks, table->locks, lock); -} +} /************************************************************************* Enqueues a waiting request for a table lock which cannot be granted @@ -3490,11 +3492,11 @@ lock_table_enqueue_waiting( { lock_t* lock; trx_t* trx; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ - + /* Test if there already is some other reason to suspend thread: we do not enqueue a lock request if the query thread should be stopped anyway */ @@ -3517,7 +3519,7 @@ lock_table_enqueue_waiting( "InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr); } - + /* Enqueue the lock request that will wait to be granted */ lock = lock_table_create(table, mode | LOCK_WAIT, trx); @@ -3536,10 +3538,10 @@ lock_table_enqueue_waiting( if (trx->wait_lock == NULL) { /* Deadlock resolution chose another transaction as a victim, and we accidentally got our lock granted! */ - + return(DB_SUCCESS); } - + trx->que_state = TRX_QUE_LOCK_WAIT; trx->was_chosen_as_deadlock_victim = FALSE; trx->wait_started = time(NULL); @@ -3573,11 +3575,11 @@ lock_table_other_has_incompatible( while (lock != NULL) { - if ((lock->trx != trx) - && (!lock_mode_compatible(lock_get_mode(lock), mode)) - && (wait || !(lock_get_wait(lock)))) { + if ((lock->trx != trx) + && (!lock_mode_compatible(lock_get_mode(lock), mode)) + && (wait || !(lock_get_wait(lock)))) { - return(TRUE); + return(TRUE); } lock = UT_LIST_GET_PREV(un_member.tab_lock.locks, lock); @@ -3603,7 +3605,7 @@ lock_table( { trx_t* trx; ulint err; - + ut_ad(table && thr); if (flags & BTR_NO_LOCKING_FLAG) { @@ -3630,12 +3632,12 @@ lock_table( other transactions have in the table lock queue. */ if (lock_table_other_has_incompatible(trx, LOCK_WAIT, table, mode)) { - + /* Another trx has a request on the table in an incompatible mode: this trx may have to wait */ err = lock_table_enqueue_waiting(mode | flags, table, thr); - + lock_mutex_exit_kernel(); return(err); @@ -3688,8 +3690,8 @@ lock_table_has_to_wait_in_queue( dict_table_t* table; lock_t* lock; - ut_ad(lock_get_wait(wait_lock)); - + ut_ad(lock_get_wait(wait_lock)); + table = wait_lock->un_member.tab_lock.table; lock = UT_LIST_GET_FIRST(table->locks); @@ -3698,7 +3700,7 @@ lock_table_has_to_wait_in_queue( if (lock_has_to_wait(wait_lock, lock)) { - return(TRUE); + return(TRUE); } lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock); @@ -3720,7 +3722,7 @@ lock_table_dequeue( they are now qualified to it */ { lock_t* lock; - + #ifdef UNIV_SYNC_DEBUG ut_ad(mutex_own(&kernel_mutex)); #endif /* UNIV_SYNC_DEBUG */ @@ -3744,7 +3746,7 @@ lock_table_dequeue( lock = UT_LIST_GET_NEXT(un_member.tab_lock.locks, lock); } -} +} /*=========================== LOCK RELEASE ==============================*/ @@ -3756,13 +3758,14 @@ to a lock. */ void lock_rec_unlock( /*============*/ - trx_t* trx, /* in: transaction that has set a record + 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; - ulint heap_no; + lock_t* lock; + lock_t* release_lock = NULL; + ulint heap_no; ut_ad(trx && rec); @@ -3772,21 +3775,23 @@ lock_rec_unlock( lock = lock_rec_get_first(rec); - /* Remove the record lock */ + /* 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_rec_reset_nth_bit(lock, heap_no); - - break; } lock = lock_rec_get_next(rec, lock); } - if (UNIV_UNLIKELY(lock == NULL)) { + /* 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, @@ -3812,7 +3817,7 @@ lock_rec_unlock( } mutex_exit(&kernel_mutex); -} +} /************************************************************************* Releases a table lock. @@ -3866,7 +3871,7 @@ lock_release_off_kernel( #endif /* UNIV_SYNC_DEBUG */ lock = UT_LIST_GET_LAST(trx->trx_locks); - + count = 0; while (lock != NULL) { @@ -3874,21 +3879,21 @@ lock_release_off_kernel( count++; if (lock_get_type(lock) == LOCK_REC) { - + lock_rec_dequeue_from_page(lock); } else { ut_ad(lock_get_type(lock) & LOCK_TABLE); if (lock_get_mode(lock) != LOCK_IS - && 0 != ut_dulint_cmp(trx->undo_no, - ut_dulint_zero)) { + && 0 != ut_dulint_cmp(trx->undo_no, + ut_dulint_zero)) { - /* The trx may have modified the table. - We block the use of the MySQL query cache - for all currently active transactions. */ + /* The trx may have modified the table. We + block the use of the MySQL query cache for + all currently active transactions. */ table = lock->un_member.tab_lock.table; - + table->query_cache_inv_trx_id = trx_sys->max_trx_id; } @@ -3905,7 +3910,7 @@ lock_release_off_kernel( lock_mutex_enter_kernel(); count = 0; - } + } lock = UT_LIST_GET_LAST(trx->trx_locks); } @@ -3929,7 +3934,7 @@ lock_cancel_waiting_and_release( #endif /* UNIV_SYNC_DEBUG */ if (lock_get_type(lock) == LOCK_REC) { - + lock_rec_dequeue_from_page(lock); } else { ut_ad(lock_get_type(lock) & LOCK_TABLE); @@ -3964,20 +3969,20 @@ lock_reset_all_on_table_for_trx( #endif /* UNIV_SYNC_DEBUG */ lock = UT_LIST_GET_LAST(trx->trx_locks); - + while (lock != NULL) { prev_lock = UT_LIST_GET_PREV(trx_locks, lock); - + if (lock_get_type(lock) == LOCK_REC && lock->index->table == table) { ut_a(!lock_get_wait(lock)); - + lock_rec_discard(lock); } else if (lock_get_type(lock) & LOCK_TABLE && lock->un_member.tab_lock.table == table) { ut_a(!lock_get_wait(lock)); - + lock_table_remove_low(lock); } @@ -4000,7 +4005,7 @@ lock_reset_all_on_table( lock = UT_LIST_GET_FIRST(table->locks); - while (lock) { + while (lock) { ut_a(!lock_get_wait(lock)); lock_reset_all_on_table_for_trx(table, lock->trx); @@ -4051,8 +4056,8 @@ lock_table_print( } putc('\n', file); -} - +} + /************************************************************************* Prints info of a record lock. */ @@ -4078,15 +4083,15 @@ lock_rec_print( ut_a(lock_get_type(lock) == LOCK_REC); space = lock->un_member.rec_lock.space; - page_no = lock->un_member.rec_lock.page_no; + page_no = lock->un_member.rec_lock.page_no; fprintf(file, "RECORD LOCKS space id %lu page no %lu n bits %lu ", - (ulong) space, (ulong) page_no, - (ulong) lock_rec_get_n_bits(lock)); + (ulong) space, (ulong) page_no, + (ulong) lock_rec_get_n_bits(lock)); dict_index_name_print(file, lock->trx, lock->index); fprintf(file, " trx id %lu %lu", - (ulong) (lock->trx)->id.high, - (ulong) (lock->trx)->id.low); + (ulong) (lock->trx)->id.high, + (ulong) (lock->trx)->id.low); if (lock_get_mode(lock) == LOCK_S) { fputs(" lock mode S", file); @@ -4119,7 +4124,7 @@ lock_rec_print( /* If the page is not in the buffer pool, we cannot load it because we have the kernel mutex and ibuf operations would break the latching order */ - + page = buf_page_get_gen(space, page_no, RW_NO_LATCH, NULL, BUF_GET_IF_IN_POOL, __FILE__, __LINE__, &mtr); @@ -4130,12 +4135,12 @@ lock_rec_print( /* Let us try to get an X-latch. If the current thread is holding an X-latch on the page, we cannot get an S-latch. */ - + page = buf_page_get_nowait(space, page_no, RW_X_LATCH, &mtr); } } - + if (page) { #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK); @@ -4166,6 +4171,7 @@ lock_rec_print( } } +#ifndef UNIV_HOTBACKUP /************************************************************************* Calculates the number of record lock structs in the record lock hash table. */ static @@ -4195,7 +4201,6 @@ lock_get_n_rec_locks(void) return(n_locks); } -#ifndef UNIV_HOTBACKUP /************************************************************************* Prints info of locks for all transactions. */ @@ -4213,7 +4218,7 @@ lock_print_info_summary( if (lock_deadlock_found) { fputs( -"------------------------\n" +"------------------------\n" "LATEST DETECTED DEADLOCK\n" "------------------------\n", file); @@ -4221,13 +4226,13 @@ lock_print_info_summary( } fputs( -"------------\n" +"------------\n" "TRANSACTIONS\n" "------------\n", file); fprintf(file, "Trx id counter %lu %lu\n", - (ulong) ut_dulint_get_high(trx_sys->max_trx_id), - (ulong) ut_dulint_get_low(trx_sys->max_trx_id)); + (ulong) ut_dulint_get_high(trx_sys->max_trx_id), + (ulong) ut_dulint_get_low(trx_sys->max_trx_id)); fprintf(file, "Purge done for trx's n:o < %lu %lu undo n:o < %lu %lu\n", @@ -4274,7 +4279,7 @@ lock_print_info_all_transactions( fputs("---", file); trx_print(file, trx, 600); } - + trx = UT_LIST_GET_NEXT(mysql_trx_list, trx); } @@ -4287,7 +4292,7 @@ loop: reading a database page in below, variable trx may be obsolete now and we must loop through the trx list to get probably the same trx, or some other trx. */ - + while (trx && (i < nth_trx)) { trx = UT_LIST_GET_NEXT(trx_list, trx); i++; @@ -4305,15 +4310,15 @@ loop: if (nth_lock == 0) { fputs("---", file); trx_print(file, trx, 600); - - if (trx->read_view) { + + if (trx->read_view) { fprintf(file, - "Trx read view will not see trx with id >= %lu %lu, sees < %lu %lu\n", - (ulong) ut_dulint_get_high(trx->read_view->low_limit_id), - (ulong) ut_dulint_get_low(trx->read_view->low_limit_id), - (ulong) ut_dulint_get_high(trx->read_view->up_limit_id), - (ulong) ut_dulint_get_low(trx->read_view->up_limit_id)); - } +"Trx read view will not see trx with id >= %lu %lu, sees < %lu %lu\n", + (ulong) ut_dulint_get_high(trx->read_view->low_limit_id), + (ulong) ut_dulint_get_low(trx->read_view->low_limit_id), + (ulong) ut_dulint_get_high(trx->read_view->up_limit_id), + (ulong) ut_dulint_get_low(trx->read_view->up_limit_id)); + } if (trx->que_state == TRX_QUE_LOCK_WAIT) { fprintf(file, @@ -4331,17 +4336,17 @@ loop: } if (!srv_print_innodb_lock_monitor) { - nth_trx++; - goto loop; + nth_trx++; + goto loop; } i = 0; /* Look at the note about the trx loop above why we loop here: lock may be an obsolete pointer now. */ - + lock = UT_LIST_GET_FIRST(trx->trx_locks); - + while (lock && (i < nth_lock)) { lock = UT_LIST_GET_NEXT(trx_locks, lock); i++; @@ -4356,14 +4361,14 @@ loop: if (lock_get_type(lock) == LOCK_REC) { space = lock->un_member.rec_lock.space; - page_no = lock->un_member.rec_lock.page_no; + page_no = lock->un_member.rec_lock.page_no; - if (load_page_first) { + if (load_page_first) { lock_mutex_exit_kernel(); innobase_mysql_end_print_arbitrary_thd(); mtr_start(&mtr); - + page = buf_page_get_with_no_latch(space, page_no, &mtr); mtr_commit(&mtr); @@ -4375,11 +4380,11 @@ loop: goto loop; } - + lock_rec_print(file, lock); } else { ut_ad(lock_get_type(lock) & LOCK_TABLE); - + lock_table_print(file, lock); } @@ -4391,7 +4396,7 @@ loop: fputs( "10 LOCKS PRINTED FOR THIS TRX: SUPPRESSING FURTHER PRINTS\n", file); - + nth_trx++; nth_lock = 0; @@ -4423,13 +4428,13 @@ lock_table_queue_validate( while (lock) { ut_a(((lock->trx)->conc_state == TRX_ACTIVE) - || ((lock->trx)->conc_state == TRX_PREPARED) - || ((lock->trx)->conc_state == TRX_COMMITTED_IN_MEMORY)); - + || ((lock->trx)->conc_state == TRX_PREPARED) + || ((lock->trx)->conc_state == TRX_COMMITTED_IN_MEMORY)); + if (!lock_get_wait(lock)) { ut_a(!is_waiting); - + ut_a(!lock_table_other_has_incompatible(lock->trx, 0, table, lock_get_mode(lock))); } else { @@ -4455,7 +4460,7 @@ lock_rec_queue_validate( dict_index_t* index, /* in: index, or NULL if not known */ const ulint* offsets)/* in: rec_get_offsets(rec, index) */ { - trx_t* impl_trx; + trx_t* impl_trx; lock_t* lock; ut_a(rec); @@ -4470,12 +4475,11 @@ lock_rec_queue_validate( while (lock) { ut_a(lock->trx->conc_state == TRX_ACTIVE - || lock->trx->conc_state == TRX_PREPARED - || lock->trx->conc_state - == TRX_COMMITTED_IN_MEMORY); - + || lock->trx->conc_state == TRX_PREPARED + || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY); + ut_a(trx_in_trx_list(lock->trx)); - + if (lock_get_wait(lock)) { ut_a(lock_rec_has_to_wait_in_queue(lock)); } @@ -4489,11 +4493,11 @@ lock_rec_queue_validate( lock_mutex_exit_kernel(); - return(TRUE); + return(TRUE); } if (index && (index->type & DICT_CLUSTERED)) { - + impl_trx = lock_clust_rec_some_has_impl(rec, index, offsets); if (impl_trx && lock_rec_other_has_expl_req(LOCK_S, 0, @@ -4505,11 +4509,11 @@ lock_rec_queue_validate( } if (index && !(index->type & DICT_CLUSTERED)) { - + /* The kernel mutex may get released temporarily in the next function call: we have to release lock table mutex to obey the latching order */ - + impl_trx = lock_sec_rec_some_has_impl_off_kernel( rec, index, offsets); @@ -4525,10 +4529,10 @@ lock_rec_queue_validate( while (lock) { ut_a(lock->trx->conc_state == TRX_ACTIVE - || lock->trx->conc_state == TRX_PREPARED - || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY); + || lock->trx->conc_state == TRX_PREPARED + || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY); ut_a(trx_in_trx_list(lock->trx)); - + if (index) { ut_a(lock->index == index); } @@ -4536,7 +4540,7 @@ lock_rec_queue_validate( if (!lock_rec_get_gap(lock) && !lock_get_wait(lock)) { ulint mode; - + if (lock_get_mode(lock) == LOCK_S) { mode = LOCK_X; } else { @@ -4586,14 +4590,14 @@ lock_rec_validate_page( #endif /* UNIV_SYNC_DEBUG */ mtr_start(&mtr); - + page = buf_page_get(space, page_no, RW_X_LATCH, &mtr); #ifdef UNIV_SYNC_DEBUG buf_page_dbg_add_level(page, SYNC_NO_ORDER_CHECK); #endif /* UNIV_SYNC_DEBUG */ lock_mutex_enter_kernel(); -loop: +loop: lock = lock_rec_get_first_on_page_addr(space, page_no); if (!lock) { @@ -4611,9 +4615,9 @@ loop: ut_a(trx_in_trx_list(lock->trx)); ut_a(lock->trx->conc_state == TRX_ACTIVE - || lock->trx->conc_state == TRX_PREPARED - || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY); - + || lock->trx->conc_state == TRX_PREPARED + || lock->trx->conc_state == TRX_COMMITTED_IN_MEMORY); + for (i = nth_bit; i < lock_rec_get_n_bits(lock); i++) { if (i == 1 || lock_rec_get_nth_bit(lock, i)) { @@ -4652,8 +4656,8 @@ function_exit: mem_heap_free(heap); } return(TRUE); -} - +} + /************************************************************************* Validates the lock system. */ @@ -4670,22 +4674,22 @@ lock_validate(void) ulint i; lock_mutex_enter_kernel(); - + trx = UT_LIST_GET_FIRST(trx_sys->trx_list); while (trx) { lock = UT_LIST_GET_FIRST(trx->trx_locks); - + while (lock) { if (lock_get_type(lock) & LOCK_TABLE) { - + lock_table_queue_validate( lock->un_member.tab_lock.table); } - + lock = UT_LIST_GET_NEXT(trx_locks, lock); } - + trx = UT_LIST_GET_NEXT(trx_list, trx); } @@ -4701,7 +4705,7 @@ lock_validate(void) space = lock->un_member.rec_lock.space; page_no = lock->un_member.rec_lock.page_no; - + if (ut_dulint_cmp( ut_dulint_create(space, page_no), limit) >= 0) { @@ -4715,7 +4719,7 @@ lock_validate(void) break; } - + lock_mutex_exit_kernel(); lock_rec_validate_page(space, page_no); @@ -4788,7 +4792,7 @@ lock_rec_insert_check_and_lock( page_update_max_trx_id(buf_frame_align(rec), thr_get_trx(thr)->id); } - + return(DB_SUCCESS); } @@ -4879,8 +4883,7 @@ lock_rec_convert_impl_to_expl( impl_trx)) { lock_rec_add_to_queue(LOCK_REC | LOCK_X - | LOCK_REC_NOT_GAP, rec, index, - impl_trx); + | LOCK_REC_NOT_GAP, rec, index, impl_trx); } } } @@ -4952,7 +4955,7 @@ lock_sec_rec_modify_check_and_lock( que_thr_t* thr) /* in: query thread */ { ulint err; - + if (flags & BTR_NO_LOCKING_FLAG) { return(DB_SUCCESS); @@ -5036,9 +5039,9 @@ lock_sec_rec_read_check_and_lock( lock_mutex_enter_kernel(); ut_ad(mode != LOCK_X - || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); + || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); ut_ad(mode != LOCK_S - || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); + || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); /* Some transaction may have an implicit x-lock on the record only if the max trx id for the page >= min trx id for the trx list or a @@ -5046,10 +5049,10 @@ lock_sec_rec_read_check_and_lock( if (((ut_dulint_cmp(page_get_max_trx_id(buf_frame_align(rec)), trx_list_get_min_trx_id()) >= 0) - || recv_recovery_is_on()) - && !page_rec_is_supremum(rec)) { + || recv_recovery_is_on()) + && !page_rec_is_supremum(rec)) { - lock_rec_convert_impl_to_expl(rec, index, offsets); + lock_rec_convert_impl_to_expl(rec, index, offsets); } err = lock_rec_lock(FALSE, mode | gap_mode, rec, index, thr); @@ -5104,12 +5107,12 @@ lock_clust_rec_read_check_and_lock( lock_mutex_enter_kernel(); ut_ad(mode != LOCK_X - || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); + || lock_table_has(thr_get_trx(thr), index->table, LOCK_IX)); ut_ad(mode != LOCK_S - || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); - + || lock_table_has(thr_get_trx(thr), index->table, LOCK_IS)); + if (!page_rec_is_supremum(rec)) { - + lock_rec_convert_impl_to_expl(rec, index, offsets); } |