summaryrefslogtreecommitdiff
path: root/sql/events.cc
diff options
context:
space:
mode:
authorJan Lindström <jan.lindstrom@mariadb.com>2019-09-06 14:54:22 +0300
committerJan Lindström <jan.lindstrom@mariadb.com>2019-09-09 14:23:59 +0300
commit0fd5b11eb05be8e8e996b26d845aae3b863448d3 (patch)
treea4c2007cd9ebf3af7f611ef53f82e63c15fdb9d9 /sql/events.cc
parentefbfded563c0d9fe5904bac0436ca5fd88baff20 (diff)
downloadmariadb-git-0fd5b11eb05be8e8e996b26d845aae3b863448d3.tar.gz
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
Diffstat (limited to 'sql/events.cc')
-rw-r--r--sql/events.cc40
1 files changed, 40 insertions, 0 deletions
diff --git a/sql/events.cc b/sql/events.cc
index 15da0adee70..c189354d5eb 100644
--- a/sql/events.cc
+++ b/sql/events.cc
@@ -1198,6 +1198,46 @@ Events::load_events_from_db(THD *thd)
delete et;
goto end;
}
+
+#ifdef WITH_WSREP
+ /**
+ IF SST is done from a galera node that is also acting as MASTER
+ newly synced node in galera eco-system will also copy-over the event state
+ enabling duplicate event in galera eco-system.
+ DISABLE such events if the current node is not event orginator.
+ (Also, make sure you skip disabling it if is already disabled to avoid
+ creation of redundant action)
+ NOTE:
+ This complete system relies on server-id. Ideally server-id should be
+ same for all nodes of galera eco-system but they aren't same.
+ Infact, based on galera use-case it seems like it recommends to have each
+ node with different server-id.
+ */
+ if (et->originator != thd->variables.server_id)
+ {
+ if (et->status == Event_parse_data::SLAVESIDE_DISABLED)
+ continue;
+
+ store_record(table, record[1]);
+ table->field[ET_FIELD_STATUS]->
+ store((longlong) Event_parse_data::SLAVESIDE_DISABLED,
+ TRUE);
+
+ /* All the dmls to mysql.events tables are stmt bin-logged. */
+ bool save_binlog_row_based;
+ if ((save_binlog_row_based= thd->is_current_stmt_binlog_format_row()))
+ thd->set_current_stmt_binlog_format_stmt();
+
+ (void) table->file->ha_update_row(table->record[1], table->record[0]);
+
+ if (save_binlog_row_based)
+ thd->set_current_stmt_binlog_format_row();
+
+ delete et;
+ continue;
+ }
+#endif /* WITH_WSREP */
+
/**
Since the Event_queue_element object could be deleted inside
Event_queue::create_event we should save the value of dropped flag