Skip to content
Permalink
Browse files
Fixed wsrep replaying for stored procedures (#1256)
- Changed replaying to always allocate a separate THD object
  for applying log events. This is to avoid tampering original
  THD state during replay process.
- Return success from sp_instr_stmt::exec_core() if replaying
  succeeds.
- Do not push warnings/errors into diagnostics area if the
  transaction must be replayed. This is to avoid reporting
  transient errors to the client.

Added two tests galera_sp_bf_abort, galera_sp_insert_parallel.
Wsrep-lib position updated.
  • Loading branch information
temeo authored and Jan Lindström committed Apr 6, 2019
1 parent fe62ff6 commit eb872ce
Show file tree
Hide file tree
Showing 10 changed files with 579 additions and 74 deletions.
@@ -0,0 +1,356 @@
connection node_2;
connection node_1;
connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
connection node_1a;
SET SESSION wsrep_sync_wait = 0;
connection node_1;
CREATE PROCEDURE proc_update_insert()
BEGIN
UPDATE t1 SET f2 = 'b';
INSERT INTO t1 VALUES (4, 'd');
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_update_insert;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 b
2 c
3 b
4 d
wsrep_local_replays
1
DELETE FROM t1;
connection node_1;
CREATE PROCEDURE proc_update_insert_with_exit_handler()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
UPDATE t1 SET f2 = 'b';
INSERT INTO t1 VALUES (4, 'd');
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_update_insert_with_exit_handler;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 b
2 c
3 b
4 d
wsrep_local_replays
1
DELETE FROM t1;
connection node_1;
CREATE PROCEDURE proc_update_insert_with_continue_handler()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
UPDATE t1 SET f2 = 'b';
INSERT INTO t1 VALUES (4, 'd');
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_update_insert_with_continue_handler;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 b
2 c
3 b
4 d
wsrep_local_replays
1
DELETE FROM t1;
connection node_1;
CREATE PROCEDURE proc_update_insert_transaction()
BEGIN
START TRANSACTION;
UPDATE t1 SET f2 = 'b';
INSERT INTO t1 VALUES (4, 'd');
COMMIT;
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_update_insert_transaction;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 b
2 c
3 b
4 d
wsrep_local_replays
1
DELETE FROM t1;
connection node_1;
CREATE PROCEDURE proc_update_insert_transaction_with_continue_handler()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
START TRANSACTION;
UPDATE t1 SET f2 = 'b';
INSERT INTO t1 VALUES (4, 'd');
COMMIT;
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_update_insert_transaction_with_continue_handler;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 b
2 c
3 b
4 d
wsrep_local_replays
1
DELETE FROM t1;
connection node_1;
CREATE PROCEDURE proc_update_insert_transaction_with_exit_handler()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION BEGIN END;
START TRANSACTION;
UPDATE t1 SET f2 = 'b';
INSERT INTO t1 VALUES (4, 'd');
COMMIT;
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_update_insert_transaction_with_exit_handler;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 b
2 c
3 b
4 d
wsrep_local_replays
1
DELETE FROM t1;
connection node_1;
CREATE PROCEDURE proc_insert_insert_conflict()
BEGIN
INSERT INTO t1 VALUES (2, 'd');
INSERT INTO t1 VALUES (4, 'd');
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_insert_insert_conflict;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
Got one of the listed errors
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 a
2 c
3 a
wsrep_local_replays
1
DELETE FROM t1;
connection node_1;
CREATE PROCEDURE proc_insert_insert_conflict_with_exit_handler()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION SELECT "Conflict exit handler";
INSERT INTO t1 VALUES (2, 'd');
INSERT INTO t1 VALUES (4, 'd');
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_insert_insert_conflict_with_exit_handler;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
Conflict exit handler
Conflict exit handler
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 a
2 c
3 a
wsrep_local_replays
1
DELETE FROM t1;
connection node_1;
CREATE PROCEDURE proc_insert_insert_conflict_with_continue_handler()
BEGIN
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION SELECT "Conflict continue handler";
INSERT INTO t1 VALUES (2, 'd');
INSERT INTO t1 VALUES (4, 'd');
END|
INSERT INTO t1 VALUES (1, 'a'), (3, 'a');
SET SESSION wsrep_sync_wait = 0;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,apply_monitor_slave_enter_sync';
connection node_2;
INSERT INTO t1 VALUES (2, 'c');
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,after_replicate_sync';
connection node_1;
CALL proc_insert_insert_conflict_with_continue_handler;
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=apply_monitor_slave_enter_sync';
SET GLOBAL wsrep_provider_options = 'signal=after_replicate_sync';
connection node_1;
Conflict continue handler
Conflict continue handler
SET SESSION wsrep_sync_wait = default;
SELECT * FROM t1;
f1 f2
1 a
2 c
3 a
4 d
wsrep_local_replays
1
DELETE FROM t1;
DROP PROCEDURE proc_update_insert;
DROP PROCEDURE proc_update_insert_with_continue_handler;
DROP PROCEDURE proc_update_insert_with_exit_handler;
DROP PROCEDURE proc_update_insert_transaction;
DROP PROCEDURE proc_update_insert_transaction_with_continue_handler;
DROP PROCEDURE proc_update_insert_transaction_with_exit_handler;
DROP PROCEDURE proc_insert_insert_conflict;
DROP PROCEDURE proc_insert_insert_conflict_with_exit_handler;
DROP PROCEDURE proc_insert_insert_conflict_with_continue_handler;
DROP TABLE t1;
@@ -0,0 +1,41 @@
connection node_2;
connection node_1;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 INTEGER) ENGINE=InnoDB;
CREATE PROCEDURE proc_insert()
BEGIN
DECLARE i INT;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION BEGIN END;
SET i = 0;
WHILE i < 1000 DO
INSERT IGNORE INTO t1 (f1, f2)
VALUES (FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15)),
(FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15)),
(FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15)),
(FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15)),
(FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15)),
(FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15)),
(FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15)),
(FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15)),
(FLOOR(1 + RAND() * 65535), FLOOR(1 + RAND() * 15));
SET i = i + 1;
END WHILE;
END|
connection node_1;
SELECT 0;
0
0
SET SESSION wsrep_sync_wait = 0;
CALL proc_insert;
connection node_2;
SELECT 0;
0
0
SET SESSION wsrep_sync_wait = 0;
CALL proc_insert;
connection node_1;
SET SESSION wsrep_sync_wait = default;
connection node_2;
SET SESSION wsrep_sync_wait = default;
connection node_1;
DROP PROCEDURE proc_insert;
DROP TABLE t1;

0 comments on commit eb872ce

Please sign in to comment.