summaryrefslogtreecommitdiff
path: root/sql/sql_repl.cc
diff options
context:
space:
mode:
authorAndrei Elkin <andrei.elkin@mariadb.com>2017-09-29 21:56:59 +0300
committerAndrei Elkin <andrei.elkin@mariadb.com>2017-11-15 22:26:32 +0200
commitaae4932775d5780fe575087b40779700eaa4fcbf (patch)
treeedc0d2f8e178d19daf9c89688f24c9cdd9a3ef06 /sql/sql_repl.cc
parent7e1326cfcf5aea38f40fb787f1b987cb325c785b (diff)
downloadmariadb-git-aae4932775d5780fe575087b40779700eaa4fcbf.tar.gz
MDEV-12012/MDEV-11969 Can't remove GTIDs for a stale GTID Domain ID
As reported in MDEV-11969 "there's no way to ditch knowledge" about some domain that is no longer updated on a server. Besides being of annoyance to clutter output in DBA console stale domains can prevent the slave to connect the master as MDEV-12012 witnesses. What domain is obsolete must be evaluated by the user (DBA) according to whether the domain info is still relevant and will the domain ever receive any update. This patch introduces a method to discard obsolete gtid domains from the server binlog state. The removal requires no event group from such domain present in existing binlog files though. If there are any the containing logs must be first PURGEd in order for FLUSH BINARY LOGS DELETE_DOMAIN_ID=(list-of-domains) succeed. Otherwise the command returns an error. The list of obsolete domains can be computed through intersecting two sets - the earliest (first) binlog's Gtid_list and the current value of @@global.gtid_binlog_state - and extracting the domain id components from the intersection list items. The new DELETE_DOMAIN_ID featured FLUSH continues to rotate binlog omitting the deleted domains from the active binlog file's Gtid_list. Notice though when the command is ineffective - that none of requested to delete domain exists in the binlog state - rotation does not occur. Obsolete domain deletion is not harmful for connected slaves as long as master side binlog files *purge* is synchronized with FLUSH-DELETE_DOMAIN_ID. The slaves must have the last event from purged files processed as usual, in order not to bump later into requesting a gtid from a file which was already gone. While the command is not replicated (as ordinary FLUSH BINLOG LOGS is) slaves, even though having extra domains, won't suffer from reconnection errors thanks to master-slave gtid connection protocol allowing the master to be ignorant about a gtid domain. Should at failover such slave to be promoted into master role it may run the ex-master's FLUSH BINARY LOGS DELETE_DOMAIN_ID=(list-of-domains) to clean its own binlog state. NOTES. suite/perfschema/r/start_server_low_digest.result is re-recorded as consequence of internal parser codes changes.
Diffstat (limited to 'sql/sql_repl.cc')
-rw-r--r--sql/sql_repl.cc68
1 files changed, 1 insertions, 67 deletions
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 764047e4720..b5cca334891 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -30,7 +30,7 @@
#include <my_dir.h>
#include "rpl_handler.h"
#include "debug_sync.h"
-
+#include "log.h" // get_gtid_list_event
enum enum_gtid_until_state {
GTID_UNTIL_NOT_DONE,
@@ -875,72 +875,6 @@ get_binlog_list(MEM_ROOT *memroot)
DBUG_RETURN(current_list);
}
-/*
- Find the Gtid_list_log_event at the start of a binlog.
-
- NULL for ok, non-NULL error message for error.
-
- If ok, then the event is returned in *out_gtid_list. This can be NULL if we
- get back to binlogs written by old server version without GTID support. If
- so, it means we have reached the point to start from, as no GTID events can
- exist in earlier binlogs.
-*/
-static const char *
-get_gtid_list_event(IO_CACHE *cache, Gtid_list_log_event **out_gtid_list)
-{
- Format_description_log_event init_fdle(BINLOG_VERSION);
- Format_description_log_event *fdle;
- Log_event *ev;
- const char *errormsg = NULL;
-
- *out_gtid_list= NULL;
-
- if (!(ev= Log_event::read_log_event(cache, 0, &init_fdle,
- opt_master_verify_checksum)) ||
- ev->get_type_code() != FORMAT_DESCRIPTION_EVENT)
- {
- if (ev)
- delete ev;
- return "Could not read format description log event while looking for "
- "GTID position in binlog";
- }
-
- fdle= static_cast<Format_description_log_event *>(ev);
-
- for (;;)
- {
- Log_event_type typ;
-
- ev= Log_event::read_log_event(cache, 0, fdle, opt_master_verify_checksum);
- if (!ev)
- {
- errormsg= "Could not read GTID list event while looking for GTID "
- "position in binlog";
- break;
- }
- typ= ev->get_type_code();
- if (typ == GTID_LIST_EVENT)
- break; /* Done, found it */
- if (typ == START_ENCRYPTION_EVENT)
- {
- if (fdle->start_decryption((Start_encryption_log_event*) ev))
- errormsg= "Could not set up decryption for binlog.";
- }
- delete ev;
- if (typ == ROTATE_EVENT || typ == STOP_EVENT ||
- typ == FORMAT_DESCRIPTION_EVENT || typ == START_ENCRYPTION_EVENT)
- continue; /* Continue looking */
-
- /* We did not find any Gtid_list_log_event, must be old binlog. */
- ev= NULL;
- break;
- }
-
- delete fdle;
- *out_gtid_list= static_cast<Gtid_list_log_event *>(ev);
- return errormsg;
-}
-
/*
Check if every GTID requested by the slave is contained in this (or a later)