mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-19544 Remove innodb_locks_unsafe_for_binlog
The transaction isolation levels READ COMMITTED and READ UNCOMMITTED should behave similarly to the old deprecated setting innodb_locks_unsafe_for_binlog=1, that is, avoid acquiring gap locks. row_search_mvcc(): Reduce the scope of some variables, and clean up the initialization and use of the variable set_also_gap_locks.
This commit is contained in:
parent
47cede646b
commit
1a6f470464
29 changed files with 158 additions and 484 deletions
|
@ -269,9 +269,6 @@ innodb_autoinc_lock_mode=2
|
|||
autoinc lock modes 0 and 1 can cause unresolved deadlock, and make
|
||||
the system unresponsive.
|
||||
|
||||
innodb_locks_unsafe_for_binlog=1
|
||||
This option is required for parallel applying.
|
||||
|
||||
5.2 WSREP OPTIONS
|
||||
|
||||
All options are optional except for wsrep_provider, wsrep_cluster_address, and
|
||||
|
|
|
@ -241,7 +241,6 @@ char* innobase_data_file_path;
|
|||
|
||||
my_bool innobase_use_doublewrite;
|
||||
my_bool innobase_file_per_table;
|
||||
my_bool innobase_locks_unsafe_for_binlog;
|
||||
my_bool innobase_rollback_on_timeout;
|
||||
my_bool innobase_create_status_file;
|
||||
|
||||
|
@ -1913,8 +1912,6 @@ static bool innodb_init_param()
|
|||
|
||||
srv_file_per_table = (my_bool) innobase_file_per_table;
|
||||
|
||||
srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
|
||||
|
||||
srv_max_n_open_files = ULINT_UNDEFINED - 5;
|
||||
srv_innodb_status = (ibool) innobase_create_status_file;
|
||||
|
||||
|
|
|
@ -31,20 +31,19 @@ SET SQL_MODE="";
|
|||
# Show prerequisites for this test.
|
||||
#
|
||||
SELECT @@global.tx_isolation;
|
||||
SELECT @@global.innodb_locks_unsafe_for_binlog;
|
||||
#
|
||||
# When innodb_locks_unsafe_for_binlog is not set (zero), which is the
|
||||
# default, InnoDB takes "next-key locks"/"gap locks". This means it
|
||||
# With the transaction isolation level REPEATABLE READ (the default)
|
||||
# or SERIALIZEBLE, InnoDB takes "next-key locks"/"gap locks". This means it
|
||||
# locks the gap before the keys that it accessed to find the rows to
|
||||
# use for a statement. In this case we have to expect some more lock
|
||||
# wait timeouts in the tests below as if innodb_locks_unsafe_for_binlog
|
||||
# is set (non-zero). In the latter case no "next-key locks"/"gap locks"
|
||||
# are taken and locks on keys that do not match the WHERE conditon are
|
||||
# released. Hence less lock collisions occur.
|
||||
# wait timeouts in the tests, compared to READ UNCOMMITTED or READ COMMITTED.
|
||||
# For READ UNCOMMITTED or READ COMMITTED, no "next-key locks"/"gap locks"
|
||||
# are taken and locks on keys that do not match the WHERE condition are
|
||||
# released. Hence fewer lock collisions occur.
|
||||
# We use the variable $keep_locks to set the expectations for
|
||||
# lock wait timeouts accordingly.
|
||||
#
|
||||
let $keep_locks= `SELECT NOT @@global.innodb_locks_unsafe_for_binlog`;
|
||||
let $keep_locks= `SELECT @@global.tx_isolation IN ('REPEATABLE-READ','SERIALIZABLE')`;
|
||||
--echo # keep_locks == $keep_locks
|
||||
|
||||
#
|
||||
|
@ -52,14 +51,6 @@ let $keep_locks= `SELECT NOT @@global.innodb_locks_unsafe_for_binlog`;
|
|||
#
|
||||
GRANT USAGE ON test.* TO mysqltest@localhost;
|
||||
|
||||
#
|
||||
# Preparatory cleanup.
|
||||
#
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
|
||||
--echo
|
||||
--echo **
|
||||
--echo ** two UPDATE's running and both changing distinct result sets
|
||||
|
@ -99,7 +90,7 @@ drop table if exists t1;
|
|||
--echo ** Update on t1 will cause a table scan which will be blocked because
|
||||
--echo ** the previously initiated table scan applied exclusive key locks on
|
||||
--echo ** all primary keys.
|
||||
--echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
--echo ** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
--echo ** do not match the WHERE condition are released.
|
||||
if ($keep_locks)
|
||||
{
|
||||
|
@ -190,7 +181,7 @@ drop table t1;
|
|||
--echo ** Update on t1 will cause a table scan which will be blocked because
|
||||
--echo ** the previously initiated table scan applied exclusive key locks on
|
||||
--echo ** all primary keys.
|
||||
--echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
--echo ** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
--echo ** do not match the WHERE condition are released.
|
||||
if ($keep_locks)
|
||||
{
|
||||
|
@ -386,7 +377,7 @@ drop table t1;
|
|||
--echo ** Updating single row using a table scan. This will time out
|
||||
--echo ** because of ongoing transaction on thread 1 holding lock on
|
||||
--echo ** all primary keys in the scan.
|
||||
--echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
--echo ** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
--echo ** do not match the WHERE condition are released.
|
||||
if ($keep_locks)
|
||||
{
|
||||
|
@ -570,7 +561,7 @@ drop table t1;
|
|||
--echo ** Update on t1 will cause a table scan which will be blocked because
|
||||
--echo ** the previously initiated table scan applied exclusive key locks on
|
||||
--echo ** all primary keys.
|
||||
--echo ** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
--echo ** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
--echo ** do not match the WHERE condition are released.
|
||||
if ($keep_locks)
|
||||
{
|
||||
|
@ -598,13 +589,8 @@ drop table t1;
|
|||
connection thread1;
|
||||
select * from t1;
|
||||
|
||||
--echo ** Cleanup
|
||||
connection thread1;
|
||||
disconnect thread1;
|
||||
--source include/wait_until_disconnected.inc
|
||||
connection thread2;
|
||||
disconnect thread2;
|
||||
--source include/wait_until_disconnected.inc
|
||||
connection default;
|
||||
drop table t1;
|
||||
drop user mysqltest@localhost;
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
--loose-innodb_lock_wait_timeout=1
|
|
@ -1,15 +1,13 @@
|
|||
SET @save_timeout = @@GLOBAL.innodb_lock_wait_timeout;
|
||||
SET GLOBAL innodb_lock_wait_timeout = 1;
|
||||
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||
connection default;
|
||||
SET SQL_MODE="";
|
||||
SELECT @@global.tx_isolation;
|
||||
@@global.tx_isolation
|
||||
REPEATABLE-READ
|
||||
SELECT @@global.innodb_locks_unsafe_for_binlog;
|
||||
@@global.innodb_locks_unsafe_for_binlog
|
||||
0
|
||||
# keep_locks == 1
|
||||
GRANT USAGE ON test.* TO mysqltest@localhost;
|
||||
drop table if exists t1;
|
||||
|
||||
**
|
||||
** two UPDATE's running and both changing distinct result sets
|
||||
|
@ -47,7 +45,7 @@ begin;
|
|||
** Update on t1 will cause a table scan which will be blocked because
|
||||
** the previously initiated table scan applied exclusive key locks on
|
||||
** all primary keys.
|
||||
** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
** do not match the WHERE condition are released.
|
||||
update t1 set eta=2 where tipo=22;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
|
@ -187,7 +185,7 @@ begin;
|
|||
** Update on t1 will cause a table scan which will be blocked because
|
||||
** the previously initiated table scan applied exclusive key locks on
|
||||
** all primary keys.
|
||||
** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
** do not match the WHERE condition are released.
|
||||
update t1 set tipo=1 where tipo=2;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
|
@ -476,7 +474,7 @@ begin;
|
|||
** Updating single row using a table scan. This will time out
|
||||
** because of ongoing transaction on thread 1 holding lock on
|
||||
** all primary keys in the scan.
|
||||
** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
** do not match the WHERE condition are released.
|
||||
update t1 set tipo=11 where tipo=22;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
|
@ -736,7 +734,7 @@ begin;
|
|||
** Update on t1 will cause a table scan which will be blocked because
|
||||
** the previously initiated table scan applied exclusive key locks on
|
||||
** all primary keys.
|
||||
** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
** do not match the WHERE condition are released.
|
||||
update t1 set tipo=1 where tipo=22;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
|
@ -789,12 +787,10 @@ eta tipo c
|
|||
70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
|
||||
80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
|
||||
90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
|
||||
** Cleanup
|
||||
connection thread1;
|
||||
disconnect thread1;
|
||||
connection thread2;
|
||||
disconnect thread2;
|
||||
connection default;
|
||||
drop table t1;
|
||||
drop user mysqltest@localhost;
|
||||
SET SQL_MODE=default;
|
||||
SET GLOBAL innodb_lock_wait_timeout = @save_timeout;
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
|
||||
let $engine_type= InnoDB;
|
||||
|
||||
SET @save_timeout = @@GLOBAL.innodb_lock_wait_timeout;
|
||||
SET GLOBAL innodb_lock_wait_timeout = 1;
|
||||
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||
# innodb_locks_unsafe_for_binlog not set for this test
|
||||
|
||||
--source include/concurrent.inc
|
||||
|
||||
SET GLOBAL innodb_lock_wait_timeout = @save_timeout;
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
--loose-innodb_locks_unsafe_for_binlog
|
||||
--loose-innodb_lock_wait_timeout=1
|
|
@ -1,15 +1,14 @@
|
|||
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||
SET @save_timeout = @@GLOBAL.innodb_lock_wait_timeout;
|
||||
SET GLOBAL innodb_lock_wait_timeout = 1;
|
||||
SET @save_isolation = @@GLOBAL.tx_isolation;
|
||||
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
connection default;
|
||||
SET SQL_MODE="";
|
||||
SELECT @@global.tx_isolation;
|
||||
@@global.tx_isolation
|
||||
REPEATABLE-READ
|
||||
SELECT @@global.innodb_locks_unsafe_for_binlog;
|
||||
@@global.innodb_locks_unsafe_for_binlog
|
||||
1
|
||||
READ-COMMITTED
|
||||
# keep_locks == 0
|
||||
GRANT USAGE ON test.* TO mysqltest@localhost;
|
||||
drop table if exists t1;
|
||||
|
||||
**
|
||||
** two UPDATE's running and both changing distinct result sets
|
||||
|
@ -47,7 +46,7 @@ begin;
|
|||
** Update on t1 will cause a table scan which will be blocked because
|
||||
** the previously initiated table scan applied exclusive key locks on
|
||||
** all primary keys.
|
||||
** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
** do not match the WHERE condition are released.
|
||||
update t1 set eta=2 where tipo=22;
|
||||
** Release user level name lock from thread 1. This will cause the ULL
|
||||
|
@ -101,7 +100,7 @@ eta tipo c
|
|||
60 2 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
|
||||
70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
|
||||
2 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
|
||||
90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
|
||||
1 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
|
||||
** And send final commit on thread 1.
|
||||
commit;
|
||||
** Table should now be updated by both updates in the order of
|
||||
|
@ -186,7 +185,7 @@ begin;
|
|||
** Update on t1 will cause a table scan which will be blocked because
|
||||
** the previously initiated table scan applied exclusive key locks on
|
||||
** all primary keys.
|
||||
** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
** do not match the WHERE condition are released.
|
||||
update t1 set tipo=1 where tipo=2;
|
||||
** Release ULL. This will release the next waiting ULL on thread 2.
|
||||
|
@ -231,13 +230,13 @@ select * from t1;
|
|||
eta tipo c
|
||||
7 7 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
8 8 bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
10 1 ccccccccccccccccccccccccccccccccccccccccccc
|
||||
1 1 ccccccccccccccccccccccccccccccccccccccccccc
|
||||
20 1 ddddddddddddddddddddddddddddddddddddddddddd
|
||||
30 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
1 1 eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
|
||||
40 1 fffffffffffffffffffffffffffffffffffffffffff
|
||||
50 1 ggggggggggggggggggggggggggggggggggggggggggg
|
||||
1 1 ggggggggggggggggggggggggggggggggggggggggggg
|
||||
60 1 hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
|
||||
70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
|
||||
1 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
|
||||
80 22 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
|
||||
90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
|
||||
commit;
|
||||
|
@ -474,7 +473,7 @@ begin;
|
|||
** Updating single row using a table scan. This will time out
|
||||
** because of ongoing transaction on thread 1 holding lock on
|
||||
** all primary keys in the scan.
|
||||
** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
** do not match the WHERE condition are released.
|
||||
update t1 set tipo=11 where tipo=22;
|
||||
** After the time out the transaction is aborted; no rows should
|
||||
|
@ -733,7 +732,7 @@ begin;
|
|||
** Update on t1 will cause a table scan which will be blocked because
|
||||
** the previously initiated table scan applied exclusive key locks on
|
||||
** all primary keys.
|
||||
** Not so if innodb_locks_unsafe_for_binlog is set. The locks that
|
||||
** Not so for READ UNCOMMITTED or READ COMMITTED. The locks that
|
||||
** do not match the WHERE condition are released.
|
||||
update t1 set tipo=1 where tipo=22;
|
||||
select * from t1;
|
||||
|
@ -785,12 +784,11 @@ eta tipo c
|
|||
70 1 iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
|
||||
80 1 jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj
|
||||
90 11 kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
|
||||
** Cleanup
|
||||
connection thread1;
|
||||
disconnect thread1;
|
||||
connection thread2;
|
||||
disconnect thread2;
|
||||
connection default;
|
||||
drop table t1;
|
||||
drop user mysqltest@localhost;
|
||||
SET SQL_MODE=default;
|
||||
SET GLOBAL innodb_lock_wait_timeout = @save_timeout;
|
||||
SET GLOBAL tx_isolation = @save_isolation;
|
||||
|
|
|
@ -16,8 +16,12 @@
|
|||
|
||||
let $engine_type= InnoDB;
|
||||
|
||||
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
|
||||
# innodb_locks_unsafe_for_binlog is set fro this test.
|
||||
SET @save_timeout = @@GLOBAL.innodb_lock_wait_timeout;
|
||||
SET GLOBAL innodb_lock_wait_timeout = 1;
|
||||
SET @save_isolation = @@GLOBAL.tx_isolation;
|
||||
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
|
||||
--source include/concurrent.inc
|
||||
|
||||
SET GLOBAL innodb_lock_wait_timeout = @save_timeout;
|
||||
SET GLOBAL tx_isolation = @save_isolation;
|
||||
|
|
|
@ -238,8 +238,7 @@ Success: 'show keys from t1' doesn't take row locks on 't1'.
|
|||
# statement-by-statement) and thanks to MVCC we can always get
|
||||
# versions of rows prior to the update that has locked them.
|
||||
# But in practice InnoDB does locking reads for all statements
|
||||
# other than SELECT (unless it is a READ-COMITTED mode or
|
||||
# innodb_locks_unsafe_for_binlog is ON).
|
||||
# other than SELECT (unless READ UNCOMMITTED or READ COMMITTED).
|
||||
connection default;
|
||||
Success: 'call p1((select i + 5 from t1 where i = 1))' takes shared row locks on 't1'.
|
||||
#
|
||||
|
|
|
@ -261,8 +261,7 @@ let $statement= show keys from t1;
|
|||
--echo # statement-by-statement) and thanks to MVCC we can always get
|
||||
--echo # versions of rows prior to the update that has locked them.
|
||||
--echo # But in practice InnoDB does locking reads for all statements
|
||||
--echo # other than SELECT (unless it is a READ-COMITTED mode or
|
||||
--echo # innodb_locks_unsafe_for_binlog is ON).
|
||||
--echo # other than SELECT (unless READ UNCOMMITTED or READ COMMITTED).
|
||||
let $statement= call p1((select i + 5 from t1 where i = 1));
|
||||
let $wait_statement= $statement;
|
||||
--source include/check_shared_row_lock.inc
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
--loose-innodb_locks_unsafe_for_binlog --loose-innodb_lock_wait_timeout=1
|
|
@ -1,3 +1,7 @@
|
|||
SET @save_timeout = @@GLOBAL.innodb_lock_wait_timeout;
|
||||
SET GLOBAL innodb_lock_wait_timeout = 1;
|
||||
SET @save_isolation = @@GLOBAL.tx_isolation;
|
||||
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9,t10;
|
||||
create table t1 (id int not null, f_id int not null, f int not null,
|
||||
primary key(f_id, id)) engine = InnoDB;
|
||||
|
@ -187,3 +191,5 @@ disconnect h;
|
|||
disconnect i;
|
||||
disconnect j;
|
||||
drop table t1, t2, t3, t5, t6, t8, t9;
|
||||
SET GLOBAL innodb_lock_wait_timeout = @save_timeout;
|
||||
SET GLOBAL tx_isolation = @save_isolation;
|
||||
|
|
|
@ -13,4 +13,12 @@
|
|||
--source include/have_innodb.inc
|
||||
let $engine_type= InnoDB;
|
||||
|
||||
SET @save_timeout = @@GLOBAL.innodb_lock_wait_timeout;
|
||||
SET GLOBAL innodb_lock_wait_timeout = 1;
|
||||
SET @save_isolation = @@GLOBAL.tx_isolation;
|
||||
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
|
||||
|
||||
--source include/unsafe_binlog.inc
|
||||
|
||||
SET GLOBAL innodb_lock_wait_timeout = @save_timeout;
|
||||
SET GLOBAL tx_isolation = @save_isolation;
|
||||
|
|
|
@ -35,7 +35,6 @@ DROP TABLE t2, t1;
|
|||
# Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
|
||||
# FOR UPDATE
|
||||
#
|
||||
drop table if exists t1;
|
||||
create table t1 (a int primary key auto_increment,
|
||||
b int, index(b)) engine=innodb;
|
||||
insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
|
@ -84,19 +83,12 @@ drop table t1, t2;
|
|||
#
|
||||
# Bug#41756 Strange error messages about locks from InnoDB
|
||||
#
|
||||
drop table if exists t1;
|
||||
# In the default transaction isolation mode, and/or with
|
||||
# innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row()
|
||||
# in InnoDB does nothing.
|
||||
# In the default transaction isolation mode,
|
||||
# handler::unlock_row() in InnoDB does nothing.
|
||||
# Thus in order to reproduce the condition that led to the
|
||||
# warning, one needs to relax isolation by either
|
||||
# setting a weaker tx_isolation value, or by turning on
|
||||
# the unsafe replication switch.
|
||||
# For testing purposes, choose to tweak the isolation level,
|
||||
# since it's settable at runtime, unlike
|
||||
# innodb_locks_unsafe_for_binlog, which is
|
||||
# only a command-line switch.
|
||||
#
|
||||
set @@session.tx_isolation="read-committed";
|
||||
# Prepare data. We need a table with a unique index,
|
||||
# for join_read_key to be used. The other column
|
||||
|
|
|
@ -1 +1 @@
|
|||
--loose-innodb-locks-unsafe-for-binlog --binlog-format=mixed
|
||||
--binlog-format=mixed
|
||||
|
|
|
@ -49,9 +49,6 @@ DROP TABLE t2, t1;
|
|||
--echo # Bug#46539 Various crashes on INSERT IGNORE SELECT + SELECT
|
||||
--echo # FOR UPDATE
|
||||
--echo #
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
create table t1 (a int primary key auto_increment,
|
||||
b int, index(b)) engine=innodb;
|
||||
insert into t1 (b) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||
|
@ -107,21 +104,12 @@ drop table t1, t2;
|
|||
--echo #
|
||||
--echo # Bug#41756 Strange error messages about locks from InnoDB
|
||||
--echo #
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
--echo # In the default transaction isolation mode, and/or with
|
||||
--echo # innodb_locks_unsafe_for_binlog=OFF, handler::unlock_row()
|
||||
--echo # in InnoDB does nothing.
|
||||
--echo # In the default transaction isolation mode,
|
||||
--echo # handler::unlock_row() in InnoDB does nothing.
|
||||
--echo # Thus in order to reproduce the condition that led to the
|
||||
--echo # warning, one needs to relax isolation by either
|
||||
--echo # setting a weaker tx_isolation value, or by turning on
|
||||
--echo # the unsafe replication switch.
|
||||
--echo # For testing purposes, choose to tweak the isolation level,
|
||||
--echo # since it's settable at runtime, unlike
|
||||
--echo # innodb_locks_unsafe_for_binlog, which is
|
||||
--echo # only a command-line switch.
|
||||
--echo #
|
||||
set @@session.tx_isolation="read-committed";
|
||||
|
||||
--echo # Prepare data. We need a table with a unique index,
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
'#---------------------BS_STVARS_031_01----------------------#'
|
||||
SELECT COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog);
|
||||
COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog)
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_031_02----------------------#'
|
||||
SET @@GLOBAL.innodb_locks_unsafe_for_binlog=1;
|
||||
ERROR HY000: Variable 'innodb_locks_unsafe_for_binlog' is a read only variable
|
||||
Expected error 'Read only variable'
|
||||
SELECT COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog);
|
||||
COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog)
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_031_03----------------------#'
|
||||
SELECT IF(@@GLOBAL.innodb_locks_unsafe_for_binlog, "ON", "OFF") = VARIABLE_VALUE
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
WHERE VARIABLE_NAME='innodb_locks_unsafe_for_binlog';
|
||||
IF(@@GLOBAL.innodb_locks_unsafe_for_binlog, "ON", "OFF") = VARIABLE_VALUE
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog);
|
||||
COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog)
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(VARIABLE_VALUE)
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
WHERE VARIABLE_NAME='innodb_locks_unsafe_for_binlog';
|
||||
COUNT(VARIABLE_VALUE)
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_031_04----------------------#'
|
||||
SELECT @@innodb_locks_unsafe_for_binlog = @@GLOBAL.innodb_locks_unsafe_for_binlog;
|
||||
@@innodb_locks_unsafe_for_binlog = @@GLOBAL.innodb_locks_unsafe_for_binlog
|
||||
1
|
||||
1 Expected
|
||||
'#---------------------BS_STVARS_031_05----------------------#'
|
||||
SELECT COUNT(@@innodb_locks_unsafe_for_binlog);
|
||||
COUNT(@@innodb_locks_unsafe_for_binlog)
|
||||
1
|
||||
1 Expected
|
||||
SELECT COUNT(@@local.innodb_locks_unsafe_for_binlog);
|
||||
ERROR HY000: Variable 'innodb_locks_unsafe_for_binlog' is a GLOBAL variable
|
||||
Expected error 'Variable is a GLOBAL variable'
|
||||
SELECT COUNT(@@SESSION.innodb_locks_unsafe_for_binlog);
|
||||
ERROR HY000: Variable 'innodb_locks_unsafe_for_binlog' is a GLOBAL variable
|
||||
Expected error 'Variable is a GLOBAL variable'
|
||||
SELECT COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog);
|
||||
COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog)
|
||||
1
|
||||
1 Expected
|
||||
SELECT innodb_locks_unsafe_for_binlog = @@SESSION.innodb_locks_unsafe_for_binlog;
|
||||
ERROR 42S22: Unknown column 'innodb_locks_unsafe_for_binlog' in 'field list'
|
||||
Expected error 'Readonly variable'
|
|
@ -1324,20 +1324,6 @@ NUMERIC_BLOCK_SIZE 0
|
|||
ENUM_VALUE_LIST NULL
|
||||
READ_ONLY NO
|
||||
COMMAND_LINE_ARGUMENT REQUIRED
|
||||
VARIABLE_NAME INNODB_LOCKS_UNSAFE_FOR_BINLOG
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE OFF
|
||||
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||
DEFAULT_VALUE OFF
|
||||
VARIABLE_SCOPE GLOBAL
|
||||
VARIABLE_TYPE BOOLEAN
|
||||
VARIABLE_COMMENT DEPRECATED. This option may be removed in future releases. Please use READ COMMITTED transaction isolation level instead. Force InnoDB to not use next-key locking, to use only row-level locking.
|
||||
NUMERIC_MIN_VALUE NULL
|
||||
NUMERIC_MAX_VALUE NULL
|
||||
NUMERIC_BLOCK_SIZE NULL
|
||||
ENUM_VALUE_LIST OFF,ON
|
||||
READ_ONLY YES
|
||||
COMMAND_LINE_ARGUMENT NONE
|
||||
VARIABLE_NAME INNODB_LOCK_SCHEDULE_ALGORITHM
|
||||
SESSION_VALUE NULL
|
||||
GLOBAL_VALUE fcfs
|
||||
|
|
|
@ -1,106 +0,0 @@
|
|||
|
||||
|
||||
################## mysql-test\t\innodb_locks_unsafe_for_binlog_basic.test #####
|
||||
# #
|
||||
# Variable Name: innodb_locks_unsafe_for_binlog #
|
||||
# Scope: Global #
|
||||
# Access Type: Static #
|
||||
# Data Type: boolean #
|
||||
# #
|
||||
# #
|
||||
# Creation Date: 2008-02-07 #
|
||||
# Author : Sharique Abdullah #
|
||||
# #
|
||||
# #
|
||||
# Description:Test Cases of Dynamic System Variable innodb_locks_unsafe_for_binlog#
|
||||
# that checks the behavior of this variable in the following ways #
|
||||
# * Value Check #
|
||||
# * Scope Check #
|
||||
# #
|
||||
# Reference: http://dev.mysql.com/doc/refman/5.1/en/ #
|
||||
# server-system-variables.html #
|
||||
# #
|
||||
###############################################################################
|
||||
|
||||
--source include/have_innodb.inc
|
||||
|
||||
--echo '#---------------------BS_STVARS_031_01----------------------#'
|
||||
####################################################################
|
||||
# Displaying default value #
|
||||
####################################################################
|
||||
SELECT COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog);
|
||||
--echo 1 Expected
|
||||
|
||||
|
||||
--echo '#---------------------BS_STVARS_031_02----------------------#'
|
||||
####################################################################
|
||||
# Check if Value can set #
|
||||
####################################################################
|
||||
|
||||
--error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
SET @@GLOBAL.innodb_locks_unsafe_for_binlog=1;
|
||||
--echo Expected error 'Read only variable'
|
||||
|
||||
SELECT COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog);
|
||||
--echo 1 Expected
|
||||
|
||||
|
||||
|
||||
|
||||
--echo '#---------------------BS_STVARS_031_03----------------------#'
|
||||
#################################################################
|
||||
# Check if the value in GLOBAL Table matches value in variable #
|
||||
#################################################################
|
||||
|
||||
--disable_warnings
|
||||
SELECT IF(@@GLOBAL.innodb_locks_unsafe_for_binlog, "ON", "OFF") = VARIABLE_VALUE
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
WHERE VARIABLE_NAME='innodb_locks_unsafe_for_binlog';
|
||||
--enable_warnings
|
||||
--echo 1 Expected
|
||||
|
||||
SELECT COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog);
|
||||
--echo 1 Expected
|
||||
|
||||
--disable_warnings
|
||||
SELECT COUNT(VARIABLE_VALUE)
|
||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||
WHERE VARIABLE_NAME='innodb_locks_unsafe_for_binlog';
|
||||
--enable_warnings
|
||||
--echo 1 Expected
|
||||
|
||||
|
||||
|
||||
--echo '#---------------------BS_STVARS_031_04----------------------#'
|
||||
################################################################################
|
||||
# Check if accessing variable with and without GLOBAL point to same variable #
|
||||
################################################################################
|
||||
SELECT @@innodb_locks_unsafe_for_binlog = @@GLOBAL.innodb_locks_unsafe_for_binlog;
|
||||
--echo 1 Expected
|
||||
|
||||
|
||||
|
||||
--echo '#---------------------BS_STVARS_031_05----------------------#'
|
||||
################################################################################
|
||||
# Check if innodb_locks_unsafe_for_binlog can be accessed with and without @@ sign #
|
||||
################################################################################
|
||||
|
||||
SELECT COUNT(@@innodb_locks_unsafe_for_binlog);
|
||||
--echo 1 Expected
|
||||
|
||||
--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
SELECT COUNT(@@local.innodb_locks_unsafe_for_binlog);
|
||||
--echo Expected error 'Variable is a GLOBAL variable'
|
||||
|
||||
--Error ER_INCORRECT_GLOBAL_LOCAL_VAR
|
||||
SELECT COUNT(@@SESSION.innodb_locks_unsafe_for_binlog);
|
||||
--echo Expected error 'Variable is a GLOBAL variable'
|
||||
|
||||
SELECT COUNT(@@GLOBAL.innodb_locks_unsafe_for_binlog);
|
||||
--echo 1 Expected
|
||||
|
||||
--Error ER_BAD_FIELD_ERROR
|
||||
SELECT innodb_locks_unsafe_for_binlog = @@SESSION.innodb_locks_unsafe_for_binlog;
|
||||
--echo Expected error 'Readonly variable'
|
||||
|
||||
|
|
@ -4,7 +4,6 @@
|
|||
[mysqld]
|
||||
binlog-format=row
|
||||
innodb-autoinc-lock-mode=2
|
||||
innodb-locks-unsafe-for-binlog=1
|
||||
wsrep_provider=@ENV.WSREP_PROVIDER
|
||||
|
||||
[mysqld.1]
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -200,7 +200,6 @@ static char* innobase_server_stopword_table;
|
|||
values */
|
||||
|
||||
static my_bool innobase_use_atomic_writes;
|
||||
static my_bool innobase_locks_unsafe_for_binlog;
|
||||
static my_bool innobase_rollback_on_timeout;
|
||||
static my_bool innobase_create_status_file;
|
||||
my_bool innobase_stats_on_metadata;
|
||||
|
@ -3979,14 +3978,6 @@ static int innodb_init_params()
|
|||
|
||||
row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
|
||||
|
||||
srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
|
||||
if (innobase_locks_unsafe_for_binlog) {
|
||||
ib::warn() << "Using innodb_locks_unsafe_for_binlog is"
|
||||
" DEPRECATED. This option may be removed in future"
|
||||
" releases. Please use READ COMMITTED transaction"
|
||||
" isolation level instead; " << SET_TRANSACTION_MSG;
|
||||
}
|
||||
|
||||
if (innobase_open_files < 10) {
|
||||
innobase_open_files = 300;
|
||||
if (srv_file_per_table && tc_size > 300 && tc_size < open_files_limit) {
|
||||
|
@ -9011,7 +9002,7 @@ ha_innobase::delete_all_rows()
|
|||
/**********************************************************************//**
|
||||
Removes a new lock set on a row, if it was not read optimistically. This can
|
||||
be called after a row has been read in the processing of an UPDATE or a DELETE
|
||||
query, if the option innodb_locks_unsafe_for_binlog is set. */
|
||||
query. */
|
||||
|
||||
void
|
||||
ha_innobase::unlock_row(void)
|
||||
|
@ -9027,11 +9018,8 @@ ha_innobase::unlock_row(void)
|
|||
|
||||
switch (m_prebuilt->row_read_type) {
|
||||
case ROW_READ_WITH_LOCKS:
|
||||
if (!srv_locks_unsafe_for_binlog
|
||||
&& m_prebuilt->trx->isolation_level
|
||||
> TRX_ISO_READ_COMMITTED) {
|
||||
if (m_prebuilt->trx->isolation_level > TRX_ISO_READ_COMMITTED)
|
||||
break;
|
||||
}
|
||||
/* fall through */
|
||||
case ROW_READ_TRY_SEMI_CONSISTENT:
|
||||
row_unlock_for_mysql(m_prebuilt, FALSE);
|
||||
|
@ -9054,28 +9042,16 @@ ha_innobase::was_semi_consistent_read(void)
|
|||
}
|
||||
|
||||
/* See handler.h and row0mysql.h for docs on this function. */
|
||||
|
||||
void
|
||||
ha_innobase::try_semi_consistent_read(bool yes)
|
||||
/*===========================================*/
|
||||
void ha_innobase::try_semi_consistent_read(bool yes)
|
||||
{
|
||||
ut_a(m_prebuilt->trx == thd_to_trx(ha_thd()));
|
||||
|
||||
ut_ad(m_prebuilt->trx == thd_to_trx(ha_thd()));
|
||||
/* Row read type is set to semi consistent read if this was
|
||||
requested by the MySQL and either innodb_locks_unsafe_for_binlog
|
||||
option is used or this session is using READ COMMITTED isolation
|
||||
level. */
|
||||
|
||||
if (yes
|
||||
&& (srv_locks_unsafe_for_binlog
|
||||
|| m_prebuilt->trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED)) {
|
||||
|
||||
m_prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
|
||||
|
||||
} else {
|
||||
m_prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
|
||||
}
|
||||
requested by the SQL layer and the transaction isolation level is
|
||||
READ UNCOMMITTED or READ COMMITTED. */
|
||||
m_prebuilt->row_read_type = yes
|
||||
&& m_prebuilt->trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
? ROW_READ_TRY_SEMI_CONSISTENT
|
||||
: ROW_READ_WITH_LOCKS;
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
|
@ -16347,9 +16323,7 @@ ha_innobase::store_lock(
|
|||
if (sql_command == SQLCOM_CHECKSUM
|
||||
|| sql_command == SQLCOM_CREATE_SEQUENCE
|
||||
|| (sql_command == SQLCOM_ANALYZE && lock_type == TL_READ)
|
||||
|| ((srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
|
||||
&& trx->isolation_level != TRX_ISO_SERIALIZABLE
|
||||
|| (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
&& (lock_type == TL_READ
|
||||
|| lock_type == TL_READ_NO_INSERT)
|
||||
&& (sql_command == SQLCOM_INSERT_SELECT
|
||||
|
@ -16358,10 +16332,8 @@ ha_innobase::store_lock(
|
|||
|| sql_command == SQLCOM_CREATE_SEQUENCE
|
||||
|| sql_command == SQLCOM_CREATE_TABLE))) {
|
||||
|
||||
/* If we either have innobase_locks_unsafe_for_binlog
|
||||
option set or this session is using READ COMMITTED
|
||||
isolation level and isolation level of the transaction
|
||||
is not set to serializable and MySQL is doing
|
||||
/* If the transaction isolation level is
|
||||
READ UNCOMMITTED or READ COMMITTED and we are executing
|
||||
INSERT INTO...SELECT or REPLACE INTO...SELECT
|
||||
or UPDATE ... = (SELECT ...) or CREATE ...
|
||||
SELECT... without FOR UPDATE or IN SHARE
|
||||
|
@ -18914,13 +18886,6 @@ static MYSQL_SYSVAR_BOOL(force_load_corrupted, srv_load_corrupted,
|
|||
"Force InnoDB to load metadata of corrupted table.",
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
|
||||
PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
|
||||
"DEPRECATED. This option may be removed in future releases."
|
||||
" Please use READ COMMITTED transaction isolation level instead."
|
||||
" Force InnoDB to not use next-key locking, to use only row-level locking.",
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
static MYSQL_SYSVAR_STR(log_group_home_dir, srv_log_group_home_dir,
|
||||
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Path to InnoDB log files.", NULL, NULL, NULL);
|
||||
|
@ -19969,7 +19934,6 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
MYSQL_SYSVAR(large_prefix), /* deprecated in MariaDB 10.2; no effect */
|
||||
MYSQL_SYSVAR(force_load_corrupted),
|
||||
MYSQL_SYSVAR(lock_schedule_algorithm),
|
||||
MYSQL_SYSVAR(locks_unsafe_for_binlog),
|
||||
MYSQL_SYSVAR(lock_wait_timeout),
|
||||
MYSQL_SYSVAR(deadlock_detect),
|
||||
MYSQL_SYSVAR(page_size),
|
||||
|
|
|
@ -271,8 +271,8 @@ row_update_for_mysql(
|
|||
row_prebuilt_t* prebuilt)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
|
||||
session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
|
||||
/** This can only be used when the current transaction is at
|
||||
READ COMMITTED or READ UNCOMMITTED isolation level.
|
||||
Before calling this function row_search_for_mysql() must have
|
||||
initialized prebuilt->new_rec_locks to store the information which new
|
||||
record locks really were set. This function removes a newly set
|
||||
|
@ -694,8 +694,9 @@ struct row_prebuilt_t {
|
|||
ulint row_read_type; /*!< ROW_READ_WITH_LOCKS if row locks
|
||||
should be the obtained for records
|
||||
under an UPDATE or DELETE cursor.
|
||||
If innodb_locks_unsafe_for_binlog
|
||||
is TRUE, this can be set to
|
||||
At READ UNCOMMITTED or
|
||||
READ COMMITTED isolation level,
|
||||
this can be set to
|
||||
ROW_READ_TRY_SEMI_CONSISTENT, so that
|
||||
if the row under an UPDATE or DELETE
|
||||
cursor was locked by another
|
||||
|
@ -717,8 +718,7 @@ struct row_prebuilt_t {
|
|||
cases; note that this breaks
|
||||
serializability. */
|
||||
ulint new_rec_locks; /*!< normally 0; if
|
||||
srv_locks_unsafe_for_binlog is
|
||||
TRUE or session is using READ
|
||||
the session is using READ
|
||||
COMMITTED or READ UNCOMMITTED
|
||||
isolation level, set in
|
||||
row_search_for_mysql() if we set a new
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved.
|
||||
Copyright (c) 2008, 2009, Google Inc.
|
||||
Copyright (c) 2009, Percona Inc.
|
||||
Copyright (c) 2013, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2013, 2019, MariaDB Corporation.
|
||||
|
||||
Portions of this file contain modifications contributed and copyrighted by
|
||||
Google, Inc. Those modifications are gratefully acknowledged and are described
|
||||
|
@ -254,10 +254,6 @@ extern ulong srv_thread_sleep_delay;
|
|||
/** Maximum sleep delay (in micro-seconds), value of 0 disables it.*/
|
||||
extern ulong srv_adaptive_max_sleep_delay;
|
||||
|
||||
/** Place locks to records only i.e. do not use next-key locking except
|
||||
on duplicate key checking and foreign key checking */
|
||||
extern ibool srv_locks_unsafe_for_binlog;
|
||||
|
||||
/** Sort buffer size in index creation */
|
||||
extern ulong srv_sort_buf_size;
|
||||
/** Maximum modification log file size for online index creation */
|
||||
|
|
|
@ -2436,8 +2436,8 @@ lock_rec_inherit_to_gap(
|
|||
|
||||
ut_ad(lock_mutex_own());
|
||||
|
||||
/* If srv_locks_unsafe_for_binlog is TRUE or session is using
|
||||
READ COMMITTED isolation level, we do not want locks set
|
||||
/* At READ UNCOMMITTED or READ COMMITTED isolation level,
|
||||
we do not want locks set
|
||||
by an UPDATE or a DELETE to be inherited as gap type locks. But we
|
||||
DO want S-locks/X-locks(taken for replace) set by a consistency
|
||||
constraint to be inherited also then. */
|
||||
|
@ -2447,11 +2447,9 @@ lock_rec_inherit_to_gap(
|
|||
lock = lock_rec_get_next(heap_no, lock)) {
|
||||
|
||||
if (!lock_rec_get_insert_intention(lock)
|
||||
&& !((srv_locks_unsafe_for_binlog
|
||||
|| lock->trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED)
|
||||
&& lock_get_mode(lock) ==
|
||||
(lock->trx->duplicates ? LOCK_S : LOCK_X))) {
|
||||
&& (lock->trx->isolation_level > TRX_ISO_READ_COMMITTED
|
||||
|| lock_get_mode(lock) !=
|
||||
(lock->trx->duplicates ? LOCK_S : LOCK_X))) {
|
||||
lock_rec_add_to_queue(
|
||||
LOCK_REC | LOCK_GAP
|
||||
| ulint(lock_get_mode(lock)),
|
||||
|
|
|
@ -1979,8 +1979,8 @@ error:
|
|||
DBUG_RETURN(err);
|
||||
}
|
||||
|
||||
/** This can only be used when srv_locks_unsafe_for_binlog is TRUE or this
|
||||
session is using a READ COMMITTED or READ UNCOMMITTED isolation level.
|
||||
/** This can only be used when the current transaction is at
|
||||
READ COMMITTED or READ UNCOMMITTED isolation level.
|
||||
Before calling this function row_search_for_mysql() must have
|
||||
initialized prebuilt->new_rec_locks to store the information which new
|
||||
record locks really were set. This function removes a newly set
|
||||
|
@ -2003,17 +2003,8 @@ row_unlock_for_mysql(
|
|||
|
||||
ut_ad(prebuilt != NULL);
|
||||
ut_ad(trx != NULL);
|
||||
ut_ad(trx->isolation_level <= TRX_ISO_READ_COMMITTED);
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
(!srv_locks_unsafe_for_binlog
|
||||
&& trx->isolation_level > TRX_ISO_READ_COMMITTED)) {
|
||||
|
||||
ib::error() << "Calling row_unlock_for_mysql though"
|
||||
" innodb_locks_unsafe_for_binlog is FALSE and this"
|
||||
" session is not using READ COMMITTED isolation"
|
||||
" level.";
|
||||
return;
|
||||
}
|
||||
if (dict_index_is_spatial(prebuilt->index)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -963,12 +963,10 @@ row_sel_get_clust_rec(
|
|||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
/* If innodb_locks_unsafe_for_binlog option is used
|
||||
or this session is using READ COMMITTED or lower isolation level
|
||||
/* At READ UNCOMMITTED or READ COMMITTED isolation level
|
||||
we lock only the record, i.e., next-key locking is
|
||||
not used. */
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
|
||||
lock_type = LOCK_REC_NOT_GAP;
|
||||
} else {
|
||||
lock_type = LOCK_ORDINARY;
|
||||
|
@ -1738,16 +1736,11 @@ rec_loop:
|
|||
true,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
/* If innodb_locks_unsafe_for_binlog option is used
|
||||
or this session is using READ COMMITTED or lower isolation
|
||||
level, we lock only the record, i.e., next-key
|
||||
locking is not used. */
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED) {
|
||||
|
||||
/* At READ UNCOMMITTED or READ COMMITTED
|
||||
isolation level, we lock only the record,
|
||||
i.e., next-key locking is not used. */
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
|
||||
if (page_rec_is_supremum(next_rec)) {
|
||||
|
||||
goto skip_lock;
|
||||
}
|
||||
|
||||
|
@ -1805,12 +1798,10 @@ skip_lock:
|
|||
|
||||
trx = thr_get_trx(thr);
|
||||
|
||||
/* If innodb_locks_unsafe_for_binlog option is used
|
||||
or this session is using READ COMMITTED or lower isolation level,
|
||||
/* At READ UNCOMMITTED or READ COMMITTED isolation level,
|
||||
we lock only the record, i.e., next-key locking is
|
||||
not used. */
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
|| dict_index_is_spatial(index)) {
|
||||
|
||||
if (page_rec_is_supremum(rec)) {
|
||||
|
@ -4146,29 +4137,18 @@ row_search_mvcc(
|
|||
dtuple_t* vrow = NULL;
|
||||
const rec_t* result_rec = NULL;
|
||||
const rec_t* clust_rec;
|
||||
dberr_t err = DB_SUCCESS;
|
||||
ibool unique_search = FALSE;
|
||||
ibool mtr_has_extra_clust_latch = FALSE;
|
||||
ibool moves_up = FALSE;
|
||||
ibool set_also_gap_locks = TRUE;
|
||||
/* if the query is a plain locking SELECT, and the isolation level
|
||||
is <= TRX_ISO_READ_COMMITTED, then this is set to FALSE */
|
||||
ibool did_semi_consistent_read = FALSE;
|
||||
/* if the returned record was locked and we did a semi-consistent
|
||||
read (fetch the newest committed version), then this is set to
|
||||
TRUE */
|
||||
ulint next_offs;
|
||||
ibool same_user_rec;
|
||||
mtr_t mtr;
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
ibool table_lock_waited = FALSE;
|
||||
byte* next_buf = 0;
|
||||
bool spatial_search = false;
|
||||
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
ut_ad(index && pcur && search_tuple);
|
||||
ut_a(prebuilt->magic_n == ROW_PREBUILT_ALLOCATED);
|
||||
ut_a(prebuilt->magic_n2 == ROW_PREBUILT_ALLOCATED);
|
||||
|
@ -4202,8 +4182,8 @@ row_search_mvcc(
|
|||
&& (prebuilt->read_just_key
|
||||
|| prebuilt->m_read_virtual_key);
|
||||
|
||||
/* Reset the new record lock info if srv_locks_unsafe_for_binlog
|
||||
is set or session is using a READ COMMITED isolation level. Then
|
||||
/* Reset the new record lock info if READ UNCOMMITTED or
|
||||
READ COMMITED isolation level is used. Then
|
||||
we are able to remove the record locks set here on an individual
|
||||
row. */
|
||||
prebuilt->new_rec_locks = 0;
|
||||
|
@ -4246,20 +4226,18 @@ row_search_mvcc(
|
|||
row_sel_dequeue_cached_row_for_mysql(buf, prebuilt);
|
||||
|
||||
prebuilt->n_rows_fetched++;
|
||||
|
||||
err = DB_SUCCESS;
|
||||
goto func_exit;
|
||||
trx->op_info = "";
|
||||
DBUG_RETURN(DB_SUCCESS);
|
||||
}
|
||||
|
||||
if (prebuilt->fetch_cache_first > 0
|
||||
&& prebuilt->fetch_cache_first < MYSQL_FETCH_CACHE_SIZE) {
|
||||
|
||||
early_not_found:
|
||||
/* The previous returned row was popped from the fetch
|
||||
cache, but the cache was not full at the time of the
|
||||
popping: no more rows can exist in the result set */
|
||||
|
||||
err = DB_RECORD_NOT_FOUND;
|
||||
goto func_exit;
|
||||
trx->op_info = "";
|
||||
DBUG_RETURN(DB_RECORD_NOT_FOUND);
|
||||
}
|
||||
|
||||
prebuilt->n_rows_fetched++;
|
||||
|
@ -4303,22 +4281,28 @@ row_search_mvcc(
|
|||
|
||||
if (UNIV_UNLIKELY(direction != 0
|
||||
&& !prebuilt->used_in_HANDLER)) {
|
||||
|
||||
err = DB_RECORD_NOT_FOUND;
|
||||
goto func_exit;
|
||||
goto early_not_found;
|
||||
}
|
||||
}
|
||||
|
||||
/* We don't support sequencial scan for Rtree index, because it
|
||||
is no meaning to do so. */
|
||||
if (dict_index_is_spatial(index)
|
||||
&& !RTREE_SEARCH_MODE(mode)) {
|
||||
err = DB_END_OF_INDEX;
|
||||
goto func_exit;
|
||||
if (dict_index_is_spatial(index) && !RTREE_SEARCH_MODE(mode)) {
|
||||
trx->op_info = "";
|
||||
DBUG_RETURN(DB_END_OF_INDEX);
|
||||
}
|
||||
|
||||
/* if the query is a plain locking SELECT, and the isolation level
|
||||
is <= TRX_ISO_READ_COMMITTED, then this is set to FALSE */
|
||||
bool did_semi_consistent_read = false;
|
||||
mtr_t mtr;
|
||||
mtr.start();
|
||||
|
||||
mem_heap_t* heap = NULL;
|
||||
ulint offsets_[REC_OFFS_NORMAL_SIZE];
|
||||
ulint* offsets = offsets_;
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
#ifdef BTR_CUR_HASH_ADAPT
|
||||
/*-------------------------------------------------------------*/
|
||||
/* PHASE 2: Try fast adaptive hash index search if possible */
|
||||
|
@ -4348,6 +4332,7 @@ row_search_mvcc(
|
|||
let us try a search shortcut through the hash
|
||||
index. */
|
||||
|
||||
dberr_t err = DB_SUCCESS;
|
||||
switch (row_sel_try_search_shortcut_for_mysql(
|
||||
&rec, prebuilt, &offsets, &heap,
|
||||
&mtr)) {
|
||||
|
@ -4367,9 +4352,10 @@ row_search_mvcc(
|
|||
case ICP_OUT_OF_RANGE:
|
||||
case ICP_ABORTED_BY_USER:
|
||||
case ICP_ERROR:
|
||||
goto shortcut_mismatch;
|
||||
err = DB_RECORD_NOT_FOUND;
|
||||
goto shortcut_done;
|
||||
case ICP_MATCH:
|
||||
goto shortcut_match;
|
||||
goto shortcut_done;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4392,21 +4378,19 @@ row_search_mvcc(
|
|||
break;
|
||||
}
|
||||
|
||||
shortcut_match:
|
||||
mtr.commit();
|
||||
|
||||
/* NOTE that we do NOT store the cursor
|
||||
position */
|
||||
err = DB_SUCCESS;
|
||||
goto func_exit;
|
||||
goto shortcut_done;
|
||||
|
||||
case SEL_EXHAUSTED:
|
||||
shortcut_mismatch:
|
||||
err = DB_RECORD_NOT_FOUND;
|
||||
shortcut_done:
|
||||
mtr.commit();
|
||||
|
||||
/* NOTE that we do NOT store the cursor
|
||||
position */
|
||||
err = DB_RECORD_NOT_FOUND;
|
||||
goto func_exit;
|
||||
trx->op_info = "";
|
||||
ut_ad(!sync_check_iterate(sync_check()));
|
||||
ut_ad(!did_semi_consistent_read);
|
||||
DBUG_RETURN(err);
|
||||
|
||||
case SEL_RETRY:
|
||||
break;
|
||||
|
@ -4444,22 +4428,16 @@ row_search_mvcc(
|
|||
|| prebuilt->table->no_rollback()
|
||||
|| srv_read_only_mode);
|
||||
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
&& prebuilt->select_lock_type != LOCK_NONE
|
||||
&& trx->mysql_thd != NULL
|
||||
&& thd_is_select(trx->mysql_thd)) {
|
||||
/* It is a plain locking SELECT and the isolation
|
||||
level is low: do not lock gaps */
|
||||
|
||||
set_also_gap_locks = FALSE;
|
||||
}
|
||||
/* Do not lock gaps for plain SELECT
|
||||
at READ UNCOMMITTED or READ COMMITTED isolation level */
|
||||
const bool set_also_gap_locks =
|
||||
prebuilt->select_lock_type != LOCK_NONE
|
||||
&& (trx->isolation_level > TRX_ISO_READ_COMMITTED
|
||||
|| !thd_is_select(trx->mysql_thd))
|
||||
#ifdef WITH_WSREP
|
||||
else if (wsrep_thd_skip_locking(trx->mysql_thd)) {
|
||||
ut_ad(!strcmp(wsrep_get_sr_table_name(),
|
||||
prebuilt->table->name.m_name));
|
||||
set_also_gap_locks = FALSE;
|
||||
}
|
||||
&& !wsrep_thd_skip_locking(trx->mysql_thd)
|
||||
#endif /* WITH_WSREP */
|
||||
;
|
||||
|
||||
/* Note that if the search mode was GE or G, then the cursor
|
||||
naturally moves upward (in fetch next) in alphabetical order,
|
||||
|
@ -4480,6 +4458,8 @@ row_search_mvcc(
|
|||
|
||||
clust_index = dict_table_get_first_index(prebuilt->table);
|
||||
|
||||
dberr_t err = DB_SUCCESS;
|
||||
|
||||
/* Do some start-of-statement preparations */
|
||||
|
||||
if (prebuilt->table->no_rollback()) {
|
||||
|
@ -4548,18 +4528,9 @@ wait_table_again:
|
|||
pcur->btr_cur.thr = thr;
|
||||
|
||||
if (dict_index_is_spatial(index)) {
|
||||
bool need_pred_lock;
|
||||
|
||||
need_pred_lock = (set_also_gap_locks
|
||||
&& !(srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED)
|
||||
&& prebuilt->select_lock_type
|
||||
!= LOCK_NONE);
|
||||
|
||||
if (!prebuilt->rtr_info) {
|
||||
prebuilt->rtr_info = rtr_create_rtr_info(
|
||||
need_pred_lock, true,
|
||||
set_also_gap_locks, true,
|
||||
btr_pcur_get_btr_cur(pcur), index);
|
||||
prebuilt->rtr_info->search_tuple = search_tuple;
|
||||
prebuilt->rtr_info->search_mode = mode;
|
||||
|
@ -4568,7 +4539,7 @@ wait_table_again:
|
|||
} else {
|
||||
rtr_info_reinit_in_cursor(
|
||||
btr_pcur_get_btr_cur(pcur),
|
||||
index, need_pred_lock);
|
||||
index, set_also_gap_locks);
|
||||
prebuilt->rtr_info->search_tuple = search_tuple;
|
||||
prebuilt->rtr_info->search_mode = mode;
|
||||
}
|
||||
|
@ -4589,11 +4560,8 @@ wait_table_again:
|
|||
ut_ad(page_rec_is_leaf(rec));
|
||||
|
||||
if (!moves_up
|
||||
&& !page_rec_is_supremum(rec)
|
||||
&& set_also_gap_locks
|
||||
&& !(srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
|
||||
&& prebuilt->select_lock_type != LOCK_NONE
|
||||
&& !page_rec_is_supremum(rec)
|
||||
&& !dict_index_is_spatial(index)) {
|
||||
|
||||
/* Try to place a gap lock on the next index record
|
||||
|
@ -4673,16 +4641,14 @@ rec_loop:
|
|||
if (page_rec_is_supremum(rec)) {
|
||||
|
||||
if (set_also_gap_locks
|
||||
&& !(srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
|
||||
&& prebuilt->select_lock_type != LOCK_NONE
|
||||
&& trx->isolation_level > TRX_ISO_READ_COMMITTED
|
||||
&& !dict_index_is_spatial(index)) {
|
||||
|
||||
/* Try to place a lock on the index record */
|
||||
|
||||
/* If innodb_locks_unsafe_for_binlog option is used
|
||||
or this session is using a READ COMMITTED or lower isolation
|
||||
level we do not lock gaps. Supremum record is really
|
||||
/* If the transaction isolation level is
|
||||
READ UNCOMMITTED or READ COMMITTED,
|
||||
we do not lock gaps. Supremum record is really
|
||||
a gap and therefore we do not set locks there. */
|
||||
|
||||
offsets = rec_get_offsets(rec, index, offsets, true,
|
||||
|
@ -4820,17 +4786,7 @@ wrong_offs:
|
|||
if (0 != cmp_dtuple_rec(search_tuple, rec, offsets)) {
|
||||
|
||||
if (set_also_gap_locks
|
||||
&& !(srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED)
|
||||
&& prebuilt->select_lock_type != LOCK_NONE
|
||||
&& !dict_index_is_spatial(index)) {
|
||||
|
||||
/* Try to place a gap lock on the index
|
||||
record only if innodb_locks_unsafe_for_binlog
|
||||
option is not set or this session is not
|
||||
using a READ COMMITTED or lower isolation level. */
|
||||
|
||||
err = sel_set_rec_lock(
|
||||
pcur,
|
||||
rec, index, offsets,
|
||||
|
@ -4865,17 +4821,7 @@ wrong_offs:
|
|||
if (!cmp_dtuple_is_prefix_of_rec(search_tuple, rec, offsets)) {
|
||||
|
||||
if (set_also_gap_locks
|
||||
&& !(srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED)
|
||||
&& prebuilt->select_lock_type != LOCK_NONE
|
||||
&& !dict_index_is_spatial(index)) {
|
||||
|
||||
/* Try to place a gap lock on the index
|
||||
record only if innodb_locks_unsafe_for_binlog
|
||||
option is not set or this session is not
|
||||
using a READ COMMITTED or lower isolation level. */
|
||||
|
||||
err = sel_set_rec_lock(
|
||||
pcur,
|
||||
rec, index, offsets,
|
||||
|
@ -4915,15 +4861,9 @@ wrong_offs:
|
|||
is a non-delete marked record, then it is enough to lock its
|
||||
existence with LOCK_REC_NOT_GAP. */
|
||||
|
||||
/* If innodb_locks_unsafe_for_binlog option is used
|
||||
or this session is using a READ COMMITED isolation
|
||||
level we lock only the record, i.e., next-key locking is
|
||||
not used. */
|
||||
|
||||
ulint lock_type;
|
||||
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
|
||||
/* At READ COMMITTED or READ UNCOMMITTED
|
||||
isolation levels, do not lock committed
|
||||
delete-marked records. */
|
||||
|
@ -5004,9 +4944,7 @@ no_gap_lock:
|
|||
switch (err) {
|
||||
const rec_t* old_vers;
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED) {
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
|
||||
/* Note that a record of
|
||||
prebuilt->index was locked. */
|
||||
prebuilt->new_rec_locks = 1;
|
||||
|
@ -5069,7 +5007,7 @@ no_gap_lock:
|
|||
goto next_rec;
|
||||
}
|
||||
|
||||
did_semi_consistent_read = TRUE;
|
||||
did_semi_consistent_read = true;
|
||||
rec = old_vers;
|
||||
break;
|
||||
case DB_RECORD_NOT_FOUND:
|
||||
|
@ -5256,9 +5194,7 @@ requires_clust_rec:
|
|||
break;
|
||||
case DB_SUCCESS_LOCKED_REC:
|
||||
ut_a(clust_rec != NULL);
|
||||
if (srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level
|
||||
<= TRX_ISO_READ_COMMITTED) {
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
|
||||
/* Note that the clustered index record
|
||||
was locked. */
|
||||
prebuilt->new_rec_locks = 2;
|
||||
|
@ -5274,8 +5210,7 @@ requires_clust_rec:
|
|||
|
||||
/* The record is delete marked: we can skip it */
|
||||
|
||||
if ((srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
&& prebuilt->select_lock_type != LOCK_NONE) {
|
||||
|
||||
/* No need to keep a lock on a delete-marked
|
||||
|
@ -5499,7 +5434,7 @@ next_rec:
|
|||
== ROW_READ_DID_SEMI_CONSISTENT)) {
|
||||
prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
|
||||
}
|
||||
did_semi_consistent_read = FALSE;
|
||||
did_semi_consistent_read = false;
|
||||
prebuilt->new_rec_locks = 0;
|
||||
vrow = NULL;
|
||||
|
||||
|
@ -5583,7 +5518,7 @@ lock_wait_or_error:
|
|||
== ROW_READ_DID_SEMI_CONSISTENT)) {
|
||||
prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
|
||||
}
|
||||
did_semi_consistent_read = FALSE;
|
||||
did_semi_consistent_read = false;
|
||||
|
||||
/*-------------------------------------------------------------*/
|
||||
if (!dict_index_is_spatial(index)) {
|
||||
|
@ -5626,8 +5561,7 @@ lock_table_wait:
|
|||
moves_up, &mtr);
|
||||
}
|
||||
|
||||
if ((srv_locks_unsafe_for_binlog
|
||||
|| trx->isolation_level <= TRX_ISO_READ_COMMITTED)
|
||||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
&& !same_user_rec) {
|
||||
|
||||
/* Since we were not able to restore the cursor
|
||||
|
|
|
@ -148,9 +148,6 @@ my_bool srv_file_per_table;
|
|||
is greater than SRV_FORCE_NO_TRX_UNDO. */
|
||||
my_bool high_level_read_only;
|
||||
|
||||
/** Place locks to records only i.e. do not use next-key locking except
|
||||
on duplicate key checking and foreign key checking */
|
||||
ibool srv_locks_unsafe_for_binlog;
|
||||
/** Sort buffer size in index creation */
|
||||
ulong srv_sort_buf_size;
|
||||
/** Maximum modification log file size for online index creation */
|
||||
|
|
Loading…
Reference in a new issue