Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
slapos
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
103
Merge Requests
103
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
nexedi
slapos
Commits
d4fef3c9
Commit
d4fef3c9
authored
Sep 30, 2024
by
Kazuhiko Shiozaki
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
component/mariadb: add 11.4.3.
parent
ece52be9
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
961 additions
and
0 deletions
+961
-0
component/mariadb/11.4-0001-Revert-MDEV-19544-Remove-innodb_locks_unsafe_for_bin.patch
...evert-MDEV-19544-Remove-innodb_locks_unsafe_for_bin.patch
+953
-0
component/mariadb/buildout.cfg
component/mariadb/buildout.cfg
+8
-0
No files found.
component/mariadb/11.4-0001-Revert-MDEV-19544-Remove-innodb_locks_unsafe_for_bin.patch
0 → 100644
View file @
d4fef3c9
From dfa6e62251670d4b1f7bb8fb9eed56210198e04b Mon Sep 17 00:00:00 2001
From: Kazuhiko SHIOZAKI <kazuhiko@nexedi.com>
Date: Sun, 29 Sep 2024 11:02:02 +0000
Subject: [PATCH] Revert "MDEV-19544 Remove innodb_locks_unsafe_for_binlog"
Revert "MDEV-19563 Removed references to deprecated option
innodb_locks_unsafe_for_binlog"
also revert part of
*
MDEV-23039 update removed_variables in mysql_upgrade_service for 10.5
*
more "removed" mysqld command-line options
also add main.innodb_locks_unsafe_for_binlog test based on main.unsafe_binlog_innodb.
---
Docs/README-wsrep | 3 +
.../innodb_locks_unsafe_for_binlog-master.opt | 1 +
.../innodb_locks_unsafe_for_binlog.result | 189 ++++++++++++++++++
.../main/innodb_locks_unsafe_for_binlog.test | 16 ++
...nnodb_locks_unsafe_for_binlog_basic.result | 53 +++++
.../suite/sys_vars/r/sysvars_innodb.result | 12 ++
.../innodb_locks_unsafe_for_binlog_basic.test | 106 ++++++++++
.../wsrep_info/mysql-test/wsrep_info/my.cnf | 1 +
sql/mysqld.cc | 1 -
sql/upgrade_conf_file.cc | 1 -
storage/innobase/handler/ha_innodb.cc | 45 ++++-
storage/innobase/include/row0mysql.h | 12 +-
storage/innobase/include/srv0srv.h | 4 +
storage/innobase/lock/lock0lock.cc | 7 +-
storage/innobase/row/row0mysql.cc | 14 +-
storage/innobase/row/row0sel.cc | 89 +++++++--
storage/innobase/srv/srv0srv.cc | 3 +
17 files changed, 515 insertions(+), 42 deletions(-)
create mode 100644 mysql-test/main/innodb_locks_unsafe_for_binlog-master.opt
create mode 100644 mysql-test/main/innodb_locks_unsafe_for_binlog.result
create mode 100644 mysql-test/main/innodb_locks_unsafe_for_binlog.test
create mode 100644 mysql-test/suite/sys_vars/r/innodb_locks_unsafe_for_binlog_basic.result
create mode 100644 mysql-test/suite/sys_vars/t/innodb_locks_unsafe_for_binlog_basic.test
diff --git a/Docs/README-wsrep b/Docs/README-wsrep
index 2e3bf52219d..a4d7d8c0ccb 100644
--- a/Docs/README-wsrep
+++ b/Docs/README-wsrep
@@ -269,6 +269,9 @@
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
diff --git a/mysql-test/main/innodb_locks_unsafe_for_binlog-master.opt b/mysql-test/main/innodb_locks_unsafe_for_binlog-master.opt
new file mode 100644
index 00000000000..0d13f0834a5
--- /dev/null
+++ b/mysql-test/main/innodb_locks_unsafe_for_binlog-master.opt
@@ -0,0 +1 @@
+--loose-innodb_locks_unsafe_for_binlog --loose-innodb_lock_wait_timeout=1
diff --git a/mysql-test/main/innodb_locks_unsafe_for_binlog.result b/mysql-test/main/innodb_locks_unsafe_for_binlog.result
new file mode 100644
index 00000000000..bb407d9562a
--- /dev/null
+++ b/mysql-test/main/innodb_locks_unsafe_for_binlog.result
@@ -0,0 +1,189 @@
+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;
+create table t2 (id int not null,s_id int not null,s varchar(200),
+primary key(id)) engine = InnoDB;
+INSERT INTO t1 VALUES (8, 1, 3);
+INSERT INTO t1 VALUES (1, 2, 1);
+INSERT INTO t2 VALUES (1, 0, '');
+INSERT INTO t2 VALUES (8, 1, '');
+commit;
+DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
+WHERE mm.id IS NULL;
+select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
+where mm.id is null lock in share mode;
+id f_id f
+drop table t1,t2;
+connect a,localhost,root,,;
+connect b,localhost,root,,;
+connection a;
+create table t1(a int not null, b int, primary key(a)) engine = InnoDB;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
+commit;
+set autocommit = 0;
+select * from t1 lock in share mode;
+a b
+1 1
+2 2
+3 1
+4 2
+5 1
+6 2
+7 3
+update t1 set b = 5 where b = 1;
+connection b;
+set autocommit = 0;
+select * from t1 where a = 2 and b = 2 for update;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection a;
+commit;
+connection b;
+commit;
+drop table t1;
+connection default;
+disconnect a;
+disconnect b;
+connect a,localhost,root,,;
+connect b,localhost,root,,;
+connection a;
+create table t1(a int not null, b int, primary key(a)) engine = InnoDB;
+insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
+commit;
+set autocommit = 0;
+update t1 set b = 5 where b = 1;
+connection b;
+set autocommit = 0;
+select * from t1 where a = 7 and b = 3 for update;
+a b
+7 3
+commit;
+connection a;
+commit;
+drop table t1;
+connection default;
+disconnect a;
+disconnect b;
+connect a,localhost,root,,;
+connect b,localhost,root,,;
+connection a;
+create table t1(a int not null, b int, primary key(a)) engine = InnoDB;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(d int not null, e int, primary key(d)) engine = InnoDB;
+insert into t2 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+d e
+3 1
+8 6
+12 1
+connection b;
+set autocommit = 0;
+insert into t1 select * from t2;
+update t1 set b = (select e from t2 where a = d);
+create table t3(d int not null, e int, primary key(d)) engine = InnoDB
+select * from t2;
+commit;
+connection a;
+commit;
+connection default;
+disconnect a;
+disconnect b;
+drop table t1, t2, t3;
+connect a,localhost,root,,;
+connect b,localhost,root,,;
+connect c,localhost,root,,;
+connect d,localhost,root,,;
+SET SESSION DEFAULT_STORAGE_ENGINE = InnoDB;
+connect e,localhost,root,,;
+connect f,localhost,root,,;
+connect g,localhost,root,,;
+SET SESSION DEFAULT_STORAGE_ENGINE = InnoDB;
+connect h,localhost,root,,;
+connect i,localhost,root,,;
+connect j,localhost,root,,;
+SET SESSION DEFAULT_STORAGE_ENGINE = InnoDB;
+connection a;
+create table t1(a int not null, b int, primary key(a)) engine = InnoDB;
+insert into t1 values (1,2),(5,3),(4,2);
+create table t2(a int not null, b int, primary key(a)) engine = InnoDB;
+insert into t2 values (8,6),(12,1),(3,1);
+create table t3(d int not null, b int, primary key(d)) engine = InnoDB;
+insert into t3 values (8,6),(12,1),(3,1);
+create table t5(a int not null, b int, primary key(a)) engine = InnoDB;
+insert into t5 values (1,2),(5,3),(4,2);
+create table t6(d int not null, e int, primary key(d)) engine = InnoDB;
+insert into t6 values (8,6),(12,1),(3,1);
+create table t8(a int not null, b int, primary key(a)) engine = InnoDB;
+insert into t8 values (1,2),(5,3),(4,2);
+create table t9(d int not null, e int, primary key(d)) engine = InnoDB;
+insert into t9 values (8,6),(12,1),(3,1);
+commit;
+set autocommit = 0;
+select * from t2 for update;
+a b
+3 1
+8 6
+12 1
+connection b;
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+insert into t1 select * from t2;
+connection c;
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+update t3 set b = (select b from t2 where a = d);
+connection d;
+set autocommit = 0;
+SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
+create table t4(a int not null, b int, primary key(a)) select * from t2;
+connection e;
+set autocommit = 0;
+insert into t5 (select * from t2 lock in share mode);
+connection f;
+set autocommit = 0;
+update t6 set e = (select b from t2 where a = d lock in share mode);
+connection g;
+set autocommit = 0;
+create table t7(a int not null, b int, primary key(a)) select * from t2 lock in share mode;
+connection h;
+set autocommit = 0;
+insert into t8 (select * from t2 for update);
+connection i;
+set autocommit = 0;
+update t9 set e = (select b from t2 where a = d for update);
+connection j;
+set autocommit = 0;
+create table t10(a int not null, b int, primary key(a)) select * from t2 for update;
+connection b;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection c;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection d;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection e;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection f;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection g;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection h;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection i;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection j;
+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
+connection a;
+commit;
+connection default;
+disconnect a;
+disconnect b;
+disconnect c;
+disconnect d;
+disconnect e;
+disconnect f;
+disconnect g;
+disconnect h;
+disconnect i;
+disconnect j;
+drop table t1, t2, t3, t5, t6, t8, t9;
diff --git a/mysql-test/main/innodb_locks_unsafe_for_binlog.test b/mysql-test/main/innodb_locks_unsafe_for_binlog.test
new file mode 100644
index 00000000000..a0516749451
--- /dev/null
+++ b/mysql-test/main/innodb_locks_unsafe_for_binlog.test
@@ -0,0 +1,16 @@
+# t/unsafe_binlog_innodb.test
+#
+# Note that this test uses at least in case of InnoDB options
+# innodb_locks_unsafe_for_binlog = true
+# innodb_lock_timeout = 5
+#
+# Last update:
+# 2006-08-02 ML test refactored
+# old name was innodb_unsafe_binlog.test
+# main code went into include/unsafe_binlog.inc
+#
+
+--source include/have_innodb.inc
+let $engine_type= InnoDB;
+
+--source include/unsafe_binlog.inc
diff --git a/mysql-test/suite/sys_vars/r/innodb_locks_unsafe_for_binlog_basic.result b/mysql-test/suite/sys_vars/r/innodb_locks_unsafe_for_binlog_basic.result
new file mode 100644
index 00000000000..c2229d54d02
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/innodb_locks_unsafe_for_binlog_basic.result
@@ -0,0 +1,53 @@
+'#---------------------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'
diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
index 869af7f97f4..0475b27030f 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result
@@ -883,6 +883,18 @@
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
+DEFAULT_VALUE OFF
+VARIABLE_SCOPE GLOBAL
+VARIABLE_TYPE BOOLEAN
+VARIABLE_COMMENT 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_WAIT_TIMEOUT
SESSION_VALUE 50
DEFAULT_VALUE 50
diff --git a/mysql-test/suite/sys_vars/t/innodb_locks_unsafe_for_binlog_basic.test b/mysql-test/suite/sys_vars/t/innodb_locks_unsafe_for_binlog_basic.test
new file mode 100644
index 00000000000..755c5c62c70
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_locks_unsafe_for_binlog_basic.test
@@ -0,0 +1,106 @@
+
+
+################## 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'
+
+
diff --git a/plugin/wsrep_info/mysql-test/wsrep_info/my.cnf b/plugin/wsrep_info/mysql-test/wsrep_info/my.cnf
index 5adf6313843..dd4fe296b71 100644
--- a/plugin/wsrep_info/mysql-test/wsrep_info/my.cnf
+++ b/plugin/wsrep_info/mysql-test/wsrep_info/my.cnf
@@ -4,6 +4,7 @@
[mysqld]
binlog-format=row
innodb-autoinc-lock-mode=2
+innodb-locks-unsafe-for-binlog=1
wsrep_provider=@ENV.WSREP_PROVIDER
[mysqld.1]
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 8d5f5d488fb..31f6afcf6e8 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5315,7 +5315,6 @@
static int init_server_components()
MARIADB_REMOVED_OPTION("innodb-defragment-fill-factor-n-recs"),
MARIADB_REMOVED_OPTION("innodb-defragment-frequency"),
MARIADB_REMOVED_OPTION("innodb-idle-flush-pct"),
- MARIADB_REMOVED_OPTION("innodb-locks-unsafe-for-binlog"),
MARIADB_REMOVED_OPTION("innodb-rollback-segments"),
MARIADB_REMOVED_OPTION("innodb-stats-sample-pages"),
MARIADB_REMOVED_OPTION("max-long-data-size"),
diff --git a/sql/upgrade_conf_file.cc b/sql/upgrade_conf_file.cc
index 0d7bc603468..f6f5a9a27e8 100644
--- a/sql/upgrade_conf_file.cc
+++ b/sql/upgrade_conf_file.cc
@@ -94,7 +94,6 @@
static const char *removed_variables[] =
"innodb_large_prefix",
"innodb_lazy_drop_table",
"innodb_locking_fake_changes",
-"innodb_locks_unsafe_for_binlog",
"innodb_log_arch_dir",
"innodb_log_arch_expire_sec",
"innodb_log_archive",
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 34fc2904cc8..c2b6db87181 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -193,6 +193,7 @@
static char* innobase_reset_all_monitor_counter;
stopword table to be used */
static char* innobase_server_stopword_table;
+static my_bool innobase_locks_unsafe_for_binlog;
my_bool innobase_rollback_on_timeout;
static my_bool innobase_create_status_file;
my_bool innobase_stats_on_metadata;
@@ -3953,6 +3954,7 @@
static int innodb_init_params()
}
srv_buf_pool_size = ulint(innobase_buffer_pool_size);
+ srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
if (innobase_open_files < 10) {
innobase_open_files = 300;
@@ -8745,7 +8747,7 @@
ha_innobase::delete_row(
/**********************************************************************//**
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. */
+query, if the option innodb_locks_unsafe_for_binlog is set. */
void
ha_innobase::unlock_row(void)
@@ -8761,8 +8763,11 @@
ha_innobase::unlock_row(void)
switch (m_prebuilt->row_read_type) {
case ROW_READ_WITH_LOCKS:
- if (m_prebuilt->trx->isolation_level > TRX_ISO_READ_COMMITTED)
+ if (!srv_locks_unsafe_for_binlog
+ && 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);
@@ -8789,12 +8794,20 @@
void ha_innobase::try_semi_consistent_read(bool yes)
{
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 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;
+ 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;
+ }
}
/******************************************************************//**
@@ -16535,7 +16548,9 @@
ha_innobase::store_lock(
if (sql_command == SQLCOM_CHECKSUM
|| sql_command == SQLCOM_CREATE_SEQUENCE
|| (sql_command == SQLCOM_ANALYZE && lock_type == TL_READ)
- || (trx->isolation_level <= TRX_ISO_READ_COMMITTED
+ || ((srv_locks_unsafe_for_binlog
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
+ && trx->isolation_level != TRX_ISO_SERIALIZABLE
&& (lock_type == TL_READ
|| lock_type == TL_READ_NO_INSERT)
&& (sql_command == SQLCOM_INSERT_SELECT
@@ -16547,8 +16562,10 @@
ha_innobase::store_lock(
&& sql_command == SQLCOM_ALTER_TABLE
&& lock_type == TL_READ)) {
- /* If the transaction isolation level is
- READ UNCOMMITTED or READ COMMITTED and we are executing
+ /* 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
INSERT INTO...SELECT or REPLACE INTO...SELECT
or UPDATE ... = (SELECT ...) or CREATE ...
SELECT... without FOR UPDATE or IN SHARE
@@ -19010,6 +19027,11 @@
static MYSQL_SYSVAR_ENUM(flush_method, innodb_flush_method,
"With which method to flush data.",
NULL, NULL, innodb_flush_method_default, &innodb_flush_method_typelib);
+static MYSQL_SYSVAR_BOOL(locks_unsafe_for_binlog, innobase_locks_unsafe_for_binlog,
+ PLUGIN_VAR_NOCMDARG | PLUGIN_VAR_READONLY,
+ "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 ib_logfile0", NULL, NULL, NULL);
@@ -19830,6 +19852,7 @@
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(ft_min_token_size),
MYSQL_SYSVAR(ft_num_word_optimize),
MYSQL_SYSVAR(ft_sort_pll_degree),
+ MYSQL_SYSVAR(locks_unsafe_for_binlog),
MYSQL_SYSVAR(lock_wait_timeout),
MYSQL_SYSVAR(deadlock_detect),
MYSQL_SYSVAR(deadlock_report),
diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h
index 878d9c9f1a2..6f7b5cb99d9 100644
--- a/storage/innobase/include/row0mysql.h
+++ b/storage/innobase/include/row0mysql.h
@@ -262,8 +262,8 @@
row_update_for_mysql(
row_prebuilt_t* prebuilt)
MY_ATTRIBUTE((warn_unused_result));
-/** This can only be used when the current transaction is at
-READ COMMITTED or READ UNCOMMITTED isolation level.
+/** 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.
Before calling this function row_search_mvcc() must have
initialized prebuilt->new_rec_locks to store the information which new
record locks really were set. This function removes a newly set
@@ -573,9 +573,8 @@
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.
- At READ UNCOMMITTED or
- READ COMMITTED isolation level,
- this can be set to
+ If innodb_locks_unsafe_for_binlog
+ is TRUE, 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
@@ -597,7 +596,8 @@
struct row_prebuilt_t {
cases; note that this breaks
serializability. */
ulint new_rec_locks; /*!< normally 0; if
- the session is using READ
+ srv_locks_unsafe_for_binlog is
+ TRUE or session is using READ
COMMITTED or READ UNCOMMITTED
isolation level, set in
row_search_mvcc() if we set a new
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 41a93c7d129..fa940c32d3e 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -168,6 +168,10 @@
extern bool high_level_read_only;
dictionary tables are in the system tablespace 0 */
extern my_bool srv_file_per_table;
+/** 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 */
diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc
index 0acb85307bd..35509d47f1d 100644
--- a/storage/innobase/lock/lock0lock.cc
+++ b/storage/innobase/lock/lock0lock.cc
@@ -2473,8 +2473,8 @@
lock_rec_inherit_to_gap(hash_cell_t &heir_cell, const page_id_t heir,
{
ut_ad(!from_split || heir_heap_no == PAGE_HEAP_NO_SUPREMUM);
- /* At READ UNCOMMITTED or READ COMMITTED isolation level,
- we do not want locks set
+ /* If srv_locks_unsafe_for_binlog is TRUE or session is using
+ 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. */
@@ -2485,7 +2485,8 @@
lock_rec_inherit_to_gap(hash_cell_t &heir_cell, const page_id_t heir,
trx_t *lock_trx= lock->trx;
if (!lock->trx->is_not_inheriting_locks() &&
!lock->is_insert_intention() &&
- (lock_trx->isolation_level > TRX_ISO_READ_COMMITTED ||
+ ((!srv_locks_unsafe_for_binlog
+ && lock_trx->isolation_level > TRX_ISO_READ_COMMITTED) ||
/* When we are in a page split (not purge), then we don't set a lock
on supremum if the donor lock type is LOCK_REC_NOT_GAP. That is, do
not create bogus gap locks for non-gap locks for READ UNCOMMITTED and
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 4b570779742..8968c7c8a51 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -1745,8 +1745,8 @@
row_update_for_mysql(row_prebuilt_t* prebuilt)
DBUG_RETURN(err);
}
-/** This can only be used when the current transaction is at
-READ COMMITTED or READ UNCOMMITTED isolation level.
+/** 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.
Before calling this function row_search_mvcc() must have
initialized prebuilt->new_rec_locks to store the information which new
record locks really were set. This function removes a newly set
@@ -1765,7 +1765,15 @@
row_unlock_for_mysql(
{
if (prebuilt->new_rec_locks == 1 && prebuilt->index->is_clust()) {
trx_t* trx = prebuilt->trx;
- 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;
+ }
trx->op_info = "unlock_row";
const rec_t* rec;
diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc
index 46bfb482223..e0e18e87be6 100644
--- a/storage/innobase/row/row0sel.cc
+++ b/storage/innobase/row/row0sel.cc
@@ -1058,14 +1058,16 @@
row_sel_get_clust_rec(
/* Try to place a lock on the index record */
trx_t* trx = thr_get_trx(thr);
- /* At READ UNCOMMITTED or READ COMMITTED isolation level
+ /* 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. */
err = lock_clust_rec_read_check_and_lock(
0, btr_pcur_get_block(&plan->clust_pcur),
clust_rec, index, offsets,
node->row_lock_mode,
- trx->isolation_level <= TRX_ISO_READ_COMMITTED
+ (srv_locks_unsafe_for_binlog
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
? LOCK_REC_NOT_GAP : LOCK_ORDINARY,
thr);
@@ -1834,10 +1836,13 @@
row_sel(
index->n_core_fields,
ULINT_UNDEFINED, &heap);
- /* 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 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) {
if (page_rec_is_supremum(next_rec)) {
goto skip_lock;
}
@@ -1894,10 +1899,12 @@
row_sel(
index->n_core_fields,
ULINT_UNDEFINED, &heap);
- /* At READ UNCOMMITTED or READ COMMITTED isolation level,
+ /* 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 (trx->isolation_level <= TRX_ISO_READ_COMMITTED
+ if (srv_locks_unsafe_for_binlog
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED
|| dict_index_is_spatial(index)) {
if (page_rec_is_supremum(rec)) {
@@ -4772,9 +4779,18 @@
row_search_mvcc(
pcur->old_rec = nullptr;
if (index->is_spatial()) {
+ 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(
- set_also_gap_locks, true, thr,
+ need_pred_lock, true, thr,
btr_pcur_get_btr_cur(pcur));
prebuilt->rtr_info->search_tuple = search_tuple;
prebuilt->rtr_info->search_mode = mode;
@@ -4783,7 +4799,7 @@
row_search_mvcc(
} else {
rtr_info_reinit_in_cursor(
btr_pcur_get_btr_cur(pcur),
- index, set_also_gap_locks);
+ index, need_pred_lock);
prebuilt->rtr_info->search_tuple = search_tuple;
prebuilt->rtr_info->search_mode = mode;
}
@@ -4809,6 +4825,9 @@
row_search_mvcc(
if (!moves_up
&& 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)) {
@@ -4929,12 +4948,16 @@
row_search_mvcc(
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
&& !dict_index_is_spatial(index)) {
/* Try to place a lock on the index record */
- /* If the transaction isolation level is
- READ UNCOMMITTED or READ COMMITTED,
+ /* 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
we do not lock gaps. Supremum record is really
a gap and therefore we do not set locks there. */
@@ -5074,7 +5097,17 @@
row_search_mvcc(
if (cmp_dtuple_rec(search_tuple, rec, index, 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,
@@ -5110,7 +5143,17 @@
row_search_mvcc(
index, 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,
@@ -5150,9 +5193,15 @@
row_search_mvcc(
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. */
+
unsigned lock_type;
- if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
+ if (srv_locks_unsafe_for_binlog
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
/* At READ COMMITTED or READ UNCOMMITTED
isolation levels, do not lock committed
delete-marked records. */
@@ -5242,7 +5291,9 @@
row_search_mvcc(
switch (err) {
const rec_t* old_vers;
case DB_SUCCESS_LOCKED_REC:
- if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
+ if (srv_locks_unsafe_for_binlog
+ || trx->isolation_level
+ <= TRX_ISO_READ_COMMITTED) {
/* Note that a record of
prebuilt->index was locked. */
prebuilt->new_rec_locks = 1;
@@ -5541,7 +5592,9 @@
row_search_mvcc(
break;
case DB_SUCCESS_LOCKED_REC:
ut_a(clust_rec != NULL);
- if (trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
+ if (srv_locks_unsafe_for_binlog
+ || trx->isolation_level
+ <= TRX_ISO_READ_COMMITTED) {
/* Note that the clustered index record
was locked. */
prebuilt->new_rec_locks = 2;
@@ -5564,7 +5617,8 @@
row_search_mvcc(
/* The record is delete marked: we can skip it */
- if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
+ if ((srv_locks_unsafe_for_binlog
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
&& prebuilt->select_lock_type != LOCK_NONE) {
/* No need to keep a lock on a delete-marked
@@ -5883,7 +5937,8 @@
row_search_mvcc(
moves_up, &mtr);
}
- if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
+ if ((srv_locks_unsafe_for_binlog
+ || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
&& !same_user_rec) {
/* Since we were not able to restore the cursor
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index cd218d97b8c..28aec0592a7 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -125,6 +125,9 @@
my_bool srv_file_per_table;
is SRV_FORCE_NO_UNDO_LOG_SCAN or greater. */
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 */
--
2.40.1
component/mariadb/buildout.cfg
View file @
d4fef3c9
...
...
@@ -117,6 +117,14 @@ patch-options = -p1
patches =
${:_profile_base_location_}/10.11-0001-Revert-MDEV-19544-Remove-innodb_locks_unsafe_for_bin.patch#bba15e0458b1ced02bc8bc949e88cd72
[mariadb-11.4]
<= mariadb-common
version = 11.4.3
md5sum = c19f97dc1ea3165fb282a8384155dc0a
patch-options = -p1
patches =
${:_profile_base_location_}/11.4-0001-Revert-MDEV-19544-Remove-innodb_locks_unsafe_for_bin.patch#4466f02817202674ebdc401f9f64d23a
[mariadb]
<= mariadb-10.4
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment