mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
Merge 11.4 into 11.8
This commit is contained in:
@@ -213,11 +213,8 @@ connection default;
|
||||
use test;
|
||||
drop view testdb_1.v1, v2, testdb_1.v3, v4;
|
||||
drop database testdb_1;
|
||||
connection testdb_1;
|
||||
disconnect testdb_1;
|
||||
connection testdb_2;
|
||||
disconnect testdb_2;
|
||||
connection default;
|
||||
drop user testdb_1@localhost;
|
||||
drop user testdb_2@localhost;
|
||||
#
|
||||
@@ -249,18 +246,18 @@ ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table `
|
||||
connection default;
|
||||
drop user mysqltest_1@localhost;
|
||||
drop database testdb_1;
|
||||
connection user1;
|
||||
disconnect user1;
|
||||
connection default;
|
||||
set global sql_mode=default;
|
||||
#
|
||||
# MDEV-20549 SQL SECURITY DEFINER does not work for INFORMATION_SCHEMA tables
|
||||
#
|
||||
create user foo@localhost;
|
||||
grant select on test.* to foo@localhost;
|
||||
connect foo,localhost,foo;
|
||||
connection default;
|
||||
create procedure rootonly() select 1;
|
||||
create sql security definer view v1d as select current_user(),user from information_schema.processlist where command!='daemon';
|
||||
create sql security invoker view v1i as select current_user(),user from information_schema.processlist where command!='daemon';
|
||||
create sql security definer view v1d as select current_user(),user from information_schema.processlist where id in($default_id, $foo_id) order by user;
|
||||
create sql security invoker view v1i as select current_user(),user from information_schema.processlist where id in($default_id, $foo_id) order by user;
|
||||
create sql security definer view v2d as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%';
|
||||
create sql security invoker view v2i as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%';
|
||||
create sql security definer view v3d as select schema_name from information_schema.schemata where schema_name like '%mysql%';
|
||||
@@ -269,7 +266,7 @@ create sql security definer view v4d as select routine_name from information_sch
|
||||
create sql security invoker view v4i as select routine_name from information_schema.routines where routine_schema='test';
|
||||
create sql security definer view v5d as select view_definition > '' from information_schema.views where table_name='v1d';
|
||||
create sql security invoker view v5i as select view_definition > '' from information_schema.views where table_name='v1d';
|
||||
connect foo,localhost,foo;
|
||||
connection foo;
|
||||
select * from v1d;
|
||||
current_user() user
|
||||
root@localhost root
|
||||
|
||||
@@ -207,13 +207,8 @@ connection default;
|
||||
use test;
|
||||
drop view testdb_1.v1, v2, testdb_1.v3, v4;
|
||||
drop database testdb_1;
|
||||
connection testdb_1;
|
||||
disconnect testdb_1;
|
||||
--source include/wait_until_disconnected.inc
|
||||
connection testdb_2;
|
||||
disconnect testdb_2;
|
||||
--source include/wait_until_disconnected.inc
|
||||
connection default;
|
||||
drop user testdb_1@localhost;
|
||||
drop user testdb_2@localhost;
|
||||
|
||||
@@ -244,10 +239,7 @@ show create view testdb_1.v1;
|
||||
connection default;
|
||||
drop user mysqltest_1@localhost;
|
||||
drop database testdb_1;
|
||||
connection user1;
|
||||
disconnect user1;
|
||||
--source include/wait_until_disconnected.inc
|
||||
connection default;
|
||||
|
||||
set global sql_mode=default;
|
||||
|
||||
@@ -257,9 +249,13 @@ set global sql_mode=default;
|
||||
|
||||
create user foo@localhost;
|
||||
grant select on test.* to foo@localhost;
|
||||
let $default_id= `select connection_id()`;
|
||||
connect foo,localhost,foo;
|
||||
let $foo_id= `select connection_id()`;
|
||||
connection default;
|
||||
create procedure rootonly() select 1;
|
||||
create sql security definer view v1d as select current_user(),user from information_schema.processlist where command!='daemon';
|
||||
create sql security invoker view v1i as select current_user(),user from information_schema.processlist where command!='daemon';
|
||||
evalp create sql security definer view v1d as select current_user(),user from information_schema.processlist where id in($default_id, $foo_id) order by user;
|
||||
evalp create sql security invoker view v1i as select current_user(),user from information_schema.processlist where id in($default_id, $foo_id) order by user;
|
||||
create sql security definer view v2d as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%';
|
||||
create sql security invoker view v2i as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%';
|
||||
create sql security definer view v3d as select schema_name from information_schema.schemata where schema_name like '%mysql%';
|
||||
@@ -268,7 +264,7 @@ create sql security definer view v4d as select routine_name from information_sch
|
||||
create sql security invoker view v4i as select routine_name from information_schema.routines where routine_schema='test';
|
||||
create sql security definer view v5d as select view_definition > '' from information_schema.views where table_name='v1d';
|
||||
create sql security invoker view v5i as select view_definition > '' from information_schema.views where table_name='v1d';
|
||||
connect foo,localhost,foo;
|
||||
connection foo;
|
||||
select * from v1d;
|
||||
select * from v1i;
|
||||
select * from v2d;
|
||||
|
||||
@@ -932,3 +932,14 @@ Warnings:
|
||||
Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 100. The query result may be incomplete
|
||||
DROP TABLE t1, t2;
|
||||
# End of 10.5 tests
|
||||
#
|
||||
# MDEV-22241: Assertion `0' failed in Protocol::end_statement after query with LIMIT ROWS EXAMINED
|
||||
#
|
||||
CREATE TABLE t1 (a int);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
SELECT 1 FROM t1
|
||||
WHERE (1 IN (SELECT 8 UNION SELECT 5)) OR t1.a = 2
|
||||
LIMIT ROWS EXAMINED 1;
|
||||
1
|
||||
DROP TABLE t1;
|
||||
# End of 10.11 tests
|
||||
|
||||
@@ -658,3 +658,18 @@ SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) UNION DISTINCT SELECT COUNT(*) FROM t
|
||||
DROP TABLE t1, t2;
|
||||
|
||||
--echo # End of 10.5 tests
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-22241: Assertion `0' failed in Protocol::end_statement after query with LIMIT ROWS EXAMINED
|
||||
--echo #
|
||||
|
||||
CREATE TABLE t1 (a int);
|
||||
INSERT INTO t1 VALUES (1);
|
||||
|
||||
SELECT 1 FROM t1
|
||||
WHERE (1 IN (SELECT 8 UNION SELECT 5)) OR t1.a = 2
|
||||
LIMIT ROWS EXAMINED 1;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
--echo # End of 10.11 tests
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
SET GLOBAL innodb_encrypt_tables=ON,innodb_encryption_threads=1;
|
||||
SET GLOBAL innodb_saved_page_number_debug=4,innodb_fil_make_page_dirty_debug=0;
|
||||
CREATE TABLE t1(f1 text, index idx(f1(20))) ENGINE INNODB;
|
||||
set global innodb_fast_shutdown=0;
|
||||
# restart: --debug_dbug=+d,ib_log_checkpoint_avoid_hard --innodb_flush_sync=0
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
[full_crc32]
|
||||
--innodb-checksum-algorithm=full_crc32
|
||||
[crc32]
|
||||
--innodb-checksum-algorithm=crc32
|
||||
@@ -5,6 +5,9 @@
|
||||
|
||||
let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
|
||||
let MYSQLD_DATADIR=`select @@datadir`;
|
||||
# Encrypt the change buffer root page
|
||||
SET GLOBAL innodb_encrypt_tables=ON,innodb_encryption_threads=1;
|
||||
SET GLOBAL innodb_saved_page_number_debug=4,innodb_fil_make_page_dirty_debug=0;
|
||||
|
||||
CREATE TABLE t1(f1 text, index idx(f1(20))) ENGINE INNODB;
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
|
||||
galera_wan : MDEV-35940 Unallowed state transition: donor -> synced in galera_wan
|
||||
galera_vote_rejoin_ddl : MDEV-35940 Unallowed state transition: donor -> synced in galera_wan
|
||||
MW-329 : MDEV-35951 Complete freeze during MW-329 test
|
||||
galera_vote_rejoin_dml : MDEV-35964 Assertion `ist_seqno >= cc_seqno' failed in galera_vote_rejoin_dml
|
||||
galera_var_notify_cmd : MDEV-37257 WSREP: Notification command failed: 1 (Operation not permitted)
|
||||
galera_var_notify_ssl_ipv6 : MDEV-37257 WSREP: Notification command failed: 1 (Operation not permitted)
|
||||
|
||||
@@ -14,10 +14,11 @@ END|
|
||||
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connection node_1b;
|
||||
connection node_1;
|
||||
connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||
connection node_1c;
|
||||
connection node_1b;
|
||||
connection node_1;
|
||||
DROP PROCEDURE proc_insert;
|
||||
DROP TABLE t1;
|
||||
disconnect node_1b;
|
||||
CALL mtr.add_suppression("WSREP: .* conflict state after post commit ");
|
||||
set global innodb_status_output=Default;
|
||||
disconnect node_1c;
|
||||
|
||||
@@ -0,0 +1,364 @@
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
#
|
||||
# 1. BF-BF conflict on MDL locks between: DROP TABLE t4 and INSERT t1
|
||||
# with foreign key references as below:
|
||||
# - t1<-t2<-t3<-t4
|
||||
#
|
||||
connection node_2;
|
||||
SET GLOBAL wsrep_slave_threads=2;
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY,
|
||||
f2 INTEGER
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
id INT PRIMARY KEY,
|
||||
t1_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t1_id(t1_id),
|
||||
CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE t3 (
|
||||
id INT PRIMARY KEY,
|
||||
t2_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t2_id(t2_id),
|
||||
CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE t4 (
|
||||
id INT PRIMARY KEY,
|
||||
t3_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t3_id(t3_id),
|
||||
CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t1 VALUES (2,0);
|
||||
INSERT INTO t2 VALUES (1,1,1234);
|
||||
INSERT INTO t2 VALUES (2,2,1234);
|
||||
INSERT INTO t3 VALUES (1,1,1234);
|
||||
INSERT INTO t3 VALUES (2,2,1234);
|
||||
INSERT INTO t4 VALUES (1,1,1234);
|
||||
INSERT INTO t4 VALUES (2,2,1234);
|
||||
connection node_2;
|
||||
SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi';
|
||||
connection node_1;
|
||||
DROP TABLE t4;
|
||||
connection node_2;
|
||||
SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached";
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
connection node_1;
|
||||
SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table';
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES (3,0);
|
||||
COMMIT;
|
||||
connection node_2;
|
||||
SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi';
|
||||
SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi";
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET GLOBAL wsrep_slave_threads=DEFAULT;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET GLOBAL wsrep_slave_threads=DEFAULT;
|
||||
connection node_1;
|
||||
include/assert_grep.inc [Foreign key referenced table found: 2 tables]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t2]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t3]
|
||||
connection node_2;
|
||||
select * from t1;
|
||||
id f2
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
select * from t2;
|
||||
id t1_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
select * from t3;
|
||||
id t2_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
select * from t4;
|
||||
ERROR 42S02: Table 'test.t4' doesn't exist
|
||||
connection node_1;
|
||||
select * from t1;
|
||||
id f2
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
select * from t2;
|
||||
id t1_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
select * from t3;
|
||||
id t2_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
select * from t4;
|
||||
ERROR 42S02: Table 'test.t4' doesn't exist
|
||||
DROP TABLE t3, t2, t1;
|
||||
#
|
||||
# 2. BF-BF conflict on MDL locks between:
|
||||
# ALTER TABLE t4 (whose parent table are t4 -> t3 -> t2 -> t1), and
|
||||
# INSERT on t1.
|
||||
#
|
||||
connection node_2;
|
||||
SET GLOBAL wsrep_slave_threads=2;
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY,
|
||||
f2 INTEGER
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
id INT PRIMARY KEY,
|
||||
t1_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t1_id(t1_id),
|
||||
CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE t3 (
|
||||
id INT PRIMARY KEY,
|
||||
t2_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t2_id(t2_id),
|
||||
CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE t4 (
|
||||
id INT PRIMARY KEY,
|
||||
t3_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t3_id(t3_id)
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t1 VALUES (2,0);
|
||||
INSERT INTO t2 VALUES (1,1,1234);
|
||||
INSERT INTO t2 VALUES (2,2,1234);
|
||||
INSERT INTO t3 VALUES (1,1,1234);
|
||||
INSERT INTO t3 VALUES (2,2,1234);
|
||||
INSERT INTO t4 VALUES (1,1,1234);
|
||||
INSERT INTO t4 VALUES (2,2,1234);
|
||||
connection node_2;
|
||||
SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi';
|
||||
connection node_1;
|
||||
ALTER TABLE t4 ADD CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||
connection node_2;
|
||||
SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached";
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
connection node_1;
|
||||
SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table';
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES (3,0);
|
||||
COMMIT;
|
||||
connection node_2;
|
||||
SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi';
|
||||
SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi";
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET GLOBAL wsrep_slave_threads=DEFAULT;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET GLOBAL wsrep_slave_threads=DEFAULT;
|
||||
connection node_1;
|
||||
include/assert_grep.inc [Foreign key referenced table found: 3 tables]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t2]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t3]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t4]
|
||||
connection node_2;
|
||||
select * from t1;
|
||||
id f2
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
select * from t2;
|
||||
id t1_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
select * from t3;
|
||||
id t2_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
connection node_1;
|
||||
select * from t1;
|
||||
id f2
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
select * from t2;
|
||||
id t1_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
select * from t3;
|
||||
id t2_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
DROP TABLE t4, t3, t2, t1;
|
||||
#
|
||||
# 3. BF-BF conflict on MDL locks between:
|
||||
# CREATE TABLE t3 (whose parent table are t4 -> t3 -> t2 -> t1), and
|
||||
# INSERT on t1.
|
||||
#
|
||||
connection node_2;
|
||||
SET GLOBAL wsrep_slave_threads=2;
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY,
|
||||
f2 INTEGER
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
id INT PRIMARY KEY,
|
||||
t1_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t1_id(t1_id),
|
||||
CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE t3 (
|
||||
id INT PRIMARY KEY,
|
||||
t2_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t2_id(t2_id),
|
||||
CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t1 VALUES (2,0);
|
||||
INSERT INTO t2 VALUES (1,1,1234);
|
||||
INSERT INTO t2 VALUES (2,2,1234);
|
||||
INSERT INTO t3 VALUES (1,1,1234);
|
||||
INSERT INTO t3 VALUES (2,2,1234);
|
||||
connection node_2;
|
||||
SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi';
|
||||
connection node_1;
|
||||
CREATE TABLE t4 (id INT PRIMARY KEY, t3_id INT NOT NULL, f2 INTEGER NOT NULL, KEY key_t3_id(t3_id), CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE);
|
||||
connection node_2;
|
||||
SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached";
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
connection node_1;
|
||||
SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table';
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES (3,0);
|
||||
COMMIT;
|
||||
connection node_2;
|
||||
SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi';
|
||||
SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi";
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET GLOBAL wsrep_slave_threads=DEFAULT;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET GLOBAL wsrep_slave_threads=DEFAULT;
|
||||
connection node_1;
|
||||
include/assert_grep.inc [Foreign key referenced table found: 2 tables]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t2]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t3]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t4]
|
||||
connection node_2;
|
||||
select * from t1;
|
||||
id f2
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
select * from t2;
|
||||
id t1_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
select * from t3;
|
||||
id t2_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
connection node_1;
|
||||
select * from t1;
|
||||
id f2
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
select * from t2;
|
||||
id t1_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
select * from t3;
|
||||
id t2_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
DROP TABLE t4, t3, t2, t1;
|
||||
#
|
||||
# 4. BF-BF conflict on MDL locks between:
|
||||
# OPTIMIZE TABLE t2 (whose parent table are t2 -> t1), and
|
||||
# INSERT t1.
|
||||
#
|
||||
connection node_2;
|
||||
SET GLOBAL wsrep_slave_threads=2;
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY,
|
||||
f2 INTEGER
|
||||
);
|
||||
CREATE TABLE t2 (
|
||||
id INT PRIMARY KEY,
|
||||
t1_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t1_id(t1_id),
|
||||
CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
CREATE TABLE t3 (
|
||||
id INT PRIMARY KEY,
|
||||
t2_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t2_id(t2_id),
|
||||
CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t1 VALUES (2,0);
|
||||
INSERT INTO t2 VALUES (1,1,1234);
|
||||
INSERT INTO t2 VALUES (2,2,1234);
|
||||
INSERT INTO t3 VALUES (1,1,1234);
|
||||
INSERT INTO t3 VALUES (2,2,1234);
|
||||
connection node_2;
|
||||
SET GLOBAL DEBUG_DBUG = '+d,sync.wsrep_apply_toi';
|
||||
connection node_1;
|
||||
OPTIMIZE TABLE t3;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t3 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t3 optimize status OK
|
||||
connection node_2;
|
||||
SET DEBUG_SYNC = "now WAIT_FOR sync.wsrep_apply_toi_reached";
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
connection node_1;
|
||||
SET GLOBAL DEBUG_DBUG = '+d,wsrep_print_foreign_keys_table';
|
||||
START TRANSACTION;
|
||||
INSERT INTO t1 VALUES (3,0);
|
||||
COMMIT;
|
||||
connection node_2;
|
||||
SET GLOBAL DEBUG_DBUG = '-d,sync.wsrep_apply_toi';
|
||||
SET DEBUG_SYNC = "now SIGNAL signal.wsrep_apply_toi";
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET GLOBAL wsrep_slave_threads=DEFAULT;
|
||||
connection node_1;
|
||||
SET DEBUG_SYNC = 'RESET';
|
||||
SET GLOBAL DEBUG_DBUG = "";
|
||||
SET GLOBAL wsrep_slave_threads=DEFAULT;
|
||||
connection node_1;
|
||||
include/assert_grep.inc [Foreign key referenced table found: 1 tables]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t2]
|
||||
include/assert_grep.inc [Foreign key referenced table found: test.t3]
|
||||
connection node_2;
|
||||
select * from t1;
|
||||
id f2
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
select * from t2;
|
||||
id t1_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
connection node_1;
|
||||
select * from t1;
|
||||
id f2
|
||||
1 0
|
||||
2 0
|
||||
3 0
|
||||
select * from t2;
|
||||
id t1_id f2
|
||||
1 1 1234
|
||||
2 2 1234
|
||||
DROP TABLE t3, t2, t1;
|
||||
@@ -83,7 +83,19 @@ while ($count)
|
||||
|
||||
--connection node_1
|
||||
--disable_query_log
|
||||
--eval KILL CONNECTION $connection_id
|
||||
--eval KILL HARD CONNECTION $connection_id
|
||||
--enable_query_log
|
||||
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||
--connection node_1c
|
||||
|
||||
--disable_query_log
|
||||
# Make sure connection is killed
|
||||
while (`SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.PROCESSLIST WHERE ID = $connection_id`)
|
||||
{
|
||||
SELECT SLEEP(1);
|
||||
--error 0,ER_NO_SUCH_THREAD,ER_QUERY_INTERRUPTED,ER_CONNECTION_KILLED
|
||||
--eval KILL HARD CONNECTION $connection_id
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
#
|
||||
@@ -101,8 +113,4 @@ DROP PROCEDURE proc_insert;
|
||||
DROP TABLE t1;
|
||||
|
||||
--disconnect node_1b
|
||||
|
||||
# Due to MW-330, Multiple "conflict state 3 after post commit" warnings if table is dropped while SP is running
|
||||
CALL mtr.add_suppression("WSREP: .* conflict state after post commit ");
|
||||
|
||||
set global innodb_status_output=Default;
|
||||
--disconnect node_1c
|
||||
|
||||
454
mysql-test/suite/galera/t/galera_multi_level_fk_ddl_insert.test
Normal file
454
mysql-test/suite/galera/t/galera_multi_level_fk_ddl_insert.test
Normal file
@@ -0,0 +1,454 @@
|
||||
#
|
||||
# BF-BF conflict on MDL locks between DDL and insert query
|
||||
# when multi-level foreign key like t3 -> t2 -> t1
|
||||
# are present.
|
||||
#
|
||||
# If bug is present, expect the wait condition
|
||||
# to timeout and when the INSERT applies, it
|
||||
# will be granted a MDL lock of type SHARED_READ
|
||||
# for table t1. When resumed, the DROP/ALTER/CREATE/OPTIMIZE
|
||||
# TABLE will also try to MDL lock t1, causing a BF-BF conflict
|
||||
# on that MDL lock.
|
||||
|
||||
--source include/galera_cluster.inc
|
||||
--source include/have_innodb.inc
|
||||
--source include/have_debug.inc
|
||||
--source include/have_debug_sync.inc
|
||||
|
||||
--echo #
|
||||
--echo # 1. BF-BF conflict on MDL locks between: DROP TABLE t4 and INSERT t1
|
||||
--echo # with foreign key references as below:
|
||||
--echo # - t1<-t2<-t3<-t4
|
||||
--echo #
|
||||
|
||||
#
|
||||
# Setup
|
||||
#
|
||||
--connection node_2
|
||||
SET GLOBAL wsrep_slave_threads=2;
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY,
|
||||
f2 INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
id INT PRIMARY KEY,
|
||||
t1_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t1_id(t1_id),
|
||||
CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE t3 (
|
||||
id INT PRIMARY KEY,
|
||||
t2_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t2_id(t2_id),
|
||||
CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE t4 (
|
||||
id INT PRIMARY KEY,
|
||||
t3_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t3_id(t3_id),
|
||||
CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t1 VALUES (2,0);
|
||||
|
||||
INSERT INTO t2 VALUES (1,1,1234);
|
||||
INSERT INTO t2 VALUES (2,2,1234);
|
||||
|
||||
INSERT INTO t3 VALUES (1,1,1234);
|
||||
INSERT INTO t3 VALUES (2,2,1234);
|
||||
|
||||
INSERT INTO t4 VALUES (1,1,1234);
|
||||
INSERT INTO t4 VALUES (2,2,1234);
|
||||
|
||||
|
||||
--let $fk_parent_query = DROP TABLE t4
|
||||
--let $fk_child_query = INSERT INTO t1 VALUES (3,0)
|
||||
--let $fk_mdl_lock_num = 3
|
||||
--source galera_multi_level_foreign_key.inc
|
||||
|
||||
|
||||
#
|
||||
# Verify Foreign key for referenced table added.
|
||||
#
|
||||
--connection node_1
|
||||
--let assert_text= Foreign key referenced table found: 2 tables
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 2
|
||||
--let assert_select= Foreign key referenced table found:
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t2
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 1
|
||||
--let assert_select= Foreign key referenced table found: test.t2
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t3
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 1
|
||||
--let assert_select= Foreign key referenced table found: test.t3
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
|
||||
#
|
||||
# Verify insert and drop table has succeded.
|
||||
#
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 3 FROM test.t1
|
||||
--source include/wait_condition.inc
|
||||
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
select * from t4;
|
||||
|
||||
--connection node_1
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
--error ER_NO_SUCH_TABLE
|
||||
select * from t4;
|
||||
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
DROP TABLE t3, t2, t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # 2. BF-BF conflict on MDL locks between:
|
||||
--echo # ALTER TABLE t4 (whose parent table are t4 -> t3 -> t2 -> t1), and
|
||||
--echo # INSERT on t1.
|
||||
--echo #
|
||||
|
||||
#
|
||||
# Setup
|
||||
#
|
||||
--connection node_2
|
||||
SET GLOBAL wsrep_slave_threads=2;
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY,
|
||||
f2 INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
id INT PRIMARY KEY,
|
||||
t1_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t1_id(t1_id),
|
||||
CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE t3 (
|
||||
id INT PRIMARY KEY,
|
||||
t2_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t2_id(t2_id),
|
||||
CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE t4 (
|
||||
id INT PRIMARY KEY,
|
||||
t3_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t3_id(t3_id)
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t1 VALUES (2,0);
|
||||
|
||||
INSERT INTO t2 VALUES (1,1,1234);
|
||||
INSERT INTO t2 VALUES (2,2,1234);
|
||||
|
||||
INSERT INTO t3 VALUES (1,1,1234);
|
||||
INSERT INTO t3 VALUES (2,2,1234);
|
||||
|
||||
INSERT INTO t4 VALUES (1,1,1234);
|
||||
INSERT INTO t4 VALUES (2,2,1234);
|
||||
|
||||
|
||||
#
|
||||
# ALTER TABLE t3 and wait for it to reach node_2
|
||||
#
|
||||
--let $fk_parent_query = ALTER TABLE t4 ADD CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
#
|
||||
# Issue a INSERT to table that references t1
|
||||
#
|
||||
--let $fk_child_query = INSERT INTO t1 VALUES (3,0)
|
||||
--let $fk_mdl_lock_num = 4
|
||||
--source galera_multi_level_foreign_key.inc
|
||||
|
||||
|
||||
#
|
||||
# Verify Foreign key for referenced table added.
|
||||
#
|
||||
--connection node_1
|
||||
--let assert_text= Foreign key referenced table found: 3 tables
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 5
|
||||
--let assert_select= Foreign key referenced table found:
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t2
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 2
|
||||
--let assert_select= Foreign key referenced table found: test.t2
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t3
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 2
|
||||
--let assert_select= Foreign key referenced table found: test.t3
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t4
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 1
|
||||
--let assert_select= Foreign key referenced table found: test.t4
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
|
||||
#
|
||||
# Verify insert has succeded.
|
||||
#
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 3 FROM test.t1
|
||||
--source include/wait_condition.inc
|
||||
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
|
||||
--connection node_1
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
DROP TABLE t4, t3, t2, t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # 3. BF-BF conflict on MDL locks between:
|
||||
--echo # CREATE TABLE t3 (whose parent table are t4 -> t3 -> t2 -> t1), and
|
||||
--echo # INSERT on t1.
|
||||
--echo #
|
||||
|
||||
#
|
||||
# Setup
|
||||
#
|
||||
--connection node_2
|
||||
SET GLOBAL wsrep_slave_threads=2;
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY,
|
||||
f2 INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
id INT PRIMARY KEY,
|
||||
t1_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t1_id(t1_id),
|
||||
CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE t3 (
|
||||
id INT PRIMARY KEY,
|
||||
t2_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t2_id(t2_id),
|
||||
CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t1 VALUES (2,0);
|
||||
|
||||
INSERT INTO t2 VALUES (1,1,1234);
|
||||
INSERT INTO t2 VALUES (2,2,1234);
|
||||
|
||||
INSERT INTO t3 VALUES (1,1,1234);
|
||||
INSERT INTO t3 VALUES (2,2,1234);
|
||||
|
||||
|
||||
--let $fk_parent_query = CREATE TABLE t4 (id INT PRIMARY KEY, t3_id INT NOT NULL, f2 INTEGER NOT NULL, KEY key_t3_id(t3_id), CONSTRAINT key_t3_id FOREIGN KEY (t3_id) REFERENCES t3 (id) ON UPDATE CASCADE ON DELETE CASCADE)
|
||||
--let $fk_child_query = INSERT INTO t1 VALUES (3,0)
|
||||
--let $fk_mdl_lock_num = 4
|
||||
--source galera_multi_level_foreign_key.inc
|
||||
|
||||
|
||||
#
|
||||
# Verify Foreign key for referenced table added.
|
||||
#
|
||||
--connection node_1
|
||||
--let assert_text= Foreign key referenced table found: 2 tables
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 8
|
||||
--let assert_select= Foreign key referenced table found:
|
||||
--let $assert_only_after = CURRENT_TEST:
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t2
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 3
|
||||
--let assert_select= Foreign key referenced table found: test.t2
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t3
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 3
|
||||
--let assert_select= Foreign key referenced table found: test.t3
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t4
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 2
|
||||
--let assert_select= Foreign key referenced table found: test.t4
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
|
||||
#
|
||||
# Verify insert has succeded.
|
||||
#
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 3 FROM test.t1
|
||||
--source include/wait_condition.inc
|
||||
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
|
||||
--connection node_1
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
select * from t3;
|
||||
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
DROP TABLE t4, t3, t2, t1;
|
||||
|
||||
|
||||
--echo #
|
||||
--echo # 4. BF-BF conflict on MDL locks between:
|
||||
--echo # OPTIMIZE TABLE t2 (whose parent table are t2 -> t1), and
|
||||
--echo # INSERT t1.
|
||||
--echo #
|
||||
|
||||
#
|
||||
# Setup
|
||||
#
|
||||
--connection node_2
|
||||
SET GLOBAL wsrep_slave_threads=2;
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INTEGER PRIMARY KEY,
|
||||
f2 INTEGER
|
||||
);
|
||||
|
||||
CREATE TABLE t2 (
|
||||
id INT PRIMARY KEY,
|
||||
t1_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t1_id(t1_id),
|
||||
CONSTRAINT key_t1_id FOREIGN KEY (t1_id) REFERENCES t1 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE t3 (
|
||||
id INT PRIMARY KEY,
|
||||
t2_id INT NOT NULL,
|
||||
f2 INTEGER NOT NULL,
|
||||
KEY key_t2_id(t2_id),
|
||||
CONSTRAINT key_t2_id FOREIGN KEY (t2_id) REFERENCES t2 (id) ON UPDATE CASCADE ON DELETE CASCADE
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO t1 VALUES (1,0);
|
||||
INSERT INTO t1 VALUES (2,0);
|
||||
|
||||
INSERT INTO t2 VALUES (1,1,1234);
|
||||
INSERT INTO t2 VALUES (2,2,1234);
|
||||
|
||||
INSERT INTO t3 VALUES (1,1,1234);
|
||||
INSERT INTO t3 VALUES (2,2,1234);
|
||||
|
||||
|
||||
--let $fk_parent_query = OPTIMIZE TABLE t3
|
||||
--let $fk_child_query = INSERT INTO t1 VALUES (3,0)
|
||||
--let $fk_mdl_lock_num = 3
|
||||
--source galera_multi_level_foreign_key.inc
|
||||
|
||||
|
||||
#
|
||||
# Verify Foreign key for referenced table added.
|
||||
#
|
||||
--connection node_1
|
||||
--let assert_text= Foreign key referenced table found: 1 tables
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 10
|
||||
--let assert_select= Foreign key referenced table found:
|
||||
--let $assert_only_after = CURRENT_TEST:
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t2
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 4
|
||||
--let assert_select= Foreign key referenced table found: test.t2
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
--let assert_text= Foreign key referenced table found: test.t3
|
||||
--let $assert_file= $MYSQLTEST_VARDIR/log/mysqld.1.err
|
||||
--let assert_count= 4
|
||||
--let assert_select= Foreign key referenced table found: test.t3
|
||||
--let assert_only_after= CURRENT_TEST: galera.galera_multi_level_fk_ddl_insert
|
||||
--source include/assert_grep.inc
|
||||
|
||||
|
||||
#
|
||||
# Verify insert has succeded.
|
||||
#
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 3 FROM test.t1
|
||||
--source include/wait_condition.inc
|
||||
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
|
||||
--connection node_1
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
|
||||
|
||||
#
|
||||
# Cleanup
|
||||
#
|
||||
DROP TABLE t3, t2, t1;
|
||||
@@ -4,25 +4,35 @@ connection node_1;
|
||||
connection node_2;
|
||||
connection node_3;
|
||||
connection node_1;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=99;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=99;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
|
||||
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
|
||||
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||
INSERT INTO t1 (f2) SELECT REPEAT('x', 1024) FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
||||
FLUSH TABLES WITH READ LOCK;
|
||||
UNLOCK TABLES;
|
||||
connection node_2;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
10000
|
||||
SELECT COUNT(*) FROM ten;
|
||||
COUNT(*)
|
||||
10
|
||||
Killing node #3 to free ports for garbd ...
|
||||
connection node_3;
|
||||
connection node_1;
|
||||
SET GLOBAL debug_dbug = "+d,sync.wsrep_donor_state";
|
||||
Starting garbd ...
|
||||
SET SESSION debug_sync = "now WAIT_FOR sync.wsrep_donor_state_reached";
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0.0;
|
||||
SET SESSION debug_sync = "now SIGNAL signal.wsrep_donor_state";
|
||||
SET GLOBAL debug_dbug = "";
|
||||
SET debug_sync='RESET';
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
Killing garbd ...
|
||||
connection node_1;
|
||||
connection node_2;
|
||||
@@ -31,9 +41,3 @@ DROP TABLE ten;
|
||||
Restarting node #3 to satisfy MTR's end-of-test checks
|
||||
connection node_3;
|
||||
connection node_1;
|
||||
connection node_1;
|
||||
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
|
||||
connection node_2;
|
||||
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
|
||||
connection node_3;
|
||||
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
|
||||
|
||||
@@ -32,14 +32,34 @@
|
||||
--let $innodb_max_dirty_pages_pct = `SELECT @@innodb_max_dirty_pages_pct`
|
||||
--let $innodb_max_dirty_pages_pct_lwm = `SELECT @@innodb_max_dirty_pages_pct_lwm`
|
||||
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
|
||||
|
||||
--let $wait_condition = SELECT variable_value = 0 FROM information_schema.global_status WHERE variable_name = 'INNODB_BUFFER_POOL_PAGES_DIRTY'
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=99;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=99;
|
||||
|
||||
--connection node_1
|
||||
CREATE TABLE t1 (f1 INTEGER, f2 varchar(1024)) Engine=InnoDB;
|
||||
CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
|
||||
INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
|
||||
INSERT INTO t1 (f2) SELECT REPEAT('x', 1024) FROM ten AS a1, ten AS a2, ten AS a3, ten AS a4;
|
||||
FLUSH TABLES WITH READ LOCK;
|
||||
UNLOCK TABLES;
|
||||
|
||||
--connection node_2
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 't1'
|
||||
--source include/wait_condition.inc
|
||||
--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'ten'
|
||||
--source include/wait_condition.inc
|
||||
--let $wait_condition = SELECT COUNT(*) = 10 FROM ten
|
||||
--source include/wait_condition.inc
|
||||
--let $wait_condition = SELECT COUNT(*) = 10000 FROM t1
|
||||
--source include/wait_condition.inc
|
||||
|
||||
SELECT COUNT(*) FROM t1;
|
||||
SELECT COUNT(*) FROM ten;
|
||||
|
||||
--echo Killing node #3 to free ports for garbd ...
|
||||
--connection node_3
|
||||
@@ -60,24 +80,20 @@ SET SESSION debug_sync = "now WAIT_FOR sync.wsrep_donor_state_reached";
|
||||
#
|
||||
# get hash of data directory contents before BP dirty page flushing
|
||||
#
|
||||
--exec find $datadir -type f ! -name tables_flushed ! -name backup_sst_complete -exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_before
|
||||
--exec find $datadir -type f ! -name tables_flushed ! -name backup_sst_complete -print 0 -exec md5sum {} \; | sort -u | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_before
|
||||
|
||||
# this should force buffer pool flushing, if not already done by donor state change transfer
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct_lwm=0.0;
|
||||
SET GLOBAL innodb_max_dirty_pages_pct=0.0;
|
||||
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
select f1 from t1;
|
||||
select * from ten;
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
--let $wait_condition = SELECT variable_value = 0 FROM information_schema.global_status WHERE variable_name = 'INNODB_BUFFER_POOL_PAGES_DIRTY'
|
||||
--source include/wait_condition.inc
|
||||
|
||||
#
|
||||
#
|
||||
# record the hash of data directory contents after BP dirty page flushing
|
||||
#
|
||||
--exec find $datadir -type f ! -name tables_flushed ! -name backup_sst_complete -exec md5sum {} \; | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_after
|
||||
--exec find $datadir -type f ! -name tables_flushed ! -name backup_sst_complete -print 0 -exec md5sum {} \; | sort -u | md5sum >$MYSQLTEST_VARDIR/tmp/innodb_after
|
||||
|
||||
# there should be no disk writes
|
||||
--diff_files $MYSQLTEST_VARDIR/tmp/innodb_before $MYSQLTEST_VARDIR/tmp/innodb_after
|
||||
@@ -86,7 +102,7 @@ SET SESSION debug_sync = "now SIGNAL signal.wsrep_donor_state";
|
||||
SET GLOBAL debug_dbug = "";
|
||||
SET debug_sync='RESET';
|
||||
|
||||
--connection node_2
|
||||
--connection node_1
|
||||
|
||||
#
|
||||
# garbd will die automatically, because of the backup SST script
|
||||
@@ -122,13 +138,3 @@ let $restart_noprint=2;
|
||||
# Restore original auto_increment_offset values.
|
||||
--source ../galera/include/auto_increment_offset_restore.inc
|
||||
|
||||
# Workaround for galera#101
|
||||
|
||||
--connection node_1
|
||||
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
|
||||
|
||||
--connection node_2
|
||||
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
|
||||
|
||||
--connection node_3
|
||||
CALL mtr.add_suppression("WSREP: Protocol violation\\. JOIN message sender 1\\.0( \\(.*\\))? is not in state transfer \\(SYNCED\\)\\. Message ignored\\.");
|
||||
|
||||
@@ -143,9 +143,9 @@ asm(".arch_extension crypto");
|
||||
|
||||
|
||||
#define CRC32C3X8(buffer, ITR) \
|
||||
__asm__("crc32cx %w[c1], %w[c1], %x[v]":[c1]"+r"(crc1):[v]"r"(*((const uint64_t *)buffer + 42*1 + (ITR))));\
|
||||
__asm__("crc32cx %w[c2], %w[c2], %x[v]":[c2]"+r"(crc2):[v]"r"(*((const uint64_t *)buffer + 42*2 + (ITR))));\
|
||||
__asm__("crc32cx %w[c0], %w[c0], %x[v]":[c0]"+r"(crc0):[v]"r"(*((const uint64_t *)buffer + 42*0 + (ITR))));
|
||||
__asm__("crc32cx %w[c1], %w[c1], %x[v]":[c1]"+r"(crc1):[v]"r"(uint8korr(buffer + (42*1 + (ITR)) * sizeof(uint64_t))));\
|
||||
__asm__("crc32cx %w[c2], %w[c2], %x[v]":[c2]"+r"(crc2):[v]"r"(uint8korr(buffer + (42*2 + (ITR)) * sizeof(uint64_t))));\
|
||||
__asm__("crc32cx %w[c0], %w[c0], %x[v]":[c0]"+r"(crc0):[v]"r"(uint8korr(buffer + (42*0 + (ITR)) * sizeof(uint64_t))));
|
||||
|
||||
#else /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
|
||||
|
||||
@@ -167,9 +167,9 @@ asm(".arch_extension crypto");
|
||||
#define CRC32B(crc, value) (crc) = __crc32b((crc), (value))
|
||||
|
||||
#define CRC32C3X8(buffer, ITR) \
|
||||
crc1 = __crc32cd(crc1, *((const uint64_t *)buffer + 42*1 + (ITR)));\
|
||||
crc2 = __crc32cd(crc2, *((const uint64_t *)buffer + 42*2 + (ITR)));\
|
||||
crc0 = __crc32cd(crc0, *((const uint64_t *)buffer + 42*0 + (ITR)));
|
||||
crc1 = __crc32cd(crc1, uint8korr(buffer + (42*1 + (ITR)) * sizeof(uint64_t)));\
|
||||
crc2 = __crc32cd(crc2, uint8korr(buffer + (42*2 + (ITR)) * sizeof(uint64_t)));\
|
||||
crc0 = __crc32cd(crc0, uint8korr(buffer + (42*0 + (ITR)) * sizeof(uint64_t)));
|
||||
|
||||
#endif /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
|
||||
|
||||
@@ -234,20 +234,20 @@ static unsigned crc32c_aarch64(unsigned crc, const void *buf, size_t len)
|
||||
|
||||
while ((length-= sizeof(uint64_t)) >= 0)
|
||||
{
|
||||
CRC32CX(crc, *(uint64_t *)buffer);
|
||||
CRC32CX(crc, uint8korr(buffer));
|
||||
buffer+= sizeof(uint64_t);
|
||||
}
|
||||
|
||||
/* The following is more efficient than the straight loop */
|
||||
if (length & sizeof(uint32_t))
|
||||
{
|
||||
CRC32CW(crc, *(uint32_t *)buffer);
|
||||
CRC32CW(crc, uint4korr(buffer));
|
||||
buffer+= sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (length & sizeof(uint16_t))
|
||||
{
|
||||
CRC32CH(crc, *(uint16_t *)buffer);
|
||||
CRC32CH(crc, uint2korr(buffer));
|
||||
buffer+= sizeof(uint16_t);
|
||||
}
|
||||
|
||||
@@ -291,7 +291,7 @@ static unsigned crc32c_aarch64_pmull(unsigned crc, const void *buf, size_t len)
|
||||
/* Prefetch 3*1024 data for avoiding L2 cache miss */
|
||||
PREF1KL2(buffer, 1024*3);
|
||||
/* Do first 8 bytes here for better pipelining */
|
||||
crc0= __crc32cd(crc, *(const uint64_t *)buffer);
|
||||
crc0= __crc32cd(crc, uint8korr(buffer));
|
||||
crc1= 0;
|
||||
crc2= 0;
|
||||
buffer+= sizeof(uint64_t);
|
||||
@@ -317,7 +317,7 @@ static unsigned crc32c_aarch64_pmull(unsigned crc, const void *buf, size_t len)
|
||||
*/
|
||||
t1= poly_mul(crc1, k2);
|
||||
t0= poly_mul(crc0, k1);
|
||||
crc= __crc32cd(crc2, *(const uint64_t *)buffer);
|
||||
crc= __crc32cd(crc2, uint8korr(buffer));
|
||||
crc1= __crc32cd(0, t1);
|
||||
crc^= crc1;
|
||||
crc0= __crc32cd(0, t0);
|
||||
@@ -342,7 +342,7 @@ static unsigned crc32c_aarch64_pmull(unsigned crc, const void *buf, size_t len)
|
||||
|
||||
PREF1KL2(buffer, 1024*3);
|
||||
__asm__("crc32cx %w[c0], %w[c], %x[v]\n\t"
|
||||
:[c0]"=r"(crc0):[c]"r"(crc), [v]"r"(*(const uint64_t *)buffer):);
|
||||
:[c0]"=r"(crc0):[c]"r"(crc), [v]"r"(uint8korr(buffer)):);
|
||||
crc1= 0;
|
||||
crc2= 0;
|
||||
buffer+= sizeof(uint64_t);
|
||||
@@ -368,7 +368,7 @@ static unsigned crc32c_aarch64_pmull(unsigned crc, const void *buf, size_t len)
|
||||
"crc32cx %w[c0], wzr, %x[c0] \n\t"
|
||||
"eor %w[c], %w[c], %w[c0] \n\t"
|
||||
:[c1]"+r"(crc1), [c0]"+r"(crc0), [c2]"+r"(crc2), [c]"+r"(crc)
|
||||
:[v]"r"(*((const uint64_t *)buffer)));
|
||||
:[v]"r"(uint8korr(buffer)));
|
||||
buffer+= sizeof(uint64_t);
|
||||
}
|
||||
# endif /* HAVE_ARMV8_CRC_CRYPTO_INTRINSICS */
|
||||
@@ -379,20 +379,20 @@ static unsigned crc32c_aarch64_pmull(unsigned crc, const void *buf, size_t len)
|
||||
{
|
||||
while ((length-= sizeof(uint64_t)) >= 0)
|
||||
{
|
||||
CRC32CX(crc, *(uint64_t *)buffer);
|
||||
CRC32CX(crc, uint8korr(buffer));
|
||||
buffer+= sizeof(uint64_t);
|
||||
}
|
||||
|
||||
/* The following is more efficient than the straight loop */
|
||||
if (length & sizeof(uint32_t))
|
||||
{
|
||||
CRC32CW(crc, *(uint32_t *)buffer);
|
||||
CRC32CW(crc, uint4korr(buffer));
|
||||
buffer+= sizeof(uint32_t);
|
||||
}
|
||||
|
||||
if (length & sizeof(uint16_t))
|
||||
{
|
||||
CRC32CH(crc, *(uint16_t *)buffer);
|
||||
CRC32CH(crc, uint2korr(buffer));
|
||||
buffer+= sizeof(uint16_t);
|
||||
}
|
||||
|
||||
@@ -426,8 +426,10 @@ unsigned int crc32_aarch64(unsigned int crc, const void *buf, size_t len)
|
||||
len--;
|
||||
}
|
||||
|
||||
for (; len >= 8; len-= 8)
|
||||
CRC32X(crc, *buf8++);
|
||||
for (; len >= 8; len-= 8) {
|
||||
CRC32X(crc, uint8korr((uchar *)buf8));
|
||||
buf8++;
|
||||
}
|
||||
|
||||
buf1= (const uint8_t *) buf8;
|
||||
while (len--)
|
||||
|
||||
@@ -29,8 +29,11 @@ void sha256_crypt_r(const unsigned char *key, size_t key_len,
|
||||
unsigned char tmp[SHA256_DIGEST_LENGTH];
|
||||
unsigned char alt[SHA256_DIGEST_LENGTH];
|
||||
size_t cnt;
|
||||
static const char b64t[64] =
|
||||
"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
static const char b64t[64]
|
||||
#if defined __GNUC__ && __GNUC__ > 7
|
||||
__attribute__((nonstring))
|
||||
#endif
|
||||
= "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
void *ctx = alloca(my_sha256_context_size());
|
||||
unsigned char *p_bytes = alloca(key_len);
|
||||
unsigned char *s_bytes = alloca(salt_len);
|
||||
|
||||
@@ -3985,6 +3985,15 @@ bool extend_table_list(THD *thd, TABLE_LIST *tables,
|
||||
(tables->updating && tables->lock_type >= TL_FIRST_WRITE)
|
||||
|| thd->lex->default_used;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
if (WSREP(thd) && !thd->wsrep_applier &&
|
||||
wsrep_is_active(thd) &&
|
||||
(sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA) &&
|
||||
tables->lock_type == TL_READ) {
|
||||
maybe_need_prelocking= true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (thd->locked_tables_mode <= LTM_LOCK_TABLES &&
|
||||
! has_prelocking_list && maybe_need_prelocking)
|
||||
{
|
||||
@@ -5115,6 +5124,7 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
Query_arena *arena, backup;
|
||||
TABLE *table= table_list->table;
|
||||
bool error= FALSE;
|
||||
bool override_fk_ignore_table= FALSE;
|
||||
|
||||
if (!table->file->referenced_by_foreign_key())
|
||||
DBUG_RETURN(FALSE);
|
||||
@@ -5131,6 +5141,37 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
|
||||
*need_prelocking= TRUE;
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
MDL is enough for read-only FK checks, we don't need the table,
|
||||
but on galera applier node lock_type is set to TL_FIRST_WRITE and not
|
||||
TL_READ, which is due to Write_rows_log_event event logged for INSERT
|
||||
is used to record insert, update and delete
|
||||
(Write_rows_log_event::get_trg_event_map()), and therefore all child
|
||||
tables will be opened and MDL locks will be taken on applier node, while
|
||||
opening of multiple child tables is ignored on write node by setting
|
||||
open_strategy= OPEN_STUB in init_one_table_for_prelocking().
|
||||
This difference in write and applier node can result in MDL deadlock.
|
||||
Tables with foreign keys: t1<-t2<-t3<-t4
|
||||
Conflicting transactions: INSERT t1 and DROP TABLE t4
|
||||
Wsrep certification keys taken on write node:
|
||||
- for INSERT t1: t1 and t2
|
||||
- for DROP TABLE t4: t4
|
||||
On applier node MDL deadlock happened between two transaction because
|
||||
MDL locks for INSERT t1 were taken on t1, t2, t3 and t4, which conflicted
|
||||
with MDL lock on t4 taken by DROP TABLE t4.
|
||||
The Wsrep certification keys does helps in resolving in transactions
|
||||
getting MDL deadlock. But to generate Wsrep certification keys it needs
|
||||
to open and take MDL locks on all child tables. So that conflicting
|
||||
transactions can be prioritize and scheduled.
|
||||
*/
|
||||
if (WSREP(thd) && !thd->wsrep_applier &&
|
||||
wsrep_is_active(thd) &&
|
||||
(sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA)) {
|
||||
override_fk_ignore_table= TRUE;
|
||||
}
|
||||
#endif // WITH_WSREP
|
||||
|
||||
while ((fk= fk_list_it++))
|
||||
{
|
||||
// FK_OPTION_RESTRICT and FK_OPTION_NO_ACTION only need read access
|
||||
@@ -5149,13 +5190,15 @@ prepare_fk_prelocking_list(THD *thd, Query_tables_list *prelocking_ctx,
|
||||
TABLE_LIST *tl= thd->alloc<TABLE_LIST>(1);
|
||||
tl->init_one_table_for_prelocking(fk->foreign_db, fk->foreign_table,
|
||||
NULL, lock_type, TABLE_LIST::PRELOCK_FK, table_list->belong_to_view,
|
||||
op, &prelocking_ctx->query_tables_last, table_list->for_insert_data);
|
||||
op, &prelocking_ctx->query_tables_last, table_list->for_insert_data,
|
||||
override_fk_ignore_table);
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
Append table level shared key for the referenced/foreign table for:
|
||||
- statement that updates existing rows (UPDATE, multi-update)
|
||||
- statement that deletes existing rows (DELETE, DELETE_MULTI)
|
||||
- statement that inserts new rows (INSERT, REPLACE, LOAD, ALTER TABLE)
|
||||
This is done to avoid potential MDL conflicts with concurrent DDLs.
|
||||
*/
|
||||
if (wsrep_foreign_key_append(thd, fk))
|
||||
@@ -5198,11 +5241,31 @@ bool DML_prelocking_strategy::handle_table(THD *thd,
|
||||
{
|
||||
DBUG_ENTER("handle_table");
|
||||
TABLE *table= table_list->table;
|
||||
bool trigger_prelocking_needed=
|
||||
(table_list->lock_type >= TL_FIRST_WRITE) ? TRUE : FALSE;
|
||||
/* We rely on a caller to check that table is going to be changed. */
|
||||
DBUG_ASSERT(table_list->lock_type >= TL_FIRST_WRITE ||
|
||||
((sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA)
|
||||
&& table_list->lock_type == TL_READ) ||
|
||||
thd->lex->default_used);
|
||||
|
||||
if (table_list->trg_event_map && table_list->lock_type >= TL_FIRST_WRITE)
|
||||
#ifdef WITH_WSREP
|
||||
/*
|
||||
Only do trigger prelocking for tables that are doing to be modified (with
|
||||
a write lock), but ignore rest for Galera additional keys for the
|
||||
referenced/foreign table are needed to avoid potential MDL conflicts with
|
||||
concurrent update and DDLs.
|
||||
*/
|
||||
if (WSREP(thd) && !thd->wsrep_applier &&
|
||||
wsrep_is_active(thd) &&
|
||||
(sql_command_flags[thd->lex->sql_command] & CF_INSERTS_DATA) &&
|
||||
table_list->trg_event_map && !table->triggers)
|
||||
{
|
||||
trigger_prelocking_needed= TRUE;
|
||||
}
|
||||
#endif // WITH_WSREP
|
||||
|
||||
if (table_list->trg_event_map && trigger_prelocking_needed)
|
||||
{
|
||||
if (table->triggers)
|
||||
{
|
||||
|
||||
@@ -2482,7 +2482,7 @@ void THD::cleanup_after_query()
|
||||
if (!in_active_multi_stmt_transaction())
|
||||
wsrep_affected_rows= 0;
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
gap_tracker_data.init();
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
@@ -3512,14 +3512,29 @@ public:
|
||||
static const ulong initial_gtid_domain_buffer_size= 16;
|
||||
uint32 gtid_domain_static_buffer[initial_gtid_domain_buffer_size];
|
||||
|
||||
inline void set_limit_rows_examined()
|
||||
/*
|
||||
Activates enforcement of the LIMIT ROWS EXAMINED clause, if present
|
||||
in the query.
|
||||
*/
|
||||
void set_limit_rows_examined()
|
||||
{
|
||||
if (limit_rows_examined)
|
||||
limit_rows_examined_cnt= limit_rows_examined->val_uint();
|
||||
else
|
||||
limit_rows_examined_cnt= ULONGLONG_MAX;
|
||||
}
|
||||
|
||||
/**
|
||||
Deactivates enforcement of the LIMIT ROWS EXAMINED clause and returns its
|
||||
prior state.
|
||||
Return value:
|
||||
- false: LIMIT ROWS EXAMINED was not activated
|
||||
- true: LIMIT ROWS EXAMINED was activated
|
||||
*/
|
||||
bool deactivate_limit_rows_examined()
|
||||
{
|
||||
bool was_activated= (limit_rows_examined_cnt != ULONGLONG_MAX);
|
||||
limit_rows_examined_cnt= ULONGLONG_MAX; // Unreachable value
|
||||
return was_activated;
|
||||
}
|
||||
|
||||
LEX_CSTRING *win_ref;
|
||||
Window_frame *win_frame;
|
||||
|
||||
@@ -665,8 +665,8 @@ bool handle_select(THD *thd, LEX *lex, select_result *result,
|
||||
thd->abort_on_warning= saved_abort_on_warning;
|
||||
thd->reset_killed();
|
||||
}
|
||||
/* Disable LIMIT ROWS EXAMINED after query execution. */
|
||||
thd->lex->limit_rows_examined_cnt= ULONGLONG_MAX;
|
||||
/* Deactivate LIMIT ROWS EXAMINED after query execution. */
|
||||
thd->lex->deactivate_limit_rows_examined();
|
||||
|
||||
MYSQL_SELECT_DONE((int) res, (ulong) thd->limit_found_rows);
|
||||
DBUG_RETURN(res);
|
||||
@@ -4878,7 +4878,7 @@ int JOIN::exec_inner()
|
||||
THD_STAGE_INFO(thd, stage_executing);
|
||||
|
||||
/*
|
||||
Enable LIMIT ROWS EXAMINED during query execution if:
|
||||
Activate enforcement of LIMIT ROWS EXAMINED during query execution if:
|
||||
(1) This JOIN is the outermost query (not a subquery or derived table)
|
||||
This ensures that the limit is enabled when actual execution begins,
|
||||
and not if a subquery is evaluated during optimization of the outer
|
||||
@@ -28052,10 +28052,10 @@ JOIN_TAB::remove_duplicates()
|
||||
sort_field_keylength+= ptr->length + (ptr->item->maybe_null() ? 1 : 0);
|
||||
|
||||
/*
|
||||
Disable LIMIT ROWS EXAMINED in order to avoid interrupting prematurely
|
||||
Deactivate LIMIT ROWS EXAMINED in order to avoid interrupting prematurely
|
||||
duplicate removal, and produce a possibly incomplete query result.
|
||||
*/
|
||||
thd->lex->limit_rows_examined_cnt= ULONGLONG_MAX;
|
||||
thd->lex->deactivate_limit_rows_examined();
|
||||
if (thd->killed == ABORT_QUERY)
|
||||
thd->reset_killed();
|
||||
|
||||
|
||||
@@ -2373,8 +2373,14 @@ bool st_select_lex_unit::exec_inner()
|
||||
if (!saved_error && !was_executed)
|
||||
save_union_explain(thd->lex->explain);
|
||||
|
||||
if (unlikely(saved_error))
|
||||
return saved_error;
|
||||
error= saved_error;
|
||||
|
||||
if (unlikely(error))
|
||||
{
|
||||
err:
|
||||
thd->lex->current_select= lex_select_save;
|
||||
return error;
|
||||
}
|
||||
|
||||
if (union_result)
|
||||
{
|
||||
@@ -2465,7 +2471,8 @@ bool st_select_lex_unit::exec_inner()
|
||||
{
|
||||
table->file->print_error(error, MYF(0));
|
||||
DBUG_ASSERT(0);
|
||||
return true;
|
||||
error= true;
|
||||
goto err;
|
||||
}
|
||||
table->no_keyread=1;
|
||||
}
|
||||
@@ -2473,24 +2480,24 @@ bool st_select_lex_unit::exec_inner()
|
||||
{
|
||||
if (union_result->flush())
|
||||
{
|
||||
thd->lex->current_select= lex_select_save;
|
||||
return true;
|
||||
error= true;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlikely(saved_error))
|
||||
{
|
||||
thd->lex->current_select= lex_select_save;
|
||||
return saved_error;
|
||||
error= saved_error;
|
||||
goto err;
|
||||
}
|
||||
if (fake_select_lex != NULL)
|
||||
{
|
||||
/* Needed for the following test and for records_at_start in next loop */
|
||||
int error= table->file->info(HA_STATUS_VARIABLE);
|
||||
error= table->file->info(HA_STATUS_VARIABLE);
|
||||
if (unlikely(error))
|
||||
{
|
||||
table->file->print_error(error, MYF(0));
|
||||
return true;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (found_rows_for_union && !sl->braces &&
|
||||
@@ -2524,20 +2531,19 @@ bool st_select_lex_unit::exec_inner()
|
||||
|
||||
DBUG_EXECUTE_IF("show_explain_probe_union_read",
|
||||
dbug_serve_apcs(thd, 1););
|
||||
{
|
||||
List<Item_func_match> empty_list;
|
||||
empty_list.empty();
|
||||
/*
|
||||
Disable LIMIT ROWS EXAMINED in order to produce the possibly incomplete
|
||||
result of the UNION without interruption due to exceeding the limit.
|
||||
*/
|
||||
thd->lex->limit_rows_examined_cnt= ULONGLONG_MAX;
|
||||
/*
|
||||
Temporarily deactivate LIMIT ROWS EXAMINED to avoid producing potentially
|
||||
incomplete result of the UNION due to exceeding of the limit. It will be
|
||||
re-activated upon the function exit (see SCOPE_EXIT macro above)
|
||||
*/
|
||||
const bool limit_rows_was_activated=
|
||||
thd->lex->deactivate_limit_rows_examined();
|
||||
|
||||
// Check if EOM
|
||||
if (fake_select_lex != NULL && likely(!thd->is_fatal_error))
|
||||
{
|
||||
/* Send result to 'result' */
|
||||
saved_error= true;
|
||||
// Check if EOM
|
||||
if (fake_select_lex != NULL && likely(!thd->is_fatal_error))
|
||||
{
|
||||
/* Send result to 'result' */
|
||||
saved_error= true;
|
||||
|
||||
set_limit(global_parameters());
|
||||
JOIN *join= fake_select_lex->join;
|
||||
@@ -2591,10 +2597,10 @@ bool st_select_lex_unit::exec_inner()
|
||||
Mark for slow query log if any of the union parts didn't use
|
||||
indexes efficiently
|
||||
*/
|
||||
}
|
||||
}
|
||||
thd->lex->current_select= lex_select_save;
|
||||
thd->lex->set_limit_rows_examined();
|
||||
if (limit_rows_was_activated)
|
||||
thd->lex->set_limit_rows_examined();
|
||||
return saved_error;
|
||||
}
|
||||
|
||||
@@ -2726,7 +2732,6 @@ bool st_select_lex_unit::exec_recursive()
|
||||
|
||||
thd->lex->current_select= lex_select_save;
|
||||
err:
|
||||
thd->lex->set_limit_rows_examined();
|
||||
DBUG_RETURN(saved_error);
|
||||
}
|
||||
|
||||
|
||||
17
sql/table.h
17
sql/table.h
@@ -2522,15 +2522,11 @@ struct TABLE_LIST
|
||||
}
|
||||
|
||||
inline void init_one_table_for_prelocking(const LEX_CSTRING *db_arg,
|
||||
const LEX_CSTRING *table_name_arg,
|
||||
const LEX_CSTRING *alias_arg,
|
||||
enum thr_lock_type lock_type_arg,
|
||||
prelocking_types prelocking_type,
|
||||
TABLE_LIST *belong_to_view_arg,
|
||||
uint8 trg_event_map_arg,
|
||||
TABLE_LIST ***last_ptr,
|
||||
my_bool insert_data)
|
||||
|
||||
const LEX_CSTRING *table_name_arg, const LEX_CSTRING *alias_arg,
|
||||
enum thr_lock_type lock_type_arg, prelocking_types prelocking_type,
|
||||
TABLE_LIST *belong_to_view_arg, uint8 trg_event_map_arg,
|
||||
TABLE_LIST ***last_ptr, my_bool insert_data,
|
||||
my_bool override_fk_ignore_table= FALSE)
|
||||
{
|
||||
init_one_table(db_arg, table_name_arg, alias_arg, lock_type_arg);
|
||||
cacheable_table= 1;
|
||||
@@ -2541,7 +2537,8 @@ struct TABLE_LIST
|
||||
belong_to_view= belong_to_view_arg;
|
||||
trg_event_map= trg_event_map_arg;
|
||||
/* MDL is enough for read-only FK checks, we don't need the table */
|
||||
if (prelocking_type == PRELOCK_FK && lock_type < TL_FIRST_WRITE)
|
||||
if (prelocking_type == PRELOCK_FK && lock_type < TL_FIRST_WRITE &&
|
||||
!override_fk_ignore_table)
|
||||
open_strategy= OPEN_STUB;
|
||||
|
||||
**last_ptr= this;
|
||||
|
||||
@@ -4146,7 +4146,7 @@ bool wsrep_foreign_key_append(THD *thd, FOREIGN_KEY_INFO *fk)
|
||||
if (WSREP(thd) && !thd->wsrep_applier &&
|
||||
wsrep_is_active(thd) &&
|
||||
(sql_command_flags[thd->lex->sql_command] &
|
||||
(CF_UPDATES_DATA | CF_DELETES_DATA)))
|
||||
(CF_UPDATES_DATA | CF_DELETES_DATA | CF_INSERTS_DATA)))
|
||||
{
|
||||
wsrep::key key(wsrep::key::shared);
|
||||
key.append_key_part(fk->foreign_db->str, fk->foreign_db->length);
|
||||
|
||||
@@ -1046,10 +1046,13 @@ dberr_t ibuf_upgrade_needed()
|
||||
if (!root)
|
||||
goto err_exit;
|
||||
|
||||
const size_t payload= fil_system.sys_space->full_crc32() ||
|
||||
!fil_system.sys_space->crypt_data
|
||||
? FIL_PAGE_TYPE : FIL_PAGE_SPACE_ID;
|
||||
|
||||
if (UNIV_LIKELY(!page_has_siblings(root->page.frame)) &&
|
||||
UNIV_LIKELY(!memcmp(root->page.frame + FIL_PAGE_TYPE, field_ref_zero,
|
||||
srv_page_size -
|
||||
(FIL_PAGE_DATA_END + FIL_PAGE_TYPE))))
|
||||
UNIV_LIKELY(!memcmp(root->page.frame + payload, field_ref_zero,
|
||||
srv_page_size - (FIL_PAGE_DATA_END + payload))))
|
||||
/* the change buffer was removed; no need to upgrade */;
|
||||
else if (page_is_comp(root->page.frame) ||
|
||||
btr_page_get_index_id(root->page.frame) != ibuf_index_id ||
|
||||
|
||||
@@ -136,7 +136,8 @@ int main(int argc __attribute__((unused)),char *argv[])
|
||||
DO_TEST_CRC32C(0,STR,(sizeof(STR)-1));
|
||||
ok(0 == my_crc32c(0, NULL, 0), "crc32c data = NULL, length = 0");
|
||||
|
||||
memset(buf, 0x5a, sizeof buf);
|
||||
for (size_t i = 0; i < sizeof buf; i++)
|
||||
buf[i] = i % 251;
|
||||
ok(0 == test_buf(my_checksum, crc32), "crc32 with various lengths");
|
||||
ok(0 == test_buf(my_crc32c, crc32c), "crc32c with various lengths");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user