-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MDEV-20511: Galera replication of events is not consistent
After SST from master node (the one where event is ENABLED) - you will end up with the event enabled on two nodes, hence it's now being executed twice. It can be solved by comparing event's originator with server_id. if not equal, then change its status to 'SLAVESIDE_DISABLED' Changes to be committed: new file: mysql-test/suite/galera/r/galera_events2.result new file: mysql-test/suite/galera/t/galera_events2.test modified: sql/events.cc
- Loading branch information
Jan Lindström
committed
Sep 9, 2019
1 parent
efbfded
commit 0fd5b11
Showing
3 changed files
with
306 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
connection node_1; | ||
connection node_2; | ||
connection node_1; | ||
CREATE TABLE event_table(a int) engine=innodb; | ||
CREATE EVENT event_2 ON SCHEDULE EVERY 1 SECOND | ||
ENDS NOW() + INTERVAL 6 SECOND | ||
ON COMPLETION NOT PRESERVE | ||
DO | ||
INSERT INTO event_table VALUES (1); | ||
Warnings: | ||
Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. | ||
# node_1 event should be there | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='event_2'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def test event_2 root@localhost SQL INSERT INTO event_table VALUES (1) RECURRING NULL 1 SECOND ENABLED NOT PRESERVE | ||
connection node_2; | ||
# node_2 event should be there | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='event_2'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def test event_2 root@localhost SQL INSERT INTO event_table VALUES (1) RECURRING NULL 1 SECOND SLAVESIDE_DISABLED NOT PRESERVE | ||
connection node_1; | ||
SET GLOBAL event_scheduler=ON; | ||
SHOW VARIABLES LIKE 'event_scheduler'; | ||
Variable_name Value | ||
event_scheduler ON | ||
# node_1 event should be removed | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='event_2'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
connection node_2; | ||
# node_2 event should be removed | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='event_2'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
connection node_1; | ||
SET GLOBAL event_scheduler=OFF; | ||
DROP TABLE event_table; | ||
connection node_1; | ||
CREATE DATABASE IF NOT EXISTS events_test; | ||
use events_test; | ||
CREATE USER ev_test@localhost; | ||
GRANT ALL ON events_test.* to ev_test@localhost; | ||
connect ev_con1,localhost,ev_test,,events_test; | ||
CREATE EVENT one_event ON SCHEDULE EVERY 10 SECOND DO SELECT 123; | ||
Warnings: | ||
Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. | ||
SHOW EVENTS; | ||
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation | ||
events_test one_event ev_test@localhost SYSTEM RECURRING NULL 10 # # NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def events_test one_event ev_test@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE | ||
ALTER EVENT one_event ON SCHEDULE EVERY 10 SECOND; | ||
"The definer should be ev_test@localhost" | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def events_test one_event ev_test@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE | ||
connection node_2; | ||
use events_test; | ||
"The definer should be ev_test@localhost" | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def events_test one_event ev_test@localhost SQL SELECT 123 RECURRING NULL 10 SECOND SLAVESIDE_DISABLED NOT PRESERVE | ||
connection node_1; | ||
disconnect ev_con1; | ||
use test; | ||
DROP EVENT events_test.one_event; | ||
DROP USER ev_test@localhost; | ||
DROP DATABASE events_test; | ||
connection node_1; | ||
use test; | ||
CREATE EVENT one_event ON SCHEDULE EVERY 10 SECOND DO SELECT 123; | ||
Warnings: | ||
Warning 1105 Event scheduler is switched off, use SET GLOBAL event_scheduler=ON to enable it. | ||
# node_1 Event should be enabled | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE | ||
connection node_2; | ||
use test; | ||
# node_2 Event should be SERVERSIDE_DISABLED | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND SLAVESIDE_DISABLED NOT PRESERVE | ||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) engine=InnoDB; | ||
INSERT INTO t1 VALUES (1, 'a'), (2, 'a'), (3, 'a'); | ||
SELECT * FROM t1; | ||
f1 f2 | ||
1 a | ||
2 a | ||
3 a | ||
Shutting down server ... | ||
connection node_1; | ||
UPDATE t1 SET f2 = 'b' WHERE f1 > 1; | ||
UPDATE t1 SET f2 = 'c' WHERE f1 > 2; | ||
SELECT * FROM t1; | ||
f1 f2 | ||
1 a | ||
2 b | ||
3 c | ||
connection node_2; | ||
# Force SST from node_1 to node_2 | ||
Starting server ... | ||
SELECT * FROM t1; | ||
f1 f2 | ||
1 a | ||
2 b | ||
3 c | ||
# node_2 Event should be SERVERSIDE_DISABLED | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND SLAVESIDE_DISABLED NOT PRESERVE | ||
connection node_1; | ||
SELECT * FROM t1; | ||
f1 f2 | ||
1 a | ||
2 b | ||
3 c | ||
# node_1 Event should be ENABLED | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
EVENT_CATALOG EVENT_SCHEMA EVENT_NAME DEFINER EVENT_BODY EVENT_DEFINITION EVENT_TYPE EXECUTE_AT INTERVAL_VALUE INTERVAL_FIELD STATUS ON_COMPLETION EVENT_COMMENT | ||
def test one_event root@localhost SQL SELECT 123 RECURRING NULL 10 SECOND ENABLED NOT PRESERVE | ||
DROP TABLE t1; | ||
DROP EVENT one_event; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
--source include/galera_cluster.inc | ||
|
||
# Save original auto_increment_offset values. | ||
--let $node_1=node_1 | ||
--let $node_2=node_2 | ||
--source include/auto_increment_offset_save.inc | ||
|
||
# | ||
# Test case 1: "ONE TIME" events should be dropped on slave nodes after expiring on master (event creator node) | ||
# | ||
|
||
--connection node_1 | ||
|
||
CREATE TABLE event_table(a int) engine=innodb; | ||
|
||
CREATE EVENT event_2 ON SCHEDULE EVERY 1 SECOND | ||
ENDS NOW() + INTERVAL 6 SECOND | ||
ON COMPLETION NOT PRESERVE | ||
DO | ||
INSERT INTO event_table VALUES (1); | ||
|
||
--echo # node_1 event should be there | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='event_2'; | ||
|
||
--connection node_2 | ||
--echo # node_2 event should be there | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='event_2'; | ||
|
||
--connection node_1 | ||
SET GLOBAL event_scheduler=ON; | ||
SHOW VARIABLES LIKE 'event_scheduler'; | ||
|
||
# Let event_2 reach the end of its execution interval | ||
let $wait_condition=select count(*) = 0 from information_schema.events where event_name='event_2'; | ||
--source include/wait_condition.inc | ||
|
||
--echo # node_1 event should be removed | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='event_2'; | ||
|
||
--connection node_2 | ||
--echo # node_2 event should be removed | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='event_2'; | ||
|
||
--connection node_1 | ||
SET GLOBAL event_scheduler=OFF; | ||
DROP TABLE event_table; | ||
|
||
# | ||
# Test case 2: After doing ALTER EVENT, slave nodes should have same definer as master | ||
# | ||
|
||
--connection node_1 | ||
|
||
CREATE DATABASE IF NOT EXISTS events_test; | ||
use events_test; | ||
CREATE USER ev_test@localhost; | ||
GRANT ALL ON events_test.* to ev_test@localhost; | ||
connect (ev_con1,localhost,ev_test,,events_test); | ||
|
||
CREATE EVENT one_event ON SCHEDULE EVERY 10 SECOND DO SELECT 123; | ||
--replace_column 8 # 9 # | ||
SHOW EVENTS; | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS ORDER BY EVENT_SCHEMA, EVENT_NAME; | ||
ALTER EVENT one_event ON SCHEDULE EVERY 10 SECOND; | ||
--echo "The definer should be ev_test@localhost" | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
|
||
--connection node_2 | ||
use events_test; | ||
--echo "The definer should be ev_test@localhost" | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
|
||
--connection node_1 | ||
--disconnect ev_con1 | ||
use test; | ||
DROP EVENT events_test.one_event; | ||
DROP USER ev_test@localhost; | ||
DROP DATABASE events_test; | ||
|
||
# | ||
# Test case 3: After SST from master node (the one where event is ENABLED) , slave event status should be 'SLAVESIDE_DISABLED' | ||
# | ||
|
||
--connection node_1 | ||
use test; | ||
CREATE EVENT one_event ON SCHEDULE EVERY 10 SECOND DO SELECT 123; | ||
|
||
--echo # node_1 Event should be enabled | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
|
||
--connection node_2 | ||
use test; | ||
--echo # node_2 Event should be SERVERSIDE_DISABLED | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
|
||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)) engine=InnoDB; | ||
INSERT INTO t1 VALUES (1, 'a'), (2, 'a'), (3, 'a'); | ||
|
||
SELECT * FROM t1; | ||
|
||
# Initiate normal shutdown on the node 2 and wait until shutdown has been completed: | ||
|
||
--echo Shutting down server ... | ||
--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 | ||
|
||
UPDATE t1 SET f2 = 'b' WHERE f1 > 1; | ||
UPDATE t1 SET f2 = 'c' WHERE f1 > 2; | ||
|
||
SELECT * FROM t1; | ||
|
||
--connection node_2 | ||
|
||
# Remove the "grastate.dat" file (to initiate new SST) and restart node 2 | ||
|
||
--remove_file $MYSQLTEST_VARDIR/mysqld.2/data/grastate.dat | ||
|
||
--echo # Force SST from node_1 to node_2 | ||
--let $start_mysqld_params= | ||
--echo Starting server ... | ||
--source include/start_mysqld.inc | ||
|
||
--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size' | ||
--source include/wait_condition.inc | ||
|
||
# Sanity check (node 2 is running now and can perform SQL operators): | ||
|
||
SELECT * FROM t1; | ||
--echo # node_2 Event should be SERVERSIDE_DISABLED | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
|
||
--connection node_1 | ||
SELECT * FROM t1; | ||
--echo # node_1 Event should be ENABLED | ||
SELECT EVENT_CATALOG, EVENT_SCHEMA, EVENT_NAME, DEFINER, EVENT_BODY, EVENT_DEFINITION, EVENT_TYPE, EXECUTE_AT, INTERVAL_VALUE, INTERVAL_FIELD, STATUS,ON_COMPLETION, EVENT_COMMENT FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_NAME='one_event'; | ||
|
||
DROP TABLE t1; | ||
DROP EVENT one_event; | ||
|
||
--source include/auto_increment_offset_restore.inc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters