mirror of
https://github.com/MariaDB/server.git
synced 2025-01-26 00:34:18 +01:00
Merge branch '10.6' into 10.7
This commit is contained in:
commit
795ff0daf0
46 changed files with 740 additions and 114 deletions
CREDITS
cmake
extra/wolfssl
libmariadbmysql-test
main
suite
federated
galera
r
galera_MDEV-29512.resultgalera_gcache_recover.resultgalera_gcache_recover_manytrx.resultgalera_savepoint_replay.result
t
galera_3nodes
galera_3nodes_sr/t
innodb
sql
field.hhandler.hitem.ccitem.hitem_jsonfunc.ccopt_subselect.ccservice_wsrep.ccsql_class.ccsql_lex.hsql_select.ccsql_select.hsql_table.ccwsrep_high_priority_service.ccwsrep_mysqld.ccwsrep_thd.ccwsrep_thd.h
storage/innobase
2
CREDITS
2
CREDITS
|
@ -9,10 +9,8 @@ MariaDB Corporation https://www.mariadb.com (2013)
|
|||
Microsoft https://microsoft.com/ (2017)
|
||||
ServiceNow https://servicenow.com (2019)
|
||||
SIT https://sit.org (2022)
|
||||
Tencent Cloud https://cloud.tencent.com (2017)
|
||||
Development Bank of Singapore https://dbs.com (2016)
|
||||
IBM https://www.ibm.com (2017)
|
||||
Visma https://visma.com (2015)
|
||||
Automattic https://automattic.com (2019)
|
||||
Galera Cluster https://galeracluster.com (2020)
|
||||
Percona https://www.percona.com (2018)
|
||||
|
|
|
@ -54,8 +54,8 @@ MACRO(BUNDLE_PCRE2)
|
|||
ExternalProject_Add(
|
||||
pcre2
|
||||
PREFIX "${dir}"
|
||||
URL "https://github.com/PhilipHazel/pcre2/releases/download/pcre2-10.40/pcre2-10.40.zip"
|
||||
URL_MD5 798698846982ce171d881ed0d7535c2a
|
||||
URL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.42/pcre2-10.42.zip"
|
||||
URL_MD5 fe90992fbfb03f854bd9f344074f49eb
|
||||
INSTALL_COMMAND ""
|
||||
CMAKE_ARGS
|
||||
"-DCMAKE_WARN_DEPRECATED=FALSE"
|
||||
|
|
|
@ -157,6 +157,8 @@ IF(WOLFSSL_X86_64_BUILD)
|
|||
${WOLFCRYPT_SRCDIR}/sha512_asm.S
|
||||
${WOLFCRYPT_SRCDIR}/sha256_asm.S)
|
||||
ADD_DEFINITIONS(-maes -msse4.2 -mpclmul)
|
||||
# WolfSSL 5.5.4 bug - user_settings.h not included into aes_asm.S
|
||||
SET_PROPERTY(SOURCE ${WOLFCRYPT_SRCDIR}/aes_asm.S APPEND PROPERTY COMPILE_OPTIONS "-DWOLFSSL_X86_64_BUILD")
|
||||
ENDIF()
|
||||
ENDIF()
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit f1e2165c591f074feb47872a8ff712713ec411e1
|
||||
Subproject commit 4fbd4fd36a21efd9d1a7e17aba390e91c78693b1
|
|
@ -1 +1 @@
|
|||
Subproject commit 72b40bfaa869f3fe84242471dda989d13983d84c
|
||||
Subproject commit 12bd1d5511fc2ff766ff6256c71b79a95739533f
|
|
@ -183,7 +183,9 @@ t1 CREATE TABLE `t1` (
|
|||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
DROP PROCEDURE sp;
|
||||
DROP TABLE t1;
|
||||
#
|
||||
# End of 10.2 tests
|
||||
#
|
||||
create table t1 (a int check (a>10)) select 100 as 'a';
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
|
@ -201,3 +203,35 @@ a
|
|||
19
|
||||
ccc
|
||||
drop table t1;
|
||||
create table t1 (a int, b int);
|
||||
create procedure sp() alter table t1 add constraint if not exists foo check (b > 0);
|
||||
call sp;
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
CONSTRAINT `foo` CHECK (`b` > 0)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
call sp;
|
||||
Warnings:
|
||||
Note 1826 Duplicate CHECK constraint name 'foo'
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
CONSTRAINT `foo` CHECK (`b` > 0)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
call sp;
|
||||
Warnings:
|
||||
Note 1826 Duplicate CHECK constraint name 'foo'
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) DEFAULT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
CONSTRAINT `foo` CHECK (`b` > 0)
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci
|
||||
drop procedure sp;
|
||||
drop table t1;
|
||||
|
|
|
@ -151,7 +151,9 @@ show create table t1;
|
|||
DROP PROCEDURE sp;
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.2 tests
|
||||
--echo #
|
||||
|
||||
#
|
||||
# Check that we don't lose constraints as part of CREATE ... SELECT
|
||||
|
@ -172,3 +174,18 @@ insert into t1 values ("ccc");
|
|||
insert into t1 values ("");
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# add if not exists in SP
|
||||
#
|
||||
|
||||
create table t1 (a int, b int);
|
||||
create procedure sp() alter table t1 add constraint if not exists foo check (b > 0);
|
||||
call sp;
|
||||
show create table t1;
|
||||
call sp;
|
||||
show create table t1;
|
||||
call sp;
|
||||
show create table t1;
|
||||
drop procedure sp;
|
||||
drop table t1;
|
||||
|
|
|
@ -1611,6 +1611,18 @@ SELECT json_object('a', coalesce(json_object('b', 'c')));
|
|||
json_object('a', coalesce(json_object('b', 'c')))
|
||||
{"a": {"b": "c"}}
|
||||
#
|
||||
# MDEV-26392: Crash with json_get_path_next and 10.5.12
|
||||
#
|
||||
CREATE TABLE arrNestTest (
|
||||
id VARCHAR(80) AS (JSON_COMPACT(JSON_EXTRACT(doc, "$._id"))) UNIQUE KEY,
|
||||
doc JSON,
|
||||
CONSTRAINT id_not_null CHECK(id IS NOT NULL));
|
||||
INSERT INTO test.arrNestTest (doc) VALUES ('{ "_id" : { "$oid" : "611c0a463b150154132f6636" }, "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : 1.0 } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] }');
|
||||
SELECT * FROM arrNestTest;
|
||||
id doc
|
||||
{"$oid":"611c0a463b150154132f6636"} { "_id" : { "$oid" : "611c0a463b150154132f6636" }, "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : 1.0 } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] }
|
||||
DROP TABLE arrNestTest;
|
||||
#
|
||||
# MDEV-26054 Server crashes in Item_func_json_arrayagg::get_str_from_field
|
||||
#
|
||||
CREATE TABLE t (a VARCHAR(8));
|
||||
|
|
|
@ -1054,6 +1054,18 @@ DROP TABLE t2;
|
|||
SELECT json_object('a', if(1, json_object('b', 'c'), json_object('e', 'f')));
|
||||
SELECT json_object('a', coalesce(json_object('b', 'c')));
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-26392: Crash with json_get_path_next and 10.5.12
|
||||
--echo #
|
||||
|
||||
CREATE TABLE arrNestTest (
|
||||
id VARCHAR(80) AS (JSON_COMPACT(JSON_EXTRACT(doc, "$._id"))) UNIQUE KEY,
|
||||
doc JSON,
|
||||
CONSTRAINT id_not_null CHECK(id IS NOT NULL));
|
||||
|
||||
INSERT INTO test.arrNestTest (doc) VALUES ('{ "_id" : { "$oid" : "611c0a463b150154132f6636" }, "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : 1.0 } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] }');
|
||||
SELECT * FROM arrNestTest;
|
||||
DROP TABLE arrNestTest;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-26054 Server crashes in Item_func_json_arrayagg::get_str_from_field
|
||||
|
|
|
@ -3407,3 +3407,20 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
drop table t1,t2,t3;
|
||||
drop table t1000,t10,t03;
|
||||
# End of 10.3 tests
|
||||
#
|
||||
# MDEV-30080 Wrong result with LEFT JOINs involving constant tables
|
||||
#
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES (1),(1);
|
||||
CREATE TABLE t3 (c INT PRIMARY KEY) ENGINE=MyISAM;
|
||||
SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.b;
|
||||
a b c
|
||||
1 1 NULL
|
||||
1 1 NULL
|
||||
SELECT COUNT(*) FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.b;
|
||||
COUNT(*)
|
||||
2
|
||||
DROP TABLE t1, t2, t3;
|
||||
# End of 10.5 tests
|
||||
|
|
|
@ -1820,3 +1820,18 @@ drop table t1,t2,t3;
|
|||
drop table t1000,t10,t03;
|
||||
|
||||
--echo # End of 10.3 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30080 Wrong result with LEFT JOINs involving constant tables
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
|
||||
INSERT INTO t2 VALUES (1),(1);
|
||||
CREATE TABLE t3 (c INT PRIMARY KEY) ENGINE=MyISAM;
|
||||
SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.b;
|
||||
SELECT COUNT(*) FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.b = t3.c) ON t1.a = t2.b;
|
||||
DROP TABLE t1, t2, t3;
|
||||
|
||||
--echo # End of 10.5 tests
|
||||
|
|
|
@ -2325,6 +2325,38 @@ DROP TABLE federated.t1;
|
|||
connection slave;
|
||||
DROP TABLE federated.t1;
|
||||
connection default;
|
||||
#
|
||||
# MDEV-30395 Wrong result with semijoin and Federated as outer table
|
||||
#
|
||||
create server s foreign data wrapper mysql options (host "127.0.0.1", database "test", user "root", port MASTER_PORT);
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (3),(2),(3);
|
||||
CREATE TABLE t2 (pk INT PRIMARY KEY);
|
||||
INSERT INTO t2 VALUES (1),(2),(3),(4);
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set optimizer_switch="materialization=off";
|
||||
CREATE TABLE t2_fed ENGINE=FEDERATED CONNECTION='s/t2';
|
||||
explain SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2_fed ALL NULL NULL NULL NULL 4 Using where
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||
SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
|
||||
pk
|
||||
2
|
||||
3
|
||||
SET optimizer_switch='semijoin=off';
|
||||
explain SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2_fed ALL NULL NULL NULL NULL 4 Using where
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 3 Using where
|
||||
SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
|
||||
pk
|
||||
2
|
||||
3
|
||||
DROP TABLE t2_fed, t1, t2;
|
||||
set @@optimizer_switch=@save_optimizer_switch;
|
||||
DROP SERVER s;
|
||||
# End of 10.5 tests
|
||||
connection master;
|
||||
DROP TABLE IF EXISTS federated.t1;
|
||||
DROP DATABASE IF EXISTS federated;
|
||||
|
|
|
@ -2060,4 +2060,34 @@ connection slave;
|
|||
DROP TABLE federated.t1;
|
||||
connection default;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-30395 Wrong result with semijoin and Federated as outer table
|
||||
--echo #
|
||||
|
||||
|
||||
--replace_result $MASTER_MYPORT MASTER_PORT
|
||||
eval create server s foreign data wrapper mysql options (host "127.0.0.1", database "test", user "root", port $MASTER_MYPORT);
|
||||
|
||||
CREATE TABLE t1 (a INT);
|
||||
INSERT INTO t1 VALUES (3),(2),(3);
|
||||
CREATE TABLE t2 (pk INT PRIMARY KEY);
|
||||
INSERT INTO t2 VALUES (1),(2),(3),(4);
|
||||
|
||||
set @save_optimizer_switch=@@optimizer_switch;
|
||||
set optimizer_switch="materialization=off";
|
||||
|
||||
CREATE TABLE t2_fed ENGINE=FEDERATED CONNECTION='s/t2';
|
||||
explain SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
|
||||
SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
|
||||
SET optimizer_switch='semijoin=off';
|
||||
explain SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
|
||||
SELECT * FROM t2_fed WHERE pk IN ( SELECT a FROM t1 );
|
||||
|
||||
DROP TABLE t2_fed, t1, t2;
|
||||
set @@optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
DROP SERVER s;
|
||||
|
||||
--echo # End of 10.5 tests
|
||||
|
||||
source include/federated_cleanup.inc;
|
||||
|
|
40
mysql-test/suite/galera/r/galera_MDEV-29512.result
Normal file
40
mysql-test/suite/galera/r/galera_MDEV-29512.result
Normal file
|
@ -0,0 +1,40 @@
|
|||
connection node_2;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 int, f3 varchar(2000));
|
||||
INSERT INTO t1 VALUES (1, 0, REPEAT('1234567890', 200));
|
||||
INSERT INTO t1 VALUES (3, 3, REPEAT('1234567890', 200));
|
||||
SET SESSION wsrep_sync_wait=0;
|
||||
SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb";
|
||||
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connection node_1a;
|
||||
SET SESSION wsrep_sync_wait=0;
|
||||
connection node_1;
|
||||
begin;
|
||||
select f1,f2 from t1;
|
||||
f1 f2
|
||||
1 0
|
||||
3 3
|
||||
connection node_2;
|
||||
UPDATE t1 SET f2=2 WHERE f1=3;
|
||||
connection node_1a;
|
||||
SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
|
||||
connection node_1;
|
||||
UPDATE t1 SET f2=1 WHERE f1=3;
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync';
|
||||
COMMIT;
|
||||
connection node_1a;
|
||||
SET SESSION wsrep_on = 0;
|
||||
SET SESSION wsrep_on = 1;
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
|
||||
SET GLOBAL debug_dbug = NULL;
|
||||
SET debug_sync='RESET';
|
||||
connection node_1;
|
||||
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
|
||||
select f1,f2 from t1;
|
||||
f1 f2
|
||||
1 0
|
||||
3 2
|
||||
DROP TABLE t1;
|
|
@ -20,8 +20,6 @@ connection node_1;
|
|||
include/diff_servers.inc [servers=1 2]
|
||||
connection node_1;
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
include/assert_grep.inc [async IST sender starting to serve]
|
||||
connection node_2;
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
include/assert_grep.inc [Recovering GCache ring buffer: found gapless sequence]
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -134,8 +134,6 @@ connection node_1;
|
|||
call mtr.add_suppression("Error in Log_event::read_log_event():.*");
|
||||
CALL mtr.add_suppression("conflict state 7 after post commit");
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
include/assert_grep.inc [async IST sender starting to serve]
|
||||
connection node_2;
|
||||
call mtr.add_suppression("Error in Log_event::read_log_event():.*");
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
include/assert_grep.inc [Recovering GCache ring buffer: found gapless sequence]
|
||||
|
|
53
mysql-test/suite/galera/r/galera_savepoint_replay.result
Normal file
53
mysql-test/suite/galera/r/galera_savepoint_replay.result
Normal file
|
@ -0,0 +1,53 @@
|
|||
connection node_2;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
|
||||
INSERT INTO t1 VALUES (1, 'a');
|
||||
INSERT INTO t1 VALUES (2, 'a');
|
||||
connection node_1;
|
||||
SET AUTOCOMMIT=ON;
|
||||
START TRANSACTION;
|
||||
UPDATE t1 SET f2 = 'b' WHERE f1 = 1;
|
||||
SELECT * FROM t1 WHERE f1 = 2 FOR UPDATE;
|
||||
f1 f2
|
||||
2 a
|
||||
SAVEPOINT my_sp;
|
||||
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
SET SESSION wsrep_sync_wait=0;
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
|
||||
connection node_2;
|
||||
UPDATE t1 SET f2 = 'c' WHERE f1 = 2;
|
||||
connection node_1a;
|
||||
SET SESSION wsrep_on = 0;
|
||||
SET SESSION wsrep_on = 1;
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_master_enter_sync';
|
||||
connection node_1;
|
||||
COMMIT;
|
||||
connection node_1a;
|
||||
SET SESSION wsrep_on = 0;
|
||||
SET SESSION wsrep_on = 1;
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=d,abort_trx_end';
|
||||
SET GLOBAL wsrep_provider_options = 'signal=apply_monitor_slave_enter_sync';
|
||||
SET SESSION wsrep_on = 0;
|
||||
SET SESSION wsrep_on = 1;
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||
SET GLOBAL wsrep_provider_options = 'signal=abort_trx_end';
|
||||
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_master_enter_sync';
|
||||
connection node_1;
|
||||
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'b';
|
||||
COUNT(*) = 1
|
||||
1
|
||||
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c';
|
||||
COUNT(*) = 1
|
||||
1
|
||||
wsrep_local_replays
|
||||
1
|
||||
connection node_2;
|
||||
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'b';
|
||||
COUNT(*) = 1
|
||||
1
|
||||
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c';
|
||||
COUNT(*) = 1
|
||||
1
|
||||
DROP TABLE t1;
|
15
mysql-test/suite/galera/t/galera_MDEV-29512.cnf
Normal file
15
mysql-test/suite/galera/t/galera_MDEV-29512.cnf
Normal file
|
@ -0,0 +1,15 @@
|
|||
!include ../galera_2nodes.cnf
|
||||
|
||||
[mysqld]
|
||||
log-bin
|
||||
log-slave-updates
|
||||
|
||||
[mysqld.1]
|
||||
log_bin
|
||||
log_slave_updates
|
||||
max-binlog-size=4096
|
||||
expire-logs-days=1
|
||||
|
||||
|
||||
[mysqld.2]
|
||||
|
91
mysql-test/suite/galera/t/galera_MDEV-29512.test
Normal file
91
mysql-test/suite/galera/t/galera_MDEV-29512.test
Normal file
|
@ -0,0 +1,91 @@
|
|||
#
|
||||
# This test is for reproducing the issue in:
|
||||
# https://jira.mariadb.org/browse/MDEV-29512
|
||||
#
|
||||
# The hanging in MDEV-29512 happens when binlog purging is attempted, and there is
|
||||
# one local BF aborted transaction waiting for commit monitor.
|
||||
#
|
||||
# The test will launch two node cluster and enable binlogging with expire log days,
|
||||
# to force binlog purging to happen.
|
||||
# A local transaction is executed so that will become BF abort victim, and has advanced
|
||||
# to replication stage waiting for commit monitor for final cleanup (to mark position in innodb)
|
||||
# after that, applier is released to complete the BF abort and due to binlog configuration,
|
||||
# starting the binlog purging. This is where the hanging would occur, if code is buggy
|
||||
#
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/galera_have_debug_sync.inc
|
||||
|
||||
#
|
||||
# binlog size is limited to 4096 bytes, we will create enough events to
|
||||
# cause binlog rotation
|
||||
#
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 int, f3 varchar(2000));
|
||||
INSERT INTO t1 VALUES (1, 0, REPEAT('1234567890', 200));
|
||||
INSERT INTO t1 VALUES (3, 3, REPEAT('1234567890', 200));
|
||||
|
||||
SET SESSION wsrep_sync_wait=0;
|
||||
|
||||
# set sync point for replication applier
|
||||
SET GLOBAL DEBUG_DBUG = "d,sync.wsrep_apply_cb";
|
||||
|
||||
# Control connection to manage sync points for appliers
|
||||
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--connection node_1a
|
||||
SET SESSION wsrep_sync_wait=0;
|
||||
|
||||
# starting local transaction, only select so far,
|
||||
# write will happen later and this will be ordered after the transaction in node_2
|
||||
--connection node_1
|
||||
begin;
|
||||
select f1,f2 from t1;
|
||||
|
||||
# send from node 2 an UPDATE transaction, which will BF abort the transaction in node_1
|
||||
--connection node_2
|
||||
--let $wait_condition=select count(*)=2 from t1
|
||||
--source include/wait_condition.inc
|
||||
|
||||
UPDATE t1 SET f2=2 WHERE f1=3;
|
||||
|
||||
--connection node_1a
|
||||
# wait to see the UPDATE from node_2 in apply_cb sync point
|
||||
SET SESSION DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_cb_reached";
|
||||
|
||||
--connection node_1
|
||||
# now issuing conflicting update
|
||||
UPDATE t1 SET f2=1 WHERE f1=3;
|
||||
|
||||
# Block the local commit, send final COMMIT and wait until it gets blocked
|
||||
--let $galera_sync_point = commit_monitor_master_enter_sync
|
||||
--source include/galera_set_sync_point.inc
|
||||
--send COMMIT
|
||||
|
||||
--connection node_1a
|
||||
# wait for the local commit to enter in commit monitor wait state
|
||||
--let $galera_sync_point = commit_monitor_master_enter_sync
|
||||
--source include/galera_wait_sync_point.inc
|
||||
--source include/galera_clear_sync_point.inc
|
||||
|
||||
# release the local transaction to continue with commit
|
||||
--let $galera_sync_point = commit_monitor_master_enter_sync
|
||||
--source include/galera_signal_sync_point.inc
|
||||
|
||||
# and now release the applier, it should force local trx to abort
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_cb";
|
||||
SET GLOBAL debug_dbug = NULL;
|
||||
SET debug_sync='RESET';
|
||||
|
||||
--connection node_1
|
||||
--error ER_LOCK_DEADLOCK
|
||||
--reap
|
||||
|
||||
# wait until applying is complete
|
||||
--let $wait_condition = SELECT COUNT(*)=1 FROM t1 WHERE f2=2
|
||||
--source include/wait_condition.inc
|
||||
|
||||
# final read to verify what we got
|
||||
select f1,f2 from t1;
|
||||
|
||||
DROP TABLE t1;
|
|
@ -54,24 +54,7 @@ INSERT INTO t1 VALUES (3);
|
|||
# Warning happens when the cluster is started for the first time
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
|
||||
# Confirm that IST took place
|
||||
--let $assert_text = async IST sender starting to serve
|
||||
--let $assert_select = async IST sender starting to serve
|
||||
--let $assert_count = 1
|
||||
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let $assert_only_after = starting as process
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--connection node_2
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
|
||||
# Confirm that gcache recovery took place
|
||||
|
||||
--let $assert_text = Recovering GCache ring buffer: found gapless sequence
|
||||
--let $assert_select = Recovering GCache ring buffer: found gapless sequence
|
||||
--let $assert_count = 1
|
||||
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err
|
||||
--let $assert_only_after = starting as process
|
||||
--source include/assert_grep.inc
|
||||
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -206,23 +206,7 @@ CALL mtr.add_suppression("conflict state 7 after post commit");
|
|||
# Warning happens when the cluster is started for the first time
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
|
||||
# Confirm that IST took place
|
||||
--let $assert_text = async IST sender starting to serve
|
||||
--let $assert_select = async IST sender starting to serve
|
||||
--let $assert_count = 1
|
||||
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let $assert_only_after = starting as process
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--connection node_2
|
||||
call mtr.add_suppression("Error in Log_event::read_log_event():.*");
|
||||
CALL mtr.add_suppression("Skipped GCache ring buffer recovery");
|
||||
|
||||
# Confirm that gcache recovery took place
|
||||
|
||||
--let $assert_text = Recovering GCache ring buffer: found gapless sequence
|
||||
--let $assert_select = Recovering GCache ring buffer: found gapless sequence
|
||||
--let $assert_count = 1
|
||||
--let $assert_file = $MYSQLTEST_VARDIR/log/mysqld.2.err
|
||||
--let $assert_only_after = starting as process
|
||||
--source include/assert_grep.inc
|
||||
|
|
86
mysql-test/suite/galera/t/galera_savepoint_replay.test
Normal file
86
mysql-test/suite/galera/t/galera_savepoint_replay.test
Normal file
|
@ -0,0 +1,86 @@
|
|||
#
|
||||
# This test tests replaying a transaction with savepoint
|
||||
#
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_debug_sync.inc
|
||||
--source include/galera_have_debug_sync.inc
|
||||
|
||||
--let $wsrep_local_replays_old = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
|
||||
INSERT INTO t1 VALUES (1, 'a');
|
||||
INSERT INTO t1 VALUES (2, 'a');
|
||||
|
||||
--connection node_1
|
||||
SET AUTOCOMMIT=ON;
|
||||
START TRANSACTION;
|
||||
|
||||
UPDATE t1 SET f2 = 'b' WHERE f1 = 1;
|
||||
SELECT * FROM t1 WHERE f1 = 2 FOR UPDATE;
|
||||
SAVEPOINT my_sp;
|
||||
|
||||
# Block the applier on node #1 and issue a conflicting update on node #2
|
||||
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
SET SESSION wsrep_sync_wait=0;
|
||||
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||
--source include/galera_set_sync_point.inc
|
||||
|
||||
--connection node_2
|
||||
UPDATE t1 SET f2 = 'c' WHERE f1 = 2;
|
||||
|
||||
--connection node_1a
|
||||
--source include/galera_wait_sync_point.inc
|
||||
--source include/galera_clear_sync_point.inc
|
||||
|
||||
# Block the commit, send the COMMIT and wait until it gets blocked
|
||||
|
||||
--let $galera_sync_point = commit_monitor_master_enter_sync
|
||||
--source include/galera_set_sync_point.inc
|
||||
|
||||
--connection node_1
|
||||
--send COMMIT
|
||||
|
||||
--connection node_1a
|
||||
|
||||
--let $galera_sync_point = apply_monitor_slave_enter_sync commit_monitor_master_enter_sync
|
||||
--source include/galera_wait_sync_point.inc
|
||||
--source include/galera_clear_sync_point.inc
|
||||
|
||||
# Let the conflicting UPDATE proceed and wait until it hits abort_trx_end.
|
||||
# The victim transaction still sits in commit_monitor_master_sync_point.
|
||||
|
||||
--let $galera_sync_point = abort_trx_end
|
||||
--source include/galera_set_sync_point.inc
|
||||
--let $galera_sync_point = apply_monitor_slave_enter_sync
|
||||
--source include/galera_signal_sync_point.inc
|
||||
--let $galera_sync_point = abort_trx_end commit_monitor_master_enter_sync
|
||||
--source include/galera_wait_sync_point.inc
|
||||
|
||||
# Let the transactions proceed
|
||||
--source include/galera_clear_sync_point.inc
|
||||
--let $galera_sync_point = abort_trx_end
|
||||
--source include/galera_signal_sync_point.inc
|
||||
--let $galera_sync_point = commit_monitor_master_enter_sync
|
||||
--source include/galera_signal_sync_point.inc
|
||||
|
||||
# Commit succeeds
|
||||
--connection node_1
|
||||
--reap
|
||||
|
||||
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'b';
|
||||
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c';
|
||||
|
||||
# wsrep_local_replays has increased by 1
|
||||
--let $wsrep_local_replays_new = `SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_local_replays'`
|
||||
--disable_query_log
|
||||
--eval SELECT $wsrep_local_replays_new - $wsrep_local_replays_old = 1 AS wsrep_local_replays;
|
||||
--enable_query_log
|
||||
|
||||
--connection node_2
|
||||
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'b';
|
||||
SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c';
|
||||
|
||||
DROP TABLE t1;
|
||||
|
41
mysql-test/suite/galera_3nodes/r/MDEV-29171.result
Normal file
41
mysql-test/suite/galera_3nodes/r/MDEV-29171.result
Normal file
|
@ -0,0 +1,41 @@
|
|||
connection node_2;
|
||||
connection node_1;
|
||||
connection node_1;
|
||||
select @@wsrep_gtid_domain_id,@@wsrep_node_name;
|
||||
@@wsrep_gtid_domain_id @@wsrep_node_name
|
||||
100 node1
|
||||
connection node_2;
|
||||
select @@wsrep_gtid_domain_id,@@wsrep_node_name;
|
||||
@@wsrep_gtid_domain_id @@wsrep_node_name
|
||||
100 node2
|
||||
connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3;
|
||||
connection node_3;
|
||||
select @@wsrep_gtid_domain_id,@@wsrep_node_name;
|
||||
@@wsrep_gtid_domain_id @@wsrep_node_name
|
||||
100 node3
|
||||
connection node_3;
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
connection node_1;
|
||||
# restart: --wsrep_new_cluster --wsrep_gtid_domain_id=200
|
||||
show variables like 'wsrep_gtid_domain_id';
|
||||
Variable_name Value
|
||||
wsrep_gtid_domain_id 200
|
||||
connection node_2;
|
||||
# restart
|
||||
show variables like 'wsrep_gtid_domain_id';
|
||||
Variable_name Value
|
||||
wsrep_gtid_domain_id 200
|
||||
connection node_3;
|
||||
# restart: --wsrep_sst_donor=node2
|
||||
show variables like 'wsrep_gtid_domain_id';
|
||||
Variable_name Value
|
||||
wsrep_gtid_domain_id 200
|
||||
connection node_1;
|
||||
set global wsrep_gtid_domain_id=100;
|
||||
connection node_2;
|
||||
set global wsrep_gtid_domain_id=100;
|
||||
CALL mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node.");
|
||||
connection node_3;
|
||||
set global wsrep_gtid_domain_id=100;
|
||||
CALL mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node.");
|
14
mysql-test/suite/galera_3nodes/t/MDEV-29171.cnf
Normal file
14
mysql-test/suite/galera_3nodes/t/MDEV-29171.cnf
Normal file
|
@ -0,0 +1,14 @@
|
|||
!include ../galera_3nodes.cnf
|
||||
|
||||
[mysqld.1]
|
||||
wsrep-node-name="node1"
|
||||
wsrep-gtid-mode=ON
|
||||
wsrep-gtid-domain-id=100
|
||||
|
||||
[mysqld.2]
|
||||
wsrep-node-name="node2"
|
||||
wsrep-gtid-mode=ON
|
||||
|
||||
[mysqld.3]
|
||||
wsrep-node-name="node3"
|
||||
wsrep-gtid-mode=ON
|
83
mysql-test/suite/galera_3nodes/t/MDEV-29171.test
Normal file
83
mysql-test/suite/galera_3nodes/t/MDEV-29171.test
Normal file
|
@ -0,0 +1,83 @@
|
|||
#
|
||||
# MDEV-29171: changing the value of wsrep_gtid_domain_id
|
||||
# with full cluster restart fails on some nodes
|
||||
#
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_innodb.inc
|
||||
|
||||
#
|
||||
# Initially wsrep gtid domain id is 100
|
||||
#
|
||||
--connection node_1
|
||||
select @@wsrep_gtid_domain_id,@@wsrep_node_name;
|
||||
|
||||
--connection node_2
|
||||
select @@wsrep_gtid_domain_id,@@wsrep_node_name;
|
||||
|
||||
--connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3
|
||||
--connection node_3
|
||||
select @@wsrep_gtid_domain_id,@@wsrep_node_name;
|
||||
|
||||
|
||||
#
|
||||
# Shutdown all nodes
|
||||
#
|
||||
--connection node_3
|
||||
--source include/shutdown_mysqld.inc
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||
--source include/wait_condition.inc
|
||||
--source include/shutdown_mysqld.inc
|
||||
|
||||
--connection node_1
|
||||
--let $wait_condition = SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||
--source include/wait_condition.inc
|
||||
--source include/shutdown_mysqld.inc
|
||||
|
||||
|
||||
#
|
||||
# Bootstrap from node_1 and change wsrep_gtid_domain_id to 200
|
||||
#
|
||||
--connection node_1
|
||||
--let $restart_parameters = --wsrep_new_cluster --wsrep_gtid_domain_id=200
|
||||
--source include/start_mysqld.inc
|
||||
show variables like 'wsrep_gtid_domain_id';
|
||||
|
||||
|
||||
#
|
||||
# Restart node_2, expect that wsrep_gtid_domain_id has changed to 200
|
||||
#
|
||||
--connection node_2
|
||||
--let $restart_parameters =
|
||||
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.2.expect
|
||||
--source include/start_mysqld.inc
|
||||
show variables like 'wsrep_gtid_domain_id';
|
||||
|
||||
|
||||
#
|
||||
# Restart node_3, select node_2 as donor
|
||||
# If bug is present, node_3 remains on domain id 100
|
||||
#
|
||||
--connection node_3
|
||||
--let $restart_parameters = --wsrep_sst_donor="node2"
|
||||
--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.3.expect
|
||||
--source include/start_mysqld.inc
|
||||
# Expect domain id 200
|
||||
show variables like 'wsrep_gtid_domain_id';
|
||||
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
--connection node_1
|
||||
set global wsrep_gtid_domain_id=100;
|
||||
|
||||
--connection node_2
|
||||
set global wsrep_gtid_domain_id=100;
|
||||
CALL mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node.");
|
||||
|
||||
--connection node_3
|
||||
set global wsrep_gtid_domain_id=100;
|
||||
CALL mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node.");
|
|
@ -8,6 +8,8 @@ CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 BLOB) ENGINE=InnoDB;
|
|||
|
||||
# Introduce inconsistency
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'
|
||||
--source include/wait_condition.inc
|
||||
SET SESSION wsrep_on=OFF;
|
||||
--eval INSERT INTO t1 VALUES ($inconsistent_fragment, 'X')
|
||||
SET SESSION wsrep_on=ON;
|
||||
|
|
|
@ -944,6 +944,8 @@ DROP TABLE t1;
|
|||
#
|
||||
# TODO: enable them after MDEV-16417 is finished
|
||||
create or replace table t1 (a int primary key) engine=innodb;
|
||||
create or replace table t2 (a int, constraint foo check(a > 0), foreign key(a) references t1(a) on update cascade) engine=innodb;
|
||||
ERROR HY000: Function or expression 'a' cannot be used in the CHECK clause of `foo`
|
||||
create or replace table t2 (a int, check(a > 0), foreign key(a) references t1(a) on update cascade) engine=innodb;
|
||||
ERROR HY000: Function or expression 'a' cannot be used in the CHECK clause of `CONSTRAINT_1`
|
||||
create or replace table t1 (f1 int, f2 date, f3 date, key(f1,f3,f2)) engine=innodb;
|
||||
|
|
|
@ -970,6 +970,8 @@ DROP TABLE t1;
|
|||
--echo # TODO: enable them after MDEV-16417 is finished
|
||||
create or replace table t1 (a int primary key) engine=innodb;
|
||||
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||
create or replace table t2 (a int, constraint foo check(a > 0), foreign key(a) references t1(a) on update cascade) engine=innodb;
|
||||
--error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED
|
||||
create or replace table t2 (a int, check(a > 0), foreign key(a) references t1(a) on update cascade) engine=innodb;
|
||||
|
||||
create or replace table t1 (f1 int, f2 date, f3 date, key(f1,f3,f2)) engine=innodb;
|
||||
|
|
|
@ -558,7 +558,6 @@ static inline const char *vcol_type_name(enum_vcol_info_type type)
|
|||
#define VCOL_AUTO_INC 16
|
||||
#define VCOL_IMPOSSIBLE 32
|
||||
#define VCOL_NEXTVAL 64 /* NEXTVAL is not implemented for vcols */
|
||||
#define VCOL_CHECK_CONSTRAINT_IF_NOT_EXISTS 128
|
||||
|
||||
#define VCOL_NOT_STRICTLY_DETERMINISTIC \
|
||||
(VCOL_NON_DETERMINISTIC | VCOL_TIME_FUNC | VCOL_SESSION_FUNC)
|
||||
|
@ -590,6 +589,7 @@ public:
|
|||
bool stored_in_db;
|
||||
bool utf8; /* Already in utf8 */
|
||||
bool automatic_name;
|
||||
bool if_not_exists;
|
||||
Item *expr;
|
||||
Lex_ident name; /* Name of constraint */
|
||||
/* see VCOL_* (VCOL_FIELD_REF, ...) */
|
||||
|
|
|
@ -357,9 +357,9 @@ enum chf_create_flags {
|
|||
Rowid's are not comparable. This is set if the rowid is unique to the
|
||||
current open handler, like it is with federated where the rowid is a
|
||||
pointer to a local result set buffer. The effect of having this set is
|
||||
that the optimizer will not consirer the following optimizations for
|
||||
that the optimizer will not consider the following optimizations for
|
||||
the table:
|
||||
ror scans or filtering
|
||||
ror scans, filtering or duplicate weedout
|
||||
*/
|
||||
#define HA_NON_COMPARABLE_ROWID (1ULL << 60)
|
||||
|
||||
|
|
|
@ -3476,7 +3476,7 @@ bool Item_field::is_null_result()
|
|||
|
||||
bool Item_field::eq(const Item *item, bool binary_cmp) const
|
||||
{
|
||||
Item *real_item2= ((Item *) item)->real_item();
|
||||
const Item *real_item2= item->real_item();
|
||||
if (real_item2->type() != FIELD_ITEM)
|
||||
return 0;
|
||||
|
||||
|
|
|
@ -2103,6 +2103,7 @@ public:
|
|||
virtual Item *copy_or_same(THD *thd) { return this; }
|
||||
virtual Item *copy_andor_structure(THD *thd) { return this; }
|
||||
virtual Item *real_item() { return this; }
|
||||
const Item *real_item() const { return const_cast<Item*>(this)->real_item(); }
|
||||
virtual Item *get_tmp_table_item(THD *thd) { return copy_or_same(thd); }
|
||||
virtual Item *make_odbc_literal(THD *thd, const LEX_CSTRING *typestr)
|
||||
{
|
||||
|
@ -5593,7 +5594,7 @@ public:
|
|||
{ return ref ? (*ref)->type() : REF_ITEM; }
|
||||
bool eq(const Item *item, bool binary_cmp) const override
|
||||
{
|
||||
Item *it= ((Item *) item)->real_item();
|
||||
const Item *it= item->real_item();
|
||||
return ref && (*ref)->eq(it, binary_cmp);
|
||||
}
|
||||
void save_val(Field *to) override;
|
||||
|
@ -5949,7 +5950,7 @@ public:
|
|||
{ orig_item->make_send_field(thd, field); }
|
||||
bool eq(const Item *item, bool binary_cmp) const override
|
||||
{
|
||||
Item *it= const_cast<Item*>(item)->real_item();
|
||||
const Item *it= item->real_item();
|
||||
return orig_item->eq(it, binary_cmp);
|
||||
}
|
||||
void fix_after_pullout(st_select_lex *new_parent, Item **refptr, bool merge)
|
||||
|
@ -7830,7 +7831,7 @@ public:
|
|||
{ m_item->make_send_field(thd, field); }
|
||||
bool eq(const Item *item, bool binary_cmp) const
|
||||
{
|
||||
Item *it= ((Item *) item)->real_item();
|
||||
const Item *it= item->real_item();
|
||||
return m_item->eq(it, binary_cmp);
|
||||
}
|
||||
void fix_after_pullout(st_select_lex *new_parent, Item **refptr, bool merge)
|
||||
|
|
|
@ -1064,7 +1064,7 @@ String *Item_func_json_extract::read_json(String *str,
|
|||
if (!possible_multiple_values)
|
||||
{
|
||||
/* Loop to the end of the JSON just to make sure it's valid. */
|
||||
while (json_get_path_next(&je, &p) == 0) {}
|
||||
while (json_scan_next(&je) == 0) {}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1688,7 +1688,7 @@ bool is_json_type(const Item *item)
|
|||
if (Type_handler_json_common::is_json_type_handler(item->type_handler()))
|
||||
return true;
|
||||
const Item_func_conv_charset *func;
|
||||
if (!(func= dynamic_cast<const Item_func_conv_charset*>(item)))
|
||||
if (!(func= dynamic_cast<const Item_func_conv_charset*>(item->real_item())))
|
||||
return false;
|
||||
item= func->arguments()[0];
|
||||
}
|
||||
|
|
|
@ -664,6 +664,17 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
/* Check if any table is not supporting comparable rowids */
|
||||
{
|
||||
List_iterator_fast<TABLE_LIST> li(select_lex->outer_select()->leaf_tables);
|
||||
TABLE_LIST *tbl;
|
||||
while ((tbl = li++))
|
||||
{
|
||||
TABLE *table= tbl->table;
|
||||
if (table && table->file->ha_table_flags() & HA_NON_COMPARABLE_ROWID)
|
||||
join->not_usable_rowid_map|= table->map;
|
||||
}
|
||||
}
|
||||
|
||||
DBUG_PRINT("info", ("Checking if subq can be converted to semi-join"));
|
||||
/*
|
||||
|
@ -683,8 +694,11 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||
9. Parent select is not a table-less select
|
||||
10. Neither parent nor child select have STRAIGHT_JOIN option.
|
||||
11. It is first optimisation (the subquery could be moved from ON
|
||||
clause during first optimisation and then be considered for SJ
|
||||
on the second when it is too late)
|
||||
clause during first optimisation and then be considered for SJ
|
||||
on the second when it is too late)
|
||||
12. All tables supports comparable rowids.
|
||||
This is needed for DuplicateWeedout strategy to work (which
|
||||
is the catch-all semi-join strategy so it must be applicable).
|
||||
*/
|
||||
if (optimizer_flag(thd, OPTIMIZER_SWITCH_SEMIJOIN) &&
|
||||
in_subs && // 1
|
||||
|
@ -699,7 +713,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
|
|||
!((join->select_options | // 10
|
||||
select_lex->outer_select()->join->select_options) // 10
|
||||
& SELECT_STRAIGHT_JOIN) && // 10
|
||||
select_lex->first_cond_optimization) // 11
|
||||
select_lex->first_cond_optimization && // 11
|
||||
join->not_usable_rowid_map == 0) // 12
|
||||
{
|
||||
DBUG_PRINT("info", ("Subquery is semi-join conversion candidate"));
|
||||
|
||||
|
@ -3556,6 +3571,9 @@ bool Duplicate_weedout_picker::check_qep(JOIN *join,
|
|||
}
|
||||
else
|
||||
{
|
||||
/* Ensure that table supports comparable rowids */
|
||||
DBUG_ASSERT(!(p->table->table->file->ha_table_flags() & HA_NON_COMPARABLE_ROWID));
|
||||
|
||||
sj_outer_fanout= COST_MULT(sj_outer_fanout, p->records_read);
|
||||
temptable_rec_size += p->table->table->file->ref_length;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright 2018 Codership Oy <info@codership.com>
|
||||
/* Copyright 2018-2023 Codership Oy <info@codership.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -253,7 +253,9 @@ extern "C" my_bool wsrep_thd_skip_locking(const THD *thd)
|
|||
|
||||
extern "C" my_bool wsrep_thd_order_before(const THD *left, const THD *right)
|
||||
{
|
||||
if (wsrep_thd_trx_seqno(left) < wsrep_thd_trx_seqno(right)) {
|
||||
if (wsrep_thd_is_BF(left, false) &&
|
||||
wsrep_thd_is_BF(right, false) &&
|
||||
wsrep_thd_trx_seqno(left) < wsrep_thd_trx_seqno(right)) {
|
||||
WSREP_DEBUG("BF conflict, order: %lld %lld\n",
|
||||
(long long)wsrep_thd_trx_seqno(left),
|
||||
(long long)wsrep_thd_trx_seqno(right));
|
||||
|
@ -368,13 +370,20 @@ extern "C" ulong wsrep_OSU_method_get(const MYSQL_THD thd)
|
|||
|
||||
extern "C" bool wsrep_thd_set_wsrep_aborter(THD *bf_thd, THD *victim_thd)
|
||||
{
|
||||
WSREP_DEBUG("wsrep_thd_set_wsrep_aborter called");
|
||||
mysql_mutex_assert_owner(&victim_thd->LOCK_thd_data);
|
||||
if (!bf_thd)
|
||||
{
|
||||
victim_thd->wsrep_aborter= 0;
|
||||
WSREP_DEBUG("wsrep_thd_set_wsrep_aborter resetting wsrep_aborter");
|
||||
return false;
|
||||
}
|
||||
if (victim_thd->wsrep_aborter && victim_thd->wsrep_aborter != bf_thd->thread_id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
victim_thd->wsrep_aborter = bf_thd->thread_id;
|
||||
victim_thd->wsrep_aborter= bf_thd->thread_id;
|
||||
WSREP_DEBUG("wsrep_thd_set_wsrep_aborter setting wsrep_aborter %u",
|
||||
victim_thd->wsrep_aborter);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -5448,8 +5448,8 @@ thd_need_ordering_with(const MYSQL_THD thd, const MYSQL_THD other_thd)
|
|||
the caller should guarantee that the BF state won't change.
|
||||
(e.g. InnoDB does it by keeping lock_sys.mutex locked)
|
||||
*/
|
||||
if (WSREP_ON && wsrep_thd_is_BF(thd, false) &&
|
||||
wsrep_thd_is_BF(other_thd, false))
|
||||
if (WSREP_ON &&
|
||||
wsrep_thd_order_before(thd, other_thd))
|
||||
return 0;
|
||||
#endif /* WITH_WSREP */
|
||||
rgi= thd->rgi_slave;
|
||||
|
|
|
@ -4397,7 +4397,7 @@ public:
|
|||
bool if_not_exists)
|
||||
{
|
||||
constr->name= name;
|
||||
constr->flags= if_not_exists ? VCOL_CHECK_CONSTRAINT_IF_NOT_EXISTS : 0;
|
||||
constr->if_not_exists= if_not_exists;
|
||||
alter_info.check_constraint_list.push_back(constr);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -409,7 +409,7 @@ void JOIN::init(THD *thd_arg, List<Item> &fields_arg,
|
|||
table_count= 0;
|
||||
top_join_tab_count= 0;
|
||||
const_tables= 0;
|
||||
const_table_map= found_const_table_map= 0;
|
||||
const_table_map= found_const_table_map= not_usable_rowid_map= 0;
|
||||
aggr_tables= 0;
|
||||
eliminated_tables= 0;
|
||||
join_list= 0;
|
||||
|
@ -2476,7 +2476,7 @@ JOIN::optimize_inner()
|
|||
/*
|
||||
We have to remove constants and duplicates from group_list before
|
||||
calling make_join_statistics() as this may call get_best_group_min_max()
|
||||
which needs a simplfied group_list.
|
||||
which needs a simplified group_list.
|
||||
*/
|
||||
if (group_list && table_count == 1)
|
||||
{
|
||||
|
@ -5863,7 +5863,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
|
|||
caller to abort with a zero row result.
|
||||
*/
|
||||
TABLE_LIST *emb= s->table->pos_in_table_list->embedding;
|
||||
if (emb && !emb->sj_on_expr)
|
||||
if (emb && !emb->sj_on_expr && !*s->on_expr_ref)
|
||||
{
|
||||
/* Mark all tables in a multi-table join nest as const */
|
||||
mark_join_nest_as_const(join, emb, &found_const_table_map,
|
||||
|
|
|
@ -1254,6 +1254,8 @@ public:
|
|||
table_map outer_join;
|
||||
/* Bitmap of tables used in the select list items */
|
||||
table_map select_list_used_tables;
|
||||
/* Tables that has HA_NON_COMPARABLE_ROWID (does not support rowid) set */
|
||||
table_map not_usable_rowid_map;
|
||||
ha_rows send_records,found_records,join_examined_rows, accepted_rows;
|
||||
|
||||
/*
|
||||
|
|
|
@ -3741,7 +3741,7 @@ without_overlaps_err:
|
|||
my_error(ER_TOO_LONG_IDENT, MYF(0), check->name.str);
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (check_expression(check, &check->name, VCOL_CHECK_TABLE))
|
||||
if (check_expression(check, &check->name, VCOL_CHECK_TABLE, alter_info))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -6186,10 +6186,8 @@ remove_key:
|
|||
|
||||
while ((check=it++))
|
||||
{
|
||||
if (!(check->flags & VCOL_CHECK_CONSTRAINT_IF_NOT_EXISTS) &&
|
||||
check->name.length)
|
||||
if (!check->if_not_exists && check->name.length)
|
||||
continue;
|
||||
check->flags= 0;
|
||||
for (c= share->field_check_constraints;
|
||||
c < share->table_check_constraints ; c++)
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright 2018-2021 Codership Oy <info@codership.com>
|
||||
/* Copyright 2018-2023 Codership Oy <info@codership.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -639,6 +639,9 @@ Wsrep_replayer_service::Wsrep_replayer_service(THD* replayer_thd, THD* orig_thd)
|
|||
transactional locks */
|
||||
DBUG_ASSERT(!orig_thd->mdl_context.has_transactional_locks());
|
||||
|
||||
replayer_thd->system_thread_info.rpl_sql_info=
|
||||
new rpl_sql_thread_info(replayer_thd->wsrep_rgi->rli->mi->rpl_filter);
|
||||
|
||||
/* Make a shadow copy of diagnostics area and reset */
|
||||
m_da_shadow.status= orig_thd->get_stmt_da()->status();
|
||||
if (m_da_shadow.status == Diagnostics_area::DA_OK)
|
||||
|
@ -677,35 +680,35 @@ Wsrep_replayer_service::Wsrep_replayer_service(THD* replayer_thd, THD* orig_thd)
|
|||
|
||||
Wsrep_replayer_service::~Wsrep_replayer_service()
|
||||
{
|
||||
THD* replayer_thd= m_thd;
|
||||
THD* orig_thd= m_orig_thd;
|
||||
|
||||
/* Switch execution context back to original. */
|
||||
wsrep_after_apply(replayer_thd);
|
||||
wsrep_after_command_ignore_result(replayer_thd);
|
||||
wsrep_close(replayer_thd);
|
||||
wsrep_reset_threadvars(replayer_thd);
|
||||
wsrep_store_threadvars(orig_thd);
|
||||
wsrep_after_apply(m_thd);
|
||||
wsrep_after_command_ignore_result(m_thd);
|
||||
wsrep_close(m_thd);
|
||||
wsrep_reset_threadvars(m_thd);
|
||||
wsrep_store_threadvars(m_orig_thd);
|
||||
|
||||
DBUG_ASSERT(!orig_thd->get_stmt_da()->is_sent());
|
||||
DBUG_ASSERT(!orig_thd->get_stmt_da()->is_set());
|
||||
DBUG_ASSERT(!m_orig_thd->get_stmt_da()->is_sent());
|
||||
DBUG_ASSERT(!m_orig_thd->get_stmt_da()->is_set());
|
||||
|
||||
delete m_thd->system_thread_info.rpl_sql_info;
|
||||
m_thd->system_thread_info.rpl_sql_info= nullptr;
|
||||
|
||||
if (m_replay_status == wsrep::provider::success)
|
||||
{
|
||||
DBUG_ASSERT(replayer_thd->wsrep_cs().current_error() == wsrep::e_success);
|
||||
orig_thd->reset_kill_query();
|
||||
my_ok(orig_thd, m_da_shadow.affected_rows, m_da_shadow.last_insert_id);
|
||||
DBUG_ASSERT(m_thd->wsrep_cs().current_error() == wsrep::e_success);
|
||||
m_orig_thd->reset_kill_query();
|
||||
my_ok(m_orig_thd, m_da_shadow.affected_rows, m_da_shadow.last_insert_id);
|
||||
}
|
||||
else if (m_replay_status == wsrep::provider::error_certification_failed)
|
||||
{
|
||||
wsrep_override_error(orig_thd, ER_LOCK_DEADLOCK);
|
||||
wsrep_override_error(m_orig_thd, ER_LOCK_DEADLOCK);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBUG_ASSERT(0);
|
||||
WSREP_ERROR("trx_replay failed for: %d, schema: %s, query: %s",
|
||||
m_replay_status,
|
||||
orig_thd->db.str, wsrep_thd_query(orig_thd));
|
||||
m_orig_thd->db.str, wsrep_thd_query(m_orig_thd));
|
||||
unireg_abort(1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -362,10 +362,12 @@ static void wsrep_log_cb(wsrep::log::level level,
|
|||
void wsrep_init_gtid()
|
||||
{
|
||||
wsrep_server_gtid_t stored_gtid= wsrep_get_SE_checkpoint<wsrep_server_gtid_t>();
|
||||
// Domain id may have changed, use the one
|
||||
// received during state transfer.
|
||||
stored_gtid.domain_id= wsrep_gtid_server.domain_id;
|
||||
if (stored_gtid.server_id == 0)
|
||||
{
|
||||
rpl_gtid wsrep_last_gtid;
|
||||
stored_gtid.domain_id= wsrep_gtid_server.domain_id;
|
||||
if (mysql_bin_log.is_open() &&
|
||||
mysql_bin_log.lookup_domain_in_binlog_state(stored_gtid.domain_id,
|
||||
&wsrep_last_gtid))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2013-2022 Codership Oy <info@codership.com>
|
||||
/* Copyright (C) 2013-2023 Codership Oy <info@codership.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -308,32 +308,37 @@ void wsrep_fire_rollbacker(THD *thd)
|
|||
}
|
||||
|
||||
|
||||
int wsrep_abort_thd(THD *bf_thd_ptr, THD *victim_thd_ptr, my_bool signal)
|
||||
int wsrep_abort_thd(THD *bf_thd,
|
||||
THD *victim_thd,
|
||||
my_bool signal)
|
||||
{
|
||||
DBUG_ENTER("wsrep_abort_thd");
|
||||
THD *victim_thd= (THD *) victim_thd_ptr;
|
||||
THD *bf_thd= (THD *) bf_thd_ptr;
|
||||
|
||||
mysql_mutex_lock(&victim_thd->LOCK_thd_data);
|
||||
|
||||
/* Note that when you use RSU node is desynced from cluster, thus WSREP(thd)
|
||||
might not be true.
|
||||
*/
|
||||
if ((WSREP(bf_thd) ||
|
||||
if ((WSREP_NNULL(bf_thd) ||
|
||||
((WSREP_ON || bf_thd->variables.wsrep_OSU_method == WSREP_OSU_RSU) &&
|
||||
wsrep_thd_is_toi(bf_thd))) &&
|
||||
victim_thd &&
|
||||
!wsrep_thd_is_aborting(victim_thd))
|
||||
{
|
||||
WSREP_DEBUG("wsrep_abort_thd, by: %llu, victim: %llu", (bf_thd) ?
|
||||
(long long)bf_thd->real_id : 0, (long long)victim_thd->real_id);
|
||||
WSREP_DEBUG("wsrep_abort_thd, by: %llu, victim: %llu",
|
||||
(long long)bf_thd->real_id, (long long)victim_thd->real_id);
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
|
||||
ha_abort_transaction(bf_thd, victim_thd, signal);
|
||||
mysql_mutex_lock(&victim_thd->LOCK_thd_data);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
WSREP_DEBUG("wsrep_abort_thd not effective: %p %p", bf_thd, victim_thd);
|
||||
WSREP_DEBUG("wsrep_abort_thd not effective: bf %llu victim %llu "
|
||||
"wsrep %d wsrep_on %d RSU %d TOI %d aborting %d",
|
||||
(long long)bf_thd->real_id, (long long)victim_thd->real_id,
|
||||
WSREP_NNULL(bf_thd), WSREP_ON,
|
||||
bf_thd->variables.wsrep_OSU_method == WSREP_OSU_RSU,
|
||||
wsrep_thd_is_toi(bf_thd),
|
||||
wsrep_thd_is_aborting(victim_thd));
|
||||
}
|
||||
|
||||
mysql_mutex_unlock(&victim_thd->LOCK_thd_data);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (C) 2013-2022 Codership Oy <info@codership.com>
|
||||
/* Copyright (C) 2013-2023 Codership Oy <info@codership.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -88,7 +88,9 @@ bool wsrep_create_appliers(long threads, bool mutex_protected=false);
|
|||
void wsrep_create_rollbacker();
|
||||
|
||||
bool wsrep_bf_abort(THD* bf_thd, THD* victim_thd);
|
||||
int wsrep_abort_thd(THD *bf_thd_ptr, THD *victim_thd_ptr, my_bool signal);
|
||||
int wsrep_abort_thd(THD *bf_thd,
|
||||
THD *victim_thd,
|
||||
my_bool signal) __attribute__((nonnull(1,2)));
|
||||
|
||||
/*
|
||||
Helper methods to deal with thread local storage.
|
||||
|
|
|
@ -18686,7 +18686,15 @@ void lock_wait_wsrep_kill(trx_t *bf_trx, ulong thd_id, trx_id_t trx_id)
|
|||
lock_sys.cancel_lock_wait_for_trx(vtrx);
|
||||
|
||||
DEBUG_SYNC(bf_thd, "before_wsrep_thd_abort");
|
||||
wsrep_thd_bf_abort(bf_thd, vthd, true);
|
||||
if (!wsrep_thd_bf_abort(bf_thd, vthd, true))
|
||||
{
|
||||
wsrep_thd_LOCK(vthd);
|
||||
wsrep_thd_set_wsrep_aborter(NULL, vthd);
|
||||
wsrep_thd_UNLOCK(vthd);
|
||||
|
||||
WSREP_DEBUG("wsrep_thd_bf_abort has failed, victim %lu will survive",
|
||||
thd_get_thread_id(vthd));
|
||||
}
|
||||
}
|
||||
wsrep_thd_kill_UNLOCK(vthd);
|
||||
}
|
||||
|
|
|
@ -693,22 +693,31 @@ lock_rec_has_to_wait(
|
|||
#endif /* HAVE_REPLICATION */
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/* New lock request from a transaction is using unique key
|
||||
scan and this transaction is a wsrep high priority transaction
|
||||
(brute force). If conflicting transaction is also wsrep high
|
||||
priority transaction we should avoid lock conflict because
|
||||
ordering of these transactions is already decided and
|
||||
conflicting transaction will be later replayed. */
|
||||
if (trx->is_wsrep_UK_scan()
|
||||
&& wsrep_thd_is_BF(lock2->trx->mysql_thd, false)) {
|
||||
return false;
|
||||
}
|
||||
/* New lock request from a transaction is using unique key
|
||||
scan and this transaction is a wsrep high priority transaction
|
||||
(brute force). If conflicting transaction is also wsrep high
|
||||
priority transaction we should avoid lock conflict because
|
||||
ordering of these transactions is already decided and
|
||||
conflicting transaction will be later replayed. */
|
||||
if (trx->is_wsrep_UK_scan()
|
||||
&& wsrep_thd_is_BF(lock2->trx->mysql_thd, false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We very well can let bf to wait normally as other
|
||||
BF will be replayed in case of conflict. For debug
|
||||
builds we will do additional sanity checks to catch
|
||||
unsupported bf wait if any. */
|
||||
ut_d(wsrep_assert_no_bf_bf_wait(lock2, trx));
|
||||
/* if BF-BF conflict, we have to look at write set order */
|
||||
if (trx->is_wsrep() &&
|
||||
(type_mode & LOCK_MODE_MASK) == LOCK_X &&
|
||||
(lock2->type_mode & LOCK_MODE_MASK) == LOCK_X &&
|
||||
wsrep_thd_order_before(trx->mysql_thd,
|
||||
lock2->trx->mysql_thd)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* We very well can let bf to wait normally as other
|
||||
BF will be replayed in case of conflict. For debug
|
||||
builds we will do additional sanity checks to catch
|
||||
unsupported bf wait if any. */
|
||||
ut_d(wsrep_assert_no_bf_bf_wait(lock2, trx));
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
return true;
|
||||
|
@ -1600,6 +1609,14 @@ lock_rec_has_to_wait_in_queue(const hash_cell_t &cell, const lock_t *wait_lock)
|
|||
if (heap_no < lock_rec_get_n_bits(lock)
|
||||
&& (p[bit_offset] & bit_mask)
|
||||
&& lock_has_to_wait(wait_lock, lock)) {
|
||||
#ifdef WITH_WSREP
|
||||
if (lock->trx->is_wsrep() &&
|
||||
wsrep_thd_order_before(wait_lock->trx->mysql_thd,
|
||||
lock->trx->mysql_thd)) {
|
||||
/* don't wait for another BF lock */
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
return(lock);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue