1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367
|
/* Copyright (c) 2016, 2025, Oracle and/or its affiliates.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License, version 2.0,
as published by the Free Software Foundation.
This program is designed to work with certain software (including
but not limited to OpenSSL) that is licensed under separate terms,
as designated in a particular file or component or in included license
documentation. The authors of MySQL hereby grant you an additional
permission to link the program and your derivative works with the
separately licensed software that they have either included with
the program or referenced in the documentation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License, version 2.0, for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
#ifndef DEFINED_RPL_REPLICA_UNTIL_OPTIONS_H
#define DEFINED_RPL_REPLICA_UNTIL_OPTIONS_H
#include <sys/types.h>
#include <string>
#include "my_dbug.h"
#include "my_inttypes.h"
#include "my_io.h"
#include "sql/rpl_gtid.h"
class Log_event;
class Relay_log_info;
/**
@class Until_option
This is the abstract base class for slave start until options. It defines
the public interfaces called by slave coordinator.
This class publics three interfaces:
- is_satisfied_at_start_slave
It is called just when starting slave coordinator to check if the until
condition is already satisfied.
- is_satisfied_before_dispatching_event
It is called just after coordinator reads a events from relay log but
before it is applied or dispatched.
- is_satisfied_after_dispatching_event
It is called just after a event is applied or dispatched by the coordinator.
These three interfaces cover all until options's check requirements.
*/
class Until_option {
public:
virtual ~Until_option() = default;
/**
Check if the until option is already satisfied at coordinator starting.
@return bool
@retval true if it is satisfied.
@retval false if it is not satisfied.
*/
bool is_satisfied_at_start_slave() {
DBUG_TRACE;
bool ret = check_at_start_slave();
return ret;
}
/**
check if the until option is satisfied before applying or dispatching
a event.
@param[in] ev point to the event which will be applied or dispatched.
@return bool
@retval true if it is satisfied.
@retval false if it is not satisfied.
*/
bool is_satisfied_before_dispatching_event(const Log_event *ev) {
DBUG_TRACE;
bool ret = check_before_dispatching_event(ev);
return ret;
}
/**
check if the until option is satisfied after applied or dispatched
a event.
@return bool
@retval true if it is satisfied.
@retval false if it is not satisfied.
*/
bool is_satisfied_after_dispatching_event() {
DBUG_TRACE;
bool ret = check_after_dispatching_event();
return ret;
}
protected:
Relay_log_info *m_rli;
Until_option(Relay_log_info *rli) : m_rli(rli) {}
private:
/*
The virtual functions called by the interface functions.
They are implemented in sub-classes.
*/
virtual bool check_at_start_slave() = 0;
virtual bool check_before_dispatching_event(const Log_event *ev) = 0;
virtual bool check_after_dispatching_event() = 0;
};
/**
@class Until_position
It is an abstract class for until master position and until relay log
position. It ecapsulates the variables and functions shared by the two
sort of until options.
To avoid comparing log name in every call of interface functions. An
optimized comparing logic is implemented.
- Log name is just compared once for each master log and relay log.
- coodinator should notify Until_option object if master log or relay
log is switched by calling notify_log_name_change() function.
*/
class Until_position : public Until_option {
public:
~Until_position() override = default;
/**
Initialize the until position when starting the slave.
@param[in] log_name the log name in START SLAVE UNTIL option.
@param[in] log_pos the log position in START SLAVE UNTIL option.
@return int
@retval 0 if succeeds.
@retval a defined mysql error number if error happens.
*/
int init(const char *log_name, my_off_t log_pos);
/**
Coordinator calls this function to notify that master
log switch or relay log switch.
*/
void notify_log_name_change() {
DBUG_TRACE;
m_log_names_cmp_result = LOG_NAMES_CMP_UNKNOWN;
return;
}
const char *get_until_log_name() { return (const char *)m_until_log_name; }
my_off_t get_until_log_pos() { return m_until_log_pos; }
protected:
/**
Log name is compared only once for each master log or relay log. And
the comparison result is stored in m_log_names_cmp_result.
*/
enum {
LOG_NAMES_CMP_UNKNOWN = -2,
LOG_NAMES_CMP_LESS = -1,
LOG_NAMES_CMP_EQUAL = 0,
LOG_NAMES_CMP_GREATER = 1
} m_log_names_cmp_result;
Until_position(Relay_log_info *rli) : Until_option(rli) {}
/**
Check if until position is satisfied.
- If m_log_names_cmp_result is LOG_NAMES_CMP_UNKNOWN, then it first
compares log_name to m_until_log_name.
- If the comparison result is LOG_NAMES_CMP_LESS, it will return
false directly. If it is LOG_NAMES_CMP_EQUAL, it then compares
log_pos to m_until_log_pos.
- If the comparison result is LOG_NAMES_CMP_GREATER, it will
return true directly.
*/
bool check_position(const char *log_name, my_off_t log_pos);
private:
/* They store the log name and log position in START SLAVE UNTIL option */
char m_until_log_name[FN_REFLEN];
ulonglong m_until_log_pos;
/*
It stores the suffix number of m_until_log_name. Suffix number is compared
as a number but not a string. Otherwise it will cause trouble for the below
log names. master-bin.999999 and master-bin.1234567.
*/
ulong m_until_log_name_extension;
};
/**
@class Until_master_position
It is for UNTIL master_log_file and master_log_pos
*/
class Until_master_position : public Until_position {
public:
Until_master_position(Relay_log_info *rli) : Until_position(rli) {}
private:
/*
Current event's master log name and position. They are set in
is_satisfied_before_dispatching_event and checked in
is_satisfied_after_dispatching_event.
*/
char m_current_log_name[FN_REFLEN];
my_off_t m_current_log_pos;
bool check_at_start_slave() override;
bool check_before_dispatching_event(const Log_event *ev) override;
bool check_after_dispatching_event() override;
};
/**
@class Until_relay_position
It is for UNTIL relay_log_file and relay_log_pos
*/
class Until_relay_position : public Until_position {
public:
Until_relay_position(Relay_log_info *rli) : Until_position(rli) {}
private:
bool check_at_start_slave() override;
bool check_before_dispatching_event(const Log_event *ev) override;
bool check_after_dispatching_event() override;
};
/**
@class Until_gtids
It is an abstract class for UNTIL SQL_BEFORE_GTIDS and SQL_AFTER_GTIDS.
It encapsulates the variables and functions shared between the two options.
*/
class Until_gtids : public Until_option {
public:
~Until_gtids() override = default;
/**
Initialize the until gtids when starting the slave.
@param[in] gtid_set_str the gtid set in START SLAVE UNTIL option.
@return int
@retval 0 if succeeds.
@retval a defined mysql error number if error happens.
*/
int init(const char *gtid_set_str);
protected:
/**
Stores the gtids of START SLAVE UNTIL SQL_*_GTIDS.
Each time a gtid is about to be processed, we check if it is in the
set. Depending on until_condition, SQL thread is stopped before or
after applying the gtid.
*/
Gtid_set m_gtids;
Until_gtids(Relay_log_info *rli)
: Until_option(rli), m_gtids(global_sid_map) {}
};
/**
@class Until_before_gtids
It implements the logic of UNTIL SQL_BEFORE_GTIDS
*/
class Until_before_gtids : public Until_gtids {
public:
Until_before_gtids(Relay_log_info *rli) : Until_gtids(rli) {}
private:
bool check_at_start_slave() override;
bool check_before_dispatching_event(const Log_event *ev) override;
bool check_after_dispatching_event() override;
};
/**
@class Until_after_gtids
It implements the logic of UNTIL SQL_AFTER_GTIDS
*/
class Until_after_gtids : public Until_gtids {
public:
Until_after_gtids(Relay_log_info *rli) : Until_gtids(rli) {}
private:
bool check_at_start_slave() override;
bool check_before_dispatching_event(const Log_event *ev) override;
bool check_after_dispatching_event() override;
};
/**
@class Until_view_id
It implements the logic for UNTIL VIEW_ID.
*/
class Until_view_id : public Until_option {
public:
Until_view_id(Relay_log_info *rli)
: Until_option(rli),
until_view_id_found(false),
until_view_id_commit_found(false) {}
/**
Initialize the view_id when starting the slave.
@param[in] view_id the view_id in START SLAVE UNTIO option.
@return int
@retval 0 if succeeds.
@retval a defined mysql error number if error happens.
*/
int init(const char *view_id);
private:
std::string m_view_id;
/*
Flag used to indicate that view_id identified by 'until_view_id'
was found on the current UNTIL_SQL_VIEW_ID condition.
It is set to false on the beginning of the UNTIL_SQL_VIEW_ID
condition, and set to true when view_id is found.
*/
bool until_view_id_found;
/*
Flag used to indicate that commit event after view_id identified
by 'until_view_id' was found on the current UNTIL_SQL_VIEW_ID condition.
It is set to false on the beginning of the UNTIL_SQL_VIEW_ID
condition, and set to true when commit event after view_id is found.
*/
bool until_view_id_commit_found;
bool check_at_start_slave() override;
bool check_before_dispatching_event(const Log_event *ev) override;
bool check_after_dispatching_event() override;
};
/**
@class Until_mts_gap
It implements the logic of UNTIL SQL_AFTER_MTS_GAP
*/
class Until_mts_gap : public Until_option {
public:
Until_mts_gap(Relay_log_info *rli) : Until_option(rli) {}
/**
Initialize it when starting the slave.
*/
void init();
private:
bool check_at_start_slave() override;
bool check_before_dispatching_event(const Log_event *ev) override;
bool check_after_dispatching_event() override;
};
#endif // DEFINED_RPL_REPLICA_UNTIL_OPTIONS_H
|