mirror of
https://github.com/MariaDB/server.git
synced 2025-01-23 23:34:34 +01:00
050f14ac37
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''
532 lines
15 KiB
C
532 lines
15 KiB
C
/******************************************************
|
|
Cursor read
|
|
|
|
(c) 1997 Innobase Oy
|
|
|
|
Created 2/16/1997 Heikki Tuuri
|
|
*******************************************************/
|
|
|
|
#include "read0read.h"
|
|
|
|
#ifdef UNIV_NONINL
|
|
#include "read0read.ic"
|
|
#endif
|
|
|
|
#include "srv0srv.h"
|
|
#include "trx0sys.h"
|
|
|
|
/*
|
|
-------------------------------------------------------------------------------
|
|
FACT A: Cursor read view on a secondary index sees only committed versions
|
|
-------
|
|
of the records in the secondary index or those versions of rows created
|
|
by transaction which created a cursor before cursor was created even
|
|
if transaction which created the cursor has changed that clustered index page.
|
|
|
|
PROOF: We must show that read goes always to the clustered index record
|
|
to see that record is visible in the cursor read view. Consider e.g.
|
|
following table and SQL-clauses:
|
|
|
|
create table t1(a int not null, b int, primary key(a), index(b));
|
|
insert into t1 values (1,1),(2,2);
|
|
commit;
|
|
|
|
Now consider that we have a cursor for a query
|
|
|
|
select b from t1 where b >= 1;
|
|
|
|
This query will use secondary key on the table t1. Now after the first fetch
|
|
on this cursor if we do a update:
|
|
|
|
update t1 set b = 5 where b = 2;
|
|
|
|
Now second fetch of the cursor should not see record (2,5) instead it should
|
|
see record (2,2).
|
|
|
|
We also should show that if we have delete t1 where b = 5; we still
|
|
can see record (2,2).
|
|
|
|
When we access a secondary key record maximum transaction id is fetched
|
|
from this record and this trx_id is compared to up_limit_id in the view.
|
|
If trx_id in the record is greater or equal than up_limit_id in the view
|
|
cluster record is accessed. Because trx_id of the creating
|
|
transaction is stored when this view was created to the list of
|
|
trx_ids not seen by this read view previous version of the
|
|
record is requested to be built. This is build using clustered record.
|
|
If the secondary key record is delete marked it's corresponding
|
|
clustered record can be already be purged only if records
|
|
trx_id < low_limit_no. Purge can't remove any record deleted by a
|
|
transaction which was active when cursor was created. But, we still
|
|
may have a deleted secondary key record but no clustered record. But,
|
|
this is not a problem because this case is handled in
|
|
row_sel_get_clust_rec() function which is called
|
|
whenever we note that this read view does not see trx_id in the
|
|
record. Thus, we see correct version. Q. E. D.
|
|
|
|
-------------------------------------------------------------------------------
|
|
FACT B: Cursor read view on a clustered index sees only committed versions
|
|
-------
|
|
of the records in the clustered index or those versions of rows created
|
|
by transaction which created a cursor before cursor was created even
|
|
if transaction which created the cursor has changed that clustered index page.
|
|
|
|
PROOF: Consider e.g.following table and SQL-clauses:
|
|
|
|
create table t1(a int not null, b int, primary key(a));
|
|
insert into t1 values (1),(2);
|
|
commit;
|
|
|
|
Now consider that we have a cursor for a query
|
|
|
|
select a from t1 where a >= 1;
|
|
|
|
This query will use clustered key on the table t1. Now after the first fetch
|
|
on this cursor if we do a update:
|
|
|
|
update t1 set a = 5 where a = 2;
|
|
|
|
Now second fetch of the cursor should not see record (5) instead it should
|
|
see record (2).
|
|
|
|
We also should show that if we have execute delete t1 where a = 5; after
|
|
the cursor is opened we still can see record (2).
|
|
|
|
When accessing clustered record we always check if this read view sees
|
|
trx_id stored to clustered record. By default we don't see any changes
|
|
if record trx_id >= low_limit_id i.e. change was made transaction
|
|
which started after transaction which created the cursor. If row
|
|
was changed by the future transaction a previous version of the
|
|
clustered record is created. Thus we see only committed version in
|
|
this case. We see all changes made by committed transactions i.e.
|
|
record trx_id < up_limit_id. In this case we don't need to do anything,
|
|
we already see correct version of the record. We don't see any changes
|
|
made by active transaction except creating transaction. We have stored
|
|
trx_id of creating transaction to list of trx_ids when this view was
|
|
created. Thus we can easily see if this record was changed by the
|
|
creating transaction. Because we already have clustered record we can
|
|
access roll_ptr. Using this roll_ptr we can fetch undo record.
|
|
We can now check that undo_no of the undo record is less than undo_no of the
|
|
trancaction which created a view when cursor was created. We see this
|
|
clustered record only in case when record undo_no is less than undo_no
|
|
in the view. If this is not true we build based on undo_rec previous
|
|
version of the record. This record is found because purge can't remove
|
|
records accessed by active transaction. Thus we see correct version. Q. E. D.
|
|
-------------------------------------------------------------------------------
|
|
FACT C: Purge does not remove any delete marked row that is visible
|
|
-------
|
|
to cursor view.
|
|
|
|
TODO: proof this
|
|
|
|
*/
|
|
|
|
/*************************************************************************
|
|
Creates a read view object. */
|
|
UNIV_INLINE
|
|
read_view_t*
|
|
read_view_create_low(
|
|
/*=================*/
|
|
/* out, own: read view struct */
|
|
ulint n, /* in: number of cells in the trx_ids array */
|
|
mem_heap_t* heap) /* in: memory heap from which allocated */
|
|
{
|
|
read_view_t* view;
|
|
|
|
view = mem_heap_alloc(heap, sizeof(read_view_t));
|
|
|
|
view->n_trx_ids = n;
|
|
view->trx_ids = mem_heap_alloc(heap, n * sizeof(dulint));
|
|
|
|
return(view);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Makes a copy of the oldest existing read view, with the exception that also
|
|
the creating trx of the oldest view is set as not visible in the 'copied'
|
|
view. Opens a new view if no views currently exist. The view must be closed
|
|
with ..._close. This is used in purge. */
|
|
|
|
read_view_t*
|
|
read_view_oldest_copy_or_open_new(
|
|
/*==============================*/
|
|
/* out, own: read view struct */
|
|
dulint cr_trx_id, /* in: trx_id of creating
|
|
transaction, or (0, 0) used in purge*/
|
|
mem_heap_t* heap) /* in: memory heap from which
|
|
allocated */
|
|
{
|
|
read_view_t* old_view;
|
|
read_view_t* view_copy;
|
|
ibool needs_insert = TRUE;
|
|
ulint insert_done = 0;
|
|
ulint n;
|
|
ulint i;
|
|
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
ut_ad(mutex_own(&kernel_mutex));
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
old_view = UT_LIST_GET_LAST(trx_sys->view_list);
|
|
|
|
if (old_view == NULL) {
|
|
|
|
return(read_view_open_now(cr_trx_id, heap));
|
|
}
|
|
|
|
n = old_view->n_trx_ids;
|
|
|
|
if (ut_dulint_cmp(old_view->creator_trx_id,
|
|
ut_dulint_create(0,0)) != 0) {
|
|
n++;
|
|
} else {
|
|
needs_insert = FALSE;
|
|
}
|
|
|
|
view_copy = read_view_create_low(n, heap);
|
|
|
|
/* Insert the id of the creator in the right place of the descending
|
|
array of ids, if needs_insert is TRUE: */
|
|
|
|
i = 0;
|
|
while (i < n) {
|
|
if (needs_insert
|
|
&& (i >= old_view->n_trx_ids
|
|
|| ut_dulint_cmp(old_view->creator_trx_id,
|
|
read_view_get_nth_trx_id(old_view, i))
|
|
> 0)) {
|
|
|
|
read_view_set_nth_trx_id(view_copy, i,
|
|
old_view->creator_trx_id);
|
|
needs_insert = FALSE;
|
|
insert_done = 1;
|
|
} else {
|
|
read_view_set_nth_trx_id(view_copy, i,
|
|
read_view_get_nth_trx_id(old_view,
|
|
i - insert_done));
|
|
}
|
|
|
|
i++;
|
|
}
|
|
|
|
view_copy->creator_trx_id = cr_trx_id;
|
|
|
|
view_copy->low_limit_no = old_view->low_limit_no;
|
|
view_copy->low_limit_id = old_view->low_limit_id;
|
|
|
|
view_copy->can_be_too_old = FALSE;
|
|
|
|
if (n > 0) {
|
|
/* The last active transaction has the smallest id: */
|
|
view_copy->up_limit_id = read_view_get_nth_trx_id(
|
|
view_copy, n - 1);
|
|
} else {
|
|
view_copy->up_limit_id = old_view->up_limit_id;
|
|
}
|
|
|
|
UT_LIST_ADD_LAST(view_list, trx_sys->view_list, view_copy);
|
|
|
|
return(view_copy);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Opens a read view where exactly the transactions serialized before this
|
|
point in time are seen in the view. */
|
|
|
|
read_view_t*
|
|
read_view_open_now(
|
|
/*===============*/
|
|
/* out, own: read view struct */
|
|
dulint cr_trx_id, /* in: trx_id of creating
|
|
transaction, or (0, 0) used in
|
|
purge */
|
|
mem_heap_t* heap) /* in: memory heap from which
|
|
allocated */
|
|
{
|
|
read_view_t* view;
|
|
trx_t* trx;
|
|
ulint n;
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
ut_ad(mutex_own(&kernel_mutex));
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
view = read_view_create_low(UT_LIST_GET_LEN(trx_sys->trx_list), heap);
|
|
|
|
view->creator_trx_id = cr_trx_id;
|
|
view->type = VIEW_NORMAL;
|
|
view->undo_no = ut_dulint_create(0, 0);
|
|
|
|
/* No future transactions should be visible in the view */
|
|
|
|
view->low_limit_no = trx_sys->max_trx_id;
|
|
view->low_limit_id = view->low_limit_no;
|
|
|
|
view->can_be_too_old = FALSE;
|
|
|
|
n = 0;
|
|
trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
|
|
|
|
/* No active transaction should be visible, except cr_trx */
|
|
|
|
while (trx) {
|
|
if (ut_dulint_cmp(trx->id, cr_trx_id) != 0
|
|
&& (trx->conc_state == TRX_ACTIVE
|
|
|| trx->conc_state == TRX_PREPARED)) {
|
|
|
|
read_view_set_nth_trx_id(view, n, trx->id);
|
|
|
|
n++;
|
|
|
|
/* NOTE that a transaction whose trx number is <
|
|
trx_sys->max_trx_id can still be active, if it is
|
|
in the middle of its commit! Note that when a
|
|
transaction starts, we initialize trx->no to
|
|
ut_dulint_max. */
|
|
|
|
if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) {
|
|
|
|
view->low_limit_no = trx->no;
|
|
}
|
|
}
|
|
|
|
trx = UT_LIST_GET_NEXT(trx_list, trx);
|
|
}
|
|
|
|
view->n_trx_ids = n;
|
|
|
|
if (n > 0) {
|
|
/* The last active transaction has the smallest id: */
|
|
view->up_limit_id = read_view_get_nth_trx_id(view, n - 1);
|
|
} else {
|
|
view->up_limit_id = view->low_limit_id;
|
|
}
|
|
|
|
|
|
UT_LIST_ADD_FIRST(view_list, trx_sys->view_list, view);
|
|
|
|
return(view);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Closes a read view. */
|
|
|
|
void
|
|
read_view_close(
|
|
/*============*/
|
|
read_view_t* view) /* in: read view */
|
|
{
|
|
#ifdef UNIV_SYNC_DEBUG
|
|
ut_ad(mutex_own(&kernel_mutex));
|
|
#endif /* UNIV_SYNC_DEBUG */
|
|
UT_LIST_REMOVE(view_list, trx_sys->view_list, view);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Closes a consistent read view for MySQL. This function is called at an SQL
|
|
statement end if the trx isolation level is <= TRX_ISO_READ_COMMITTED. */
|
|
|
|
void
|
|
read_view_close_for_mysql(
|
|
/*======================*/
|
|
trx_t* trx) /* in: trx which has a read view */
|
|
{
|
|
ut_a(trx->global_read_view);
|
|
|
|
mutex_enter(&kernel_mutex);
|
|
|
|
read_view_close(trx->global_read_view);
|
|
|
|
mem_heap_empty(trx->global_read_view_heap);
|
|
|
|
trx->read_view = NULL;
|
|
trx->global_read_view = NULL;
|
|
|
|
mutex_exit(&kernel_mutex);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Prints a read view to stderr. */
|
|
|
|
void
|
|
read_view_print(
|
|
/*============*/
|
|
read_view_t* view) /* in: read view */
|
|
{
|
|
ulint n_ids;
|
|
ulint i;
|
|
|
|
if (view->type == VIEW_HIGH_GRANULARITY) {
|
|
fprintf(stderr,
|
|
"High-granularity read view undo_n:o %lu %lu\n",
|
|
(ulong) ut_dulint_get_high(view->undo_no),
|
|
(ulong) ut_dulint_get_low(view->undo_no));
|
|
} else {
|
|
fprintf(stderr, "Normal read view\n");
|
|
}
|
|
|
|
fprintf(stderr, "Read view low limit trx n:o %lu %lu\n",
|
|
(ulong) ut_dulint_get_high(view->low_limit_no),
|
|
(ulong) ut_dulint_get_low(view->low_limit_no));
|
|
|
|
fprintf(stderr, "Read view up limit trx id %lu %lu\n",
|
|
(ulong) ut_dulint_get_high(view->up_limit_id),
|
|
(ulong) ut_dulint_get_low(view->up_limit_id));
|
|
|
|
fprintf(stderr, "Read view low limit trx id %lu %lu\n",
|
|
(ulong) ut_dulint_get_high(view->low_limit_id),
|
|
(ulong) ut_dulint_get_low(view->low_limit_id));
|
|
|
|
fprintf(stderr, "Read view individually stored trx ids:\n");
|
|
|
|
n_ids = view->n_trx_ids;
|
|
|
|
for (i = 0; i < n_ids; i++) {
|
|
fprintf(stderr, "Read view trx id %lu %lu\n",
|
|
(ulong) ut_dulint_get_high(read_view_get_nth_trx_id(view, i)),
|
|
(ulong) ut_dulint_get_low(read_view_get_nth_trx_id(view, i)));
|
|
}
|
|
}
|
|
|
|
/*************************************************************************
|
|
Create a high-granularity consistent cursor view for mysql to be used
|
|
in cursors. In this consistent read view modifications done by the
|
|
creating transaction after the cursor is created or future transactions
|
|
are not visible. */
|
|
|
|
cursor_view_t*
|
|
read_cursor_view_create_for_mysql(
|
|
/*==============================*/
|
|
trx_t* cr_trx) /* in: trx where cursor view is created */
|
|
{
|
|
cursor_view_t* curview;
|
|
read_view_t* view;
|
|
mem_heap_t* heap;
|
|
trx_t* trx;
|
|
ulint n;
|
|
|
|
ut_a(cr_trx);
|
|
|
|
/* Use larger heap than in trx_create when creating a read_view
|
|
because cursors are quite long. */
|
|
|
|
heap = mem_heap_create(512);
|
|
|
|
curview = (cursor_view_t*) mem_heap_alloc(heap, sizeof(cursor_view_t));
|
|
curview->heap = heap;
|
|
|
|
/* Drop cursor tables from consideration when evaluating the need of
|
|
auto-commit */
|
|
curview->n_mysql_tables_in_use = cr_trx->n_mysql_tables_in_use;
|
|
cr_trx->n_mysql_tables_in_use = 0;
|
|
|
|
mutex_enter(&kernel_mutex);
|
|
|
|
curview->read_view = read_view_create_low(
|
|
UT_LIST_GET_LEN(trx_sys->trx_list),
|
|
curview->heap);
|
|
|
|
view = curview->read_view;
|
|
view->creator_trx_id = cr_trx->id;
|
|
view->type = VIEW_HIGH_GRANULARITY;
|
|
view->undo_no = cr_trx->undo_no;
|
|
|
|
/* No future transactions should be visible in the view */
|
|
|
|
view->low_limit_no = trx_sys->max_trx_id;
|
|
view->low_limit_id = view->low_limit_no;
|
|
|
|
view->can_be_too_old = FALSE;
|
|
|
|
n = 0;
|
|
trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
|
|
|
|
/* No active transaction should be visible */
|
|
|
|
while (trx) {
|
|
|
|
if (trx->conc_state == TRX_ACTIVE
|
|
|| trx->conc_state == TRX_PREPARED) {
|
|
|
|
read_view_set_nth_trx_id(view, n, trx->id);
|
|
|
|
n++;
|
|
|
|
/* NOTE that a transaction whose trx number is <
|
|
trx_sys->max_trx_id can still be active, if it is
|
|
in the middle of its commit! Note that when a
|
|
transaction starts, we initialize trx->no to
|
|
ut_dulint_max. */
|
|
|
|
if (ut_dulint_cmp(view->low_limit_no, trx->no) > 0) {
|
|
|
|
view->low_limit_no = trx->no;
|
|
}
|
|
}
|
|
|
|
trx = UT_LIST_GET_NEXT(trx_list, trx);
|
|
}
|
|
|
|
view->n_trx_ids = n;
|
|
|
|
if (n > 0) {
|
|
/* The last active transaction has the smallest id: */
|
|
view->up_limit_id = read_view_get_nth_trx_id(view, n - 1);
|
|
} else {
|
|
view->up_limit_id = view->low_limit_id;
|
|
}
|
|
|
|
UT_LIST_ADD_FIRST(view_list, trx_sys->view_list, view);
|
|
|
|
mutex_exit(&kernel_mutex);
|
|
|
|
return(curview);
|
|
}
|
|
|
|
/*************************************************************************
|
|
Close a given consistent cursor view for mysql and restore global read view
|
|
back to a transaction read view. */
|
|
|
|
void
|
|
read_cursor_view_close_for_mysql(
|
|
/*=============================*/
|
|
trx_t* trx, /* in: trx */
|
|
cursor_view_t* curview)/* in: cursor view to be closed */
|
|
{
|
|
ut_a(curview);
|
|
ut_a(curview->read_view);
|
|
ut_a(curview->heap);
|
|
|
|
/* Add cursor's tables to the global count of active tables that
|
|
belong to this transaction */
|
|
trx->n_mysql_tables_in_use += curview->n_mysql_tables_in_use;
|
|
|
|
mutex_enter(&kernel_mutex);
|
|
|
|
read_view_close(curview->read_view);
|
|
trx->read_view = trx->global_read_view;
|
|
|
|
mutex_exit(&kernel_mutex);
|
|
|
|
mem_heap_free(curview->heap);
|
|
}
|
|
|
|
/*************************************************************************
|
|
This function sets a given consistent cursor view to a transaction
|
|
read view if given consistent cursor view is not NULL. Otherwise, function
|
|
restores a global read view to a transaction read view. */
|
|
|
|
void
|
|
read_cursor_set_for_mysql(
|
|
/*======================*/
|
|
trx_t* trx, /* in: transaction where cursor is set */
|
|
cursor_view_t* curview)/* in: consistent cursor view to be set */
|
|
{
|
|
ut_a(trx);
|
|
|
|
mutex_enter(&kernel_mutex);
|
|
|
|
if (UNIV_LIKELY(curview != NULL)) {
|
|
trx->read_view = curview->read_view;
|
|
} else {
|
|
trx->read_view = trx->global_read_view;
|
|
}
|
|
|
|
mutex_exit(&kernel_mutex);
|
|
}
|