diff options
author | Daniele Sciascia <daniele.sciascia@galeracluster.com> | 2021-04-23 11:31:02 +0200 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2021-04-28 12:15:30 +0300 |
commit | b1b2689f17c8c722feb2dd6648a866908040e6a7 (patch) | |
tree | f78eeb304602eff980ee32b5d53d6d01f2c98344 /mysql-test/suite | |
parent | 206d630ea0c1f89f6c3bd2b8d3d62eafa37a2bc2 (diff) | |
download | mariadb-git-b1b2689f17c8c722feb2dd6648a866908040e6a7.tar.gz |
MDEV-25553 : Avoid unnecessary rollbacks with SRbb-10.4-MDEV-25553
This patch changes statement rollback for streaming replication.
Previously, a statement rollback was turned into full transaction
rollback in the case where the transaction had already replicated a
fragment. This was introduced in the initial implementation of
streaming replication due to the fact that we do not have a mechanism
to perform a statement rollback on the applying side.
This policy is however overly pessimistic, causing full rollbacks even
in cases where a local statement rollback, would not require a
statement rollback on the applying side. This happens to be case when
the statement itself has not replicated any fragments.
So the patch changes the condition that determines if a statement
rollback should be turned into a full rollback accordingly.
Reviewed-by: Jan Lindström <jan.lindstrom@mariadb.com>
Diffstat (limited to 'mysql-test/suite')
9 files changed, 170 insertions, 22 deletions
diff --git a/mysql-test/suite/galera_3nodes_sr/disabled.def b/mysql-test/suite/galera_3nodes_sr/disabled.def index 0944abd0ad5..900b27860a5 100644 --- a/mysql-test/suite/galera_3nodes_sr/disabled.def +++ b/mysql-test/suite/galera_3nodes_sr/disabled.def @@ -1,6 +1,5 @@ GCF-336 : GCF-582 : -GCF-609 : GCF-810A : GCF-810B : GCF-810C : diff --git a/mysql-test/suite/galera_3nodes_sr/r/GCF-609.result b/mysql-test/suite/galera_3nodes_sr/r/GCF-609.result index 8fe13c7e2bf..db7da93c8c0 100644 --- a/mysql-test/suite/galera_3nodes_sr/r/GCF-609.result +++ b/mysql-test/suite/galera_3nodes_sr/r/GCF-609.result @@ -1,20 +1,78 @@ +connection node_2; +connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; +connection node_1; SET SESSION wsrep_trx_fragment_size=1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); +connection node_2; SET SESSION wsrep_trx_fragment_size=1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20); INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20); -ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +ERROR 23000: Duplicate entry '11' for key 'PRIMARY' INSERT INTO t1 VALUES (31),(32),(33); SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; COUNT(*) = 0 0 +connection node_1; SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; COUNT(*) = 0 0 COMMIT; +connection node_2; +COMMIT; +SELECT * FROM t1; +f1 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +31 +32 +33 +connection node_1; +SELECT * FROM t1; +f1 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +31 +32 +33 DROP TABLE t1; diff --git a/mysql-test/suite/galera_3nodes_sr/t/GCF-609.test b/mysql-test/suite/galera_3nodes_sr/t/GCF-609.test index fd346cf365b..210b100a9f8 100644 --- a/mysql-test/suite/galera_3nodes_sr/t/GCF-609.test +++ b/mysql-test/suite/galera_3nodes_sr/t/GCF-609.test @@ -17,7 +17,7 @@ SET SESSION wsrep_trx_fragment_size=1; SET AUTOCOMMIT=OFF; START TRANSACTION; INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20); ---error ER_LOCK_DEADLOCK +--error ER_DUP_ENTRY INSERT INTO t1 VALUES (11),(12),(13),(14),(15),(16),(17),(18),(19),(20); INSERT INTO t1 VALUES (31),(32),(33); @@ -27,4 +27,11 @@ SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; COMMIT; +--connection node_2 +COMMIT; +SELECT * FROM t1; + +--connection node_1 +SELECT * FROM t1; + DROP TABLE t1; diff --git a/mysql-test/suite/galera_sr/r/GCF-572.result b/mysql-test/suite/galera_sr/r/GCF-572.result index cb4d48b3600..41ae2378a3f 100644 --- a/mysql-test/suite/galera_sr/r/GCF-572.result +++ b/mysql-test/suite/galera_sr/r/GCF-572.result @@ -1,18 +1,38 @@ connection node_2; connection node_1; -CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(10)) ENGINE=InnoDB; connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; connection node_1; SET SESSION wsrep_trx_fragment_size = 1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +CREATE TABLE t2 (f1 INTEGER PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2),(3); +ALTER TABLE t2 DROP PRIMARY KEY; +INSERT INTO t2 VALUES (1); +SET SESSION wsrep_trx_fragment_size = 1; +START TRANSACTION; +INSERT INTO t1 SELECT * FROM t2; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +SELECT * FROM t1; +f1 +connection node_2; +SELECT * FROM t1; +f1 +connection node_1; +DROP TABLE t1; +DROP TABLE t2; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(10)) ENGINE=InnoDB; +connection node_1; +SET SESSION wsrep_trx_fragment_size = 1; START TRANSACTION; INSERT INTO t1 VALUES (1, 'node1'); connection node_1a; INSERT INTO t1 VALUES (5, 'node2'); connection node_1; INSERT INTO t1 VALUES (5, 'node1'); -ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +ERROR 23000: Duplicate entry '5' for key 'PRIMARY' SELECT * FROM t1; f1 f2 +1 node1 5 node2 SET SESSION wsrep_trx_fragment_size = 10000; START TRANSACTION; @@ -24,6 +44,7 @@ INSERT INTO t1 VALUES(15, 'node2'); connection node_1; SELECT * FROM t1; f1 f2 +1 node1 5 node2 10 node1 INSERT INTO t1 VALUES(15, 'node1'); @@ -31,6 +52,7 @@ ERROR 23000: Duplicate entry '15' for key 'PRIMARY' COMMIT; SELECT * FROM t1; f1 f2 +1 node1 5 node2 10 node1 15 node2 diff --git a/mysql-test/suite/galera_sr/r/galera_sr_dupkey_error.result b/mysql-test/suite/galera_sr/r/galera_sr_dupkey_error.result index b23b934da33..ad843c7c2c6 100644 --- a/mysql-test/suite/galera_sr/r/galera_sr_dupkey_error.result +++ b/mysql-test/suite/galera_sr/r/galera_sr_dupkey_error.result @@ -13,7 +13,7 @@ INSERT INTO t1 VALUES (REPEAT('e', 512)); INSERT INTO t1 VALUES (REPEAT('f', 512)); connection node_2; connection node_1; -INSERT INTO t1 VALUES (REPEAT('c', 512)); +INSERT INTO t1 VALUES (REPEAT('g', 1024)),(REPEAT('c', 512)); ERROR 40001: Deadlock found when trying to get lock; try restarting transaction connection node_1; SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; diff --git a/mysql-test/suite/galera_sr/r/mysql-wsrep-bugs-900.result b/mysql-test/suite/galera_sr/r/mysql-wsrep-bugs-900.result new file mode 100644 index 00000000000..a51b5299aa2 --- /dev/null +++ b/mysql-test/suite/galera_sr/r/mysql-wsrep-bugs-900.result @@ -0,0 +1,15 @@ +connection node_2; +connection node_1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +SET SESSION wsrep_trx_fragment_size=1; +START TRANSACTION; +INSERT INTO t1 VALUES (1); +SET SESSION wsrep_cluster_name = ' '; +ERROR HY000: Variable 'wsrep_cluster_name' is a GLOBAL variable and should be set with SET GLOBAL +INSERT INTO t1 VALUES (2); +COMMIT; +SELECT f1 AS expect_1_and_2 FROM t1; +expect_1_and_2 +1 +2 +DROP TABLE t1; diff --git a/mysql-test/suite/galera_sr/t/GCF-572.test b/mysql-test/suite/galera_sr/t/GCF-572.test index abefb9b08f6..be77451a332 100644 --- a/mysql-test/suite/galera_sr/t/GCF-572.test +++ b/mysql-test/suite/galera_sr/t/GCF-572.test @@ -1,15 +1,43 @@ --source include/galera_cluster.inc --source include/have_innodb.inc -CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(10)) ENGINE=InnoDB; - --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 # -# Test 1: statement rollback is not safe -# (some fragments were already replicated) +# Test 1: statement rollback is not safe. +# Statement has already replicated some fragments # +--connection node_1 +SET SESSION wsrep_trx_fragment_size = 1; +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +CREATE TABLE t2 (f1 INTEGER PRIMARY KEY); +INSERT INTO t2 VALUES (1),(2),(3); +ALTER TABLE t2 DROP PRIMARY KEY; +INSERT INTO t2 VALUES (1); +SET SESSION wsrep_trx_fragment_size = 1; +START TRANSACTION; + +# The following INSERT .. SELECT inserts a duplicate key, +# ER_LOCK_DEADLOCK is the only possible outcome at this point. +# Notice that ER_DUP_ENTRY is NOT an option here because we were +# forced to rollback the whole transaction (not just the statement) +--error ER_LOCK_DEADLOCK +INSERT INTO t1 SELECT * FROM t2; +SELECT * FROM t1; + +--connection node_2 +SELECT * FROM t1; + +--connection node_1 +DROP TABLE t1; +DROP TABLE t2; + +# +# Test 2: statement rollback is safe. +# Fragments were already replicated, not in the same statement +# +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(10)) ENGINE=InnoDB; --connection node_1 SET SESSION wsrep_trx_fragment_size = 1; START TRANSACTION; @@ -19,20 +47,16 @@ INSERT INTO t1 VALUES (1, 'node1'); INSERT INTO t1 VALUES (5, 'node2'); --connection node_1 -# If we try to INSERT a duplicate key, ER_LOCK_DEADLOCK is the only possible -# outcome at this point. Notice that ER_DUP_ENTRY is NOT an option here -# because we were forced to rollback the whole transaction (not just the -# statement) ---error ER_LOCK_DEADLOCK +# Only the statement is rolled back, expect ER_DUP_ENTRY +--error ER_DUP_ENTRY INSERT INTO t1 VALUES (5, 'node1'); SELECT * FROM t1; # -# Test 2: statement rollback is safe -# (no fragments have been replicated) +# Test 3: statement rollback is safe +# No fragments have been replicated # - SET SESSION wsrep_trx_fragment_size = 10000; START TRANSACTION; diff --git a/mysql-test/suite/galera_sr/t/galera_sr_dupkey_error.test b/mysql-test/suite/galera_sr/t/galera_sr_dupkey_error.test index a7aca042829..146da425d88 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_dupkey_error.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_dupkey_error.test @@ -22,12 +22,13 @@ INSERT INTO t1 VALUES (REPEAT('f', 512)); --let $wait_condition = SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log; --connection node_1 -# Deadlock error instead of dupkey since the transaction is SR and -# statement rollback is not safe. +# Deadlock error instead of dupkey since the transaction is SR, +# and the statement has already replicated a fragment (which +# makes statement rollback unsafe). --error ER_LOCK_DEADLOCK -INSERT INTO t1 VALUES (REPEAT('c', 512)); +INSERT INTO t1 VALUES (REPEAT('g', 1024)),(REPEAT('c', 512)); -# Confirm that the wsrep_streaming_log table is now empty, as it was a full transaction rollback +# Confirm that the wsrep_schema table is now empty, as it was a full transaction rollback --connection node_1 SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; diff --git a/mysql-test/suite/galera_sr/t/mysql-wsrep-bugs-900.test b/mysql-test/suite/galera_sr/t/mysql-wsrep-bugs-900.test new file mode 100644 index 00000000000..d534fcc5524 --- /dev/null +++ b/mysql-test/suite/galera_sr/t/mysql-wsrep-bugs-900.test @@ -0,0 +1,22 @@ +# +# Statement with no side effects causes unnecessary full rollback +# + +--source include/galera_cluster.inc + +CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); +SET SESSION wsrep_trx_fragment_size=1; +START TRANSACTION; +INSERT INTO t1 VALUES (1); +# Let's cause some bogus error with a statement that +# does not cause any replication event. +# The following used to return error ER_LOCK_DEADLOCK +# and cause the entire transaction to be rolled back. +--error ER_GLOBAL_VARIABLE +SET SESSION wsrep_cluster_name = ' '; + +INSERT INTO t1 VALUES (2); +COMMIT; + +SELECT f1 AS expect_1_and_2 FROM t1; +DROP TABLE t1;
\ No newline at end of file |