mirror of
https://github.com/MariaDB/server.git
synced 2026-10-23 18:49:29 +03:00
Replaces std::function / std::optional / std::unordered_map /
std::unordered_set / std::string_view and template-heavy code in the
master.info / relay-log.info persistence layer with plain MariaDB
idioms.
- On-disk file format unchanged.
- SQL syntrax unchanged
- No notable test changes, except those for which new error messages was
added and output from SHOW VARIABLES.
- master_* CLI options moved from inline globals in
rpl_master_info_file.h to Sys_var_* in sys_vars.cc (READ_ONLY,
AUTO_SET on use_gtid and heartbeat_period). master_heartbeat_period
is Sys_var_double (seconds); master_use_gtid is Sys_var_enum. Global
storage sits outside HAVE_REPLICATION so libmariadbd links.
- This adds the rpl_master_info variables to SHOW VARIABLES
- Value classes are no longer templates. Persistent renamed to Value;
Optional_* classes renamed (Uint_value_with_default, Path_value,
etc.). has_value flag in the base; is_default()
non-virtual. Multi-line method bodies moved to new rpl_info_file.cc
and rpl_master_info_file.cc.
- VALUE_LIST (Mem_fn array) and VALUE_MAP (std::unordered_map)
replaced by per-instance Value *const value_list[] / value_map[]
arrays + a static TYPELIB populated at first construction from each
Value's variable_name. seen-set dedup is now a uint32 bitmask.
- Default handling is not anymore done with using special values.
Setting a value to default is now done by calling set_default(),
which sets the has_value member to 0 and stores the default value
in the variable.
When reading a value, one does not have to check if the value is
a default value.
This makes the interface cleaner and easier to manage.
- CHANGE MASTER TO parser no longer builds std::function lambdas:
LEX_MASTER_INFO carries mi_used_options / mi_used_default bitmasks
plus plain value fields; change_master() applies them via bit-test +
direct copy or set_default(). std::optional<T> and trilean are gone
from the value class API.
- Heartbeat_period_value::load_from uses my_strtod() instead of
my_decimal for the on-disk format. from_decimal kept for CHANGE
MASTER.
- RocksDB #if __cplusplus < 201703L guard at the top of
rpl_master_info_file.h dropped; header now compiles in C++11.
cstdint dropped; uint32_t / UINT32_MAX in touched code replaced by
MariaDB's uint32 / UINT_MAX32. include/my_global.h gains
INT_BUFFER_SIZE next to LONGLONG_BUFFER_SIZE.
- Pointer-style throughout (T * not T &). Multi-line inline functions
used in more than one place moved to .cc files per style.
New features:
- SHOW VARIABLES now shows the master default values.
- If there is an wrong value for a row in a master.info file the
corresponding variable name and the value is now written to the
error log.
Bug fixes uncovered by the refactor:
- master_ssl_verify_server_cert had a pre-existing inconsistency with
security implications: the documented default and the Sys_var_mybool
default are TRUE (validate the master's certificate), but the OLD
init_ssl_config() set the per-Master_info field to FALSE on RESET
SLAVE ALL. Concretely: after RESET SLAVE ALL followed by a bare
CHANGE MASTER TO (no explicit MASTER_SSL_VERIFY_SERVER_CERT), the
slave would connect with MASTER_SSL=1 enabled but with certificate
validation silently disabled.
Fixed by not resetting master_ssl_verify_server_cert in
RESET SLAVE ALL;
- As some replication setups sets master_ssl_verify_server_cert= 0
while other does not do that, the expected value used in
check-testcase.inc "Master_SSL_Verify_Server_Cert No" does not make
sense. The value of this variable is now ignored by
check-testcase.inc
- The old code would fail to read a master info file if there was a new
variable longer than 23 characters. This is now extended to 80.
- Removed warning on RESET SLAVE that "RESET SLAVE is implicitly changing"
the value of 'Using_Gtid' from 'No' to 'Slave_Pos'" as this change did
not really happen. This error was given if the master could support
GTID but the user had specified directly or indirectly to not use GTID.
Other things
- Size of mariadb (optimize build) shrunk with 1,408,009 bytes
(Based on 'dec' from the size command)
- Size of code in sql directory did not change notable.
- Reworked Master_use_gtid_value to remember users last choice and use
this as default when connecting to slave.
Replace mi->using_gtid, with was a pointer to master_use_gtid, with
two functions:
- using_gtid() returns the current mode, for the code that needs the
value itself (SHOW SLAVE STATUS and performance schema output,
comparisons against CURRENT_POS and SLAVE_POS).
- is_gtid_supported() tells whether the connection uses gtid at all.
The many callers that compared the mode against USE_GTID_NO with
== or != now call this function instead of testing the enum value.
- Master_use_gtid_value::supported() did the same test as
is_gtid_supported() and is removed
- Removed some operators in rpl_master_info_file.* that hid
that functions was used to read and update values.
Behavior changes:
- The last used value in CHANGE MASTER for MASTER_USE_GTID will be
remembered for future CHANGE MASTER for the same connection. This is
true even if RESET SLAVE is called.
- If Using git is not used with change master but log_file_name, pos,
relay_log_name or relay_log_pos is specified this is treated as
if Using_git=NO would have been given. (Old behavior, but not
documented).
--auto-master-use-gtid does nothing. The default value of
master_use_gtid is by default SlavePos that will automatically
change to NO if the master does not support GTID. This already
handles what auto-master-use-gtid tries to do.
- CHANGE MASTER's MASTER_HEARTBEAT_PERIOD now works like other MASTER
options: When set to a value, this value is kept until value is
changed or set to DEFAULT. The DEFAULT is
@global.master_heartbeat_period if this is set as startup, if not
then @global.slave_net_timeout/2 is used.
175 lines
6.3 KiB
C++
175 lines
6.3 KiB
C++
/*
|
|
Copyright (c) 2025 MariaDB
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; version 2 of the License.
|
|
|
|
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 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-1335 USA.
|
|
*/
|
|
|
|
#ifndef RPL_INFO_FILE_H
|
|
#define RPL_INFO_FILE_H
|
|
|
|
#include <my_sys.h> // IO_CACHE, FN_REFLEN, ...
|
|
|
|
|
|
/*
|
|
Read one '\n'-terminated decimal unsigned integer from file.
|
|
Returns false on success, true on EOF / parse error / out of range.
|
|
*/
|
|
bool uint_from_chars(IO_CACHE *file, ulonglong max_value, ulonglong *result);
|
|
|
|
/* Write an unsigned integer as decimal digits (no '\n'). */
|
|
void uint_to_chars(IO_CACHE *file, ulonglong value);
|
|
|
|
/*
|
|
Common superclass of Master_info_file and Relay_log_info_file. Provides
|
|
load and save code for their MySQL line-based sections. As only
|
|
Master_info_file has a MariaDB key=value section with a mix of explicit
|
|
and DEFAULT-able values, the code for those is in Master_info_file.
|
|
|
|
Each value is an instance of an implementation of the Info_file::Value
|
|
interface. The interface uses an explicit has_value flag (in the base)
|
|
to track whether the value was explicitly set, instead of per-class
|
|
sentinels. set_default() copies the default into value so reading the
|
|
value never needs to check is_default().
|
|
|
|
It's an old inconsistency that @ref Master_info_file's line count includes
|
|
the line-count "value" while @ref Relay_log_info_file's excludes it.
|
|
This is reason that Info_file::load_from_file() and
|
|
Info_file::save_to_file() defines the line-count lines differently -
|
|
It is so the two subclasses can implement either interpretation
|
|
on top of the indifferent common code in this superclass.
|
|
|
|
Multi-line method bodies live in rpl_info_file.cc.
|
|
*/
|
|
struct Info_file
|
|
{
|
|
IO_CACHE file;
|
|
|
|
/*
|
|
Persistence interface for an unspecified item.
|
|
|
|
has_value semantics:
|
|
true: the field holds an explicitly-set value (loaded from file
|
|
or assigned by code).
|
|
false: the field holds its DEFAULT (copied in by set_default()),
|
|
or has not been initialized.
|
|
*/
|
|
struct Value
|
|
{
|
|
virtual ~Value()= default;
|
|
Value(const char *name)
|
|
:variable_name(name)
|
|
{}
|
|
const char *variable_name;
|
|
bool has_value= false;
|
|
/* True if the value is the DEFAULT (i.e. has_value is false). */
|
|
bool is_default() const { return !has_value; }
|
|
/*
|
|
Copy the DEFAULT into the value field and clear has_value. Returns
|
|
true if no DEFAULT exists (i.e. the value is mandatory). Subclasses
|
|
with a DEFAULT override this to copy in their default and return
|
|
false. The return value is used only in
|
|
Master_info_file::load_from_file(), to detect a bare key=value line
|
|
whose value type has no DEFAULT (a malformed input).
|
|
*/
|
|
virtual bool set_default() { has_value= false; return true; }
|
|
/*
|
|
Set the value by reading a line from the IO and consuming the '\n'.
|
|
Sets has_value to true on success. Returns false on success,
|
|
true on error.
|
|
*/
|
|
virtual bool load_from(IO_CACHE *file)= 0;
|
|
/*
|
|
Write the value to the file without a '\n'.
|
|
This is only called in the case is_default() is false.
|
|
*/
|
|
virtual void save_to(IO_CACHE *file)= 0;
|
|
};
|
|
|
|
/* Unsigned 32-bit integer value (mandatory). */
|
|
struct Uint_value: Value
|
|
{
|
|
Uint_value(const char *name): Value(name) {}
|
|
uint value;
|
|
bool load_from(IO_CACHE *file) override;
|
|
void save_to(IO_CACHE *file) override;
|
|
};
|
|
|
|
/* Unsigned 64-bit integer value (mandatory). */
|
|
struct Ulonglong_value: Value
|
|
{
|
|
Ulonglong_value(const char *name): Value(name) {}
|
|
ulonglong value;
|
|
bool load_from(IO_CACHE *file) override;
|
|
void save_to(IO_CACHE *file) override;
|
|
};
|
|
|
|
/*
|
|
Null-terminated string value (mandatory). The buffer is owned by the
|
|
parent struct and passed in via the constructor.
|
|
*/
|
|
struct String_value: Value
|
|
{
|
|
char *buf;
|
|
size_t buf_size;
|
|
String_value(const char *name, char *buf, size_t size):
|
|
Value(name), buf(buf), buf_size(size) {}
|
|
bool load_from(IO_CACHE *file) override;
|
|
void save_to(IO_CACHE *file) override;
|
|
};
|
|
|
|
virtual ~Info_file()= default;
|
|
virtual bool load_from_file()= 0;
|
|
virtual void save_to_file()= 0;
|
|
|
|
protected:
|
|
|
|
/*
|
|
(Re)load the MySQL line-based section from the file.
|
|
|
|
@param values Array of pointers to value subobjects of *this. nullptr
|
|
marks a line to skip (MySQL-only fields MariaDB ignores).
|
|
The first element must be a String_value, to be
|
|
unambiguous with the line count line.
|
|
@param size Number of elements in values.
|
|
@param default_line_count
|
|
Some MySQL/MariaDB versions generate more lines than needed.
|
|
Starting with MySQL/MariaDB 4.1.x for Master_info_file and 5.6.x
|
|
for Relay_log_info_file, the first line is the number of value
|
|
lines, including the line count itself. This parameter specifies
|
|
the effective line count before those versions (where the first
|
|
line is a filename rather than an integer).
|
|
@return false on success, true on error.
|
|
*/
|
|
bool load_from_file(Value *const *values, size_t size,
|
|
size_t default_line_count= 0,
|
|
int value_counter_correction= 0);
|
|
|
|
/*
|
|
Flush the MySQL line-based section to the file.
|
|
|
|
@param values Array of pointers to value subobjects.
|
|
nullptr entries write an empty line.
|
|
@param size Number of elements in values.
|
|
@param total_line_count Number of lines to declare on the first line.
|
|
If larger than size, the file is padded with
|
|
empty lines. This reservation provides
|
|
compatibility with MySQL, which has added
|
|
more old-style lines.
|
|
*/
|
|
void save_to_file(Value *const *values, size_t size,
|
|
size_t total_line_count);
|
|
};
|
|
|
|
#endif
|