Skip to content

Commit a00b9da

Browse files
PS-10244 feature: Add configuration options for specifying GTID-based / position-based replication mode
https://perconadev.atlassian.net/browse/PS-10244 'replication' section of the main configuration file extended with one more required string 'mode' configuration parameter, which can be either 'position' or 'gtid'. At this moment only 'position' is supported. 'replication_config' class moved from the 'easymysql' namespace to 'binsrv'. Added 'binbsrv::storage_metadata' class that is intended to keep persistent info for binlog storages. Currently it has only one attribute 'mode' (either 'position' or 'gtid') that indicates in which replication mode this storage was created. This metadata is stored in the storage folder (along with binlog index and binlog data files) under the 'metadata.json' name. In addition, for forward compatibility, this metadata file also includes the 'version' parameter that currently is alwas set to / expected to be '1'. 'binsrv::storage' constructor extended with additional logic to read / write and validate the content of the metadata file. Similarly to 'util/nv_tuple_from_json.hpp' file that reads from JSON to 'util::nv_tuple', added 'util/nv_tuple_to_json.hpp' that writes data from 'util::nv_tuple' to JSON. Main application now prints to the log file replication mode from the configuration file along with the one extracted from the storage metadata. Re-factored the way how classes report their string-convertibility: now each class interested in specializing 'util::is_string_convertable' template does this in its own header. In order to minimize dependencies, 'util::is_string_convertable' definition extracted into separate header 'util/nv_tuple_json_support.hpp'. We no longer use 'boost::json' as a header only library (by including 'boost/json/src.hpp'). Instead, we now use 'libboost_json.a' static library. Updated 'set_up_binsrv_environment.inc' MTR include file - we now explicitly set '<replication.mode>' to 'position' in the generated configuration file. 'main_config.json' sample configuration file updated with new '<replication.mode>' parameter. Updated 'README.md' with the '<replication.mode>' parameter description.
1 parent 3c9124f commit a00b9da

29 files changed

Lines changed: 572 additions & 82 deletions

CMakeLists.txt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ if(WITH_ASAN)
7272
target_link_options(binlog_server_compiler_flags INTERFACE "-fsanitize=address")
7373
endif()
7474

75-
find_package(Boost 1.88.0 EXACT REQUIRED COMPONENTS url)
75+
find_package(Boost 1.88.0 EXACT REQUIRED COMPONENTS url json)
7676

7777
find_package(MySQL REQUIRED)
7878

@@ -252,6 +252,12 @@ set(source_files
252252
src/binsrv/operation_mode_type_fwd.hpp
253253
src/binsrv/operation_mode_type.hpp
254254

255+
src/binsrv/replication_config_fwd.hpp
256+
src/binsrv/replication_config.hpp
257+
258+
src/binsrv/replication_mode_type_fwd.hpp
259+
src/binsrv/replication_mode_type.hpp
260+
255261
src/binsrv/size_unit_fwd.hpp
256262
src/binsrv/size_unit.hpp
257263
src/binsrv/size_unit.cpp
@@ -277,6 +283,10 @@ set(source_files
277283
src/binsrv/storage_config_fwd.hpp
278284
src/binsrv/storage_config.hpp
279285

286+
src/binsrv/storage_metadata_fwd.hpp
287+
src/binsrv/storage_metadata.hpp
288+
src/binsrv/storage_metadata.cpp
289+
280290
src/binsrv/time_unit_fwd.hpp
281291
src/binsrv/time_unit.hpp
282292
src/binsrv/time_unit.cpp
@@ -316,7 +326,9 @@ set(source_files
316326

317327
src/util/nv_tuple_fwd.hpp
318328
src/util/nv_tuple.hpp
329+
src/util/nv_tuple_json_support.hpp
319330
src/util/nv_tuple_from_json.hpp
331+
src/util/nv_tuple_to_json.hpp
320332

321333
src/util/redirectable.hpp
322334

@@ -343,9 +355,6 @@ set(source_files
343355
src/easymysql/library.hpp
344356
src/easymysql/library.cpp
345357

346-
src/easymysql/replication_config_fwd.hpp
347-
src/easymysql/replication_config.hpp
348-
349358
src/easymysql/ssl_config_fwd.hpp
350359
src/easymysql/ssl_config.hpp
351360

@@ -360,7 +369,7 @@ add_executable(binlog_server ${source_files})
360369
target_link_libraries(binlog_server
361370
PRIVATE
362371
binlog_server_compiler_flags
363-
Boost::headers Boost::url
372+
Boost::headers Boost::json Boost::url
364373
ZLIB::ZLIB
365374
MySQL::client
366375
aws-cpp-sdk-s3-crt

README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,8 @@ The Percona Binary Log Server configuration file has the following format.
217217
"replication": {
218218
"server_id": 42,
219219
"idle_time": 10,
220-
"verify_checksum": true
220+
"verify_checksum": true,
221+
"mode": "position"
221222
},
222223
"storage": {
223224
"backend": "s3",
@@ -271,6 +272,7 @@ Currently we use the following mapping:
271272
- `<replication.server_id>` - specifies the server ID that the utility will be using when connecting to a remote MySQL server (similar to [--connection-server-id](https://dev.mysql.com/doc/refman/8.0/en/mysqlbinlog.html#option_mysqlbinlog_connection-server-id) `mysqlbinlog` command line option).
272273
- `<replication.idle_time>` - the number of seconds the utility will spend in disconnected mode between reconnection attempts.
273274
- `<replication.verify_checksum>` - a boolean value which specifies whether the utility should verify event checksums.
275+
- `<replication.mode>` - the replication mode, can be either `position` for position-based replication or `gtid` for GTID-based replication.
274276

275277
#### \<storage\> section
276278
- `<storage.backend>` - the type of the storage where the received binary logs should be stored:

main_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
"replication": {
3030
"server_id": 42,
3131
"idle_time": 10,
32-
"verify_checksum": true
32+
"verify_checksum": true,
33+
"mode": "position"
3334
},
3435
"storage": {
3536
"backend": "file",

mtr/binlog_streaming/include/set_up_binsrv_environment.inc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,8 @@ eval SET @binsrv_config_json = JSON_OBJECT(
8181
'replication', JSON_OBJECT(
8282
'server_id', @@server_id + 1,
8383
'idle_time', $binsrv_idle_time,
84-
'verify_checksum', $binsrv_verify_checksum
84+
'verify_checksum', $binsrv_verify_checksum,
85+
'mode', 'position'
8586
),
8687
'storage', JSON_OBJECT(
8788
'backend', '$storage_backend',

src/app.cpp

Lines changed: 25 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
#include "binsrv/logger_factory.hpp"
4545
#include "binsrv/main_config.hpp"
4646
#include "binsrv/operation_mode_type.hpp"
47+
#include "binsrv/replication_mode_type.hpp"
4748
#include "binsrv/size_unit.hpp"
4849
#include "binsrv/storage.hpp"
4950
// needed for storage_backend_type's operator <<
@@ -194,14 +195,16 @@ void log_connection_config_info(
194195

195196
void log_replication_config_info(
196197
binsrv::basic_logger &logger,
197-
const easymysql::replication_config &replication_config) {
198+
const binsrv::replication_config &replication_config) {
198199

199200
log_config_param<"server_id">(logger, replication_config,
200201
"mysql replication server id");
201202
log_config_param<"idle_time">(logger, replication_config,
202203
"mysql replication idle time (seconds)");
203204
log_config_param<"verify_checksum">(
204205
logger, replication_config, "mysql replication checksum verification");
206+
log_config_param<"mode">(logger, replication_config,
207+
"mysql replication mode");
205208
}
206209

207210
void log_storage_config_info(binsrv::basic_logger &logger,
@@ -225,6 +228,12 @@ void log_storage_info(binsrv::basic_logger &logger,
225228
msg += storage.get_backend_description();
226229
logger.log(binsrv::log_severity::info, msg);
227230

231+
msg.clear();
232+
msg = "binlog storage initialized in ";
233+
msg += boost::lexical_cast<std::string>(storage.get_replication_mode());
234+
msg += " mode";
235+
logger.log(binsrv::log_severity::info, msg);
236+
228237
msg.clear();
229238
if (storage.has_current_binlog_name()) {
230239
msg = "binlog storage initialized at \"";
@@ -375,7 +384,8 @@ void receive_binlog_events(
375384
const volatile std::atomic_flag &termination_flag,
376385
binsrv::basic_logger &logger, const easymysql::library &mysql_lib,
377386
const easymysql::connection_config &connection_config,
378-
std::uint32_t server_id, bool verify_checksum, binsrv::storage &storage) {
387+
std::uint32_t server_id, bool verify_checksum,
388+
binsrv::replication_mode_type replication_mode, binsrv::storage &storage) {
379389
easymysql::connection connection{};
380390
try {
381391
connection = mysql_lib.create_connection(connection_config);
@@ -406,9 +416,10 @@ void receive_binlog_events(
406416
: easymysql::connection_replication_mode_type::blocking};
407417

408418
try {
409-
connection.switch_to_replication(server_id, current_binlog_name,
410-
current_binlog_position, verify_checksum,
411-
blocking_mode);
419+
connection.switch_to_replication(
420+
server_id, current_binlog_name, current_binlog_position,
421+
verify_checksum,
422+
replication_mode == binsrv::replication_mode_type::gtid, blocking_mode);
412423
} catch (const easymysql::core_error &) {
413424
if (operation_mode == binsrv::operation_mode_type::fetch) {
414425
throw;
@@ -419,7 +430,8 @@ void receive_binlog_events(
419430

420431
logger.log(binsrv::log_severity::info,
421432
std::string{"switched to replication (checksum "} +
422-
(verify_checksum ? "enabled" : "disabled") + ")");
433+
(verify_checksum ? "enabled" : "disabled") + ", " +
434+
boost::lexical_cast<std::string>(replication_mode) + "mode)");
423435

424436
log_replication_info(logger, server_id, current_binlog_name,
425437
current_binlog_position, blocking_mode);
@@ -431,7 +443,7 @@ void receive_binlog_events(
431443
util::const_byte_span portion;
432444

433445
binsrv::event::reader_context context{connection.get_server_version(),
434-
verify_checksum};
446+
verify_checksum, replication_mode};
435447

436448
// if binlog is still open, there is no sense to close it and re-open
437449
// instead, we will just instruct this loop to process the
@@ -605,9 +617,6 @@ int main(int argc, char *argv[]) {
605617
const auto &storage_config = config->root().get<"storage">();
606618
log_storage_config_info(*logger, storage_config);
607619

608-
binsrv::storage storage{storage_config};
609-
log_storage_info(*logger, storage);
610-
611620
const auto &connection_config = config->root().get<"connection">();
612621
log_connection_config_info(*logger, connection_config);
613622

@@ -617,6 +626,10 @@ int main(int argc, char *argv[]) {
617626
const auto server_id{replication_config.get<"server_id">()};
618627
const auto idle_time_seconds{replication_config.get<"idle_time">()};
619628
const auto verify_checksum{replication_config.get<"verify_checksum">()};
629+
const auto replication_mode{replication_config.get<"mode">()};
630+
631+
binsrv::storage storage{storage_config, replication_mode};
632+
log_storage_info(*logger, storage);
620633

621634
const easymysql::library mysql_lib;
622635
logger->log(binsrv::log_severity::info, "initialized mysql client library");
@@ -625,7 +638,7 @@ int main(int argc, char *argv[]) {
625638

626639
receive_binlog_events(operation_mode, termination_flag, *logger, mysql_lib,
627640
connection_config, server_id, verify_checksum,
628-
storage);
641+
replication_mode, storage);
629642

630643
if (operation_mode == binsrv::operation_mode_type::pull) {
631644
std::size_t iteration_number{1U};
@@ -646,7 +659,7 @@ int main(int argc, char *argv[]) {
646659

647660
receive_binlog_events(operation_mode, termination_flag, *logger,
648661
mysql_lib, connection_config, server_id,
649-
verify_checksum, storage);
662+
verify_checksum, replication_mode, storage);
650663
++iteration_number;
651664
}
652665
}

src/binsrv/event/reader_context.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
#include <stdexcept>
2323
#include <utility>
2424

25+
#include "binsrv/replication_mode_type_fwd.hpp"
26+
2527
#include "binsrv/event/code_type.hpp"
2628
#include "binsrv/event/common_header_flag_type.hpp"
2729
#include "binsrv/event/event.hpp"
@@ -33,9 +35,10 @@
3335
namespace binsrv::event {
3436

3537
reader_context::reader_context(std::uint32_t encoded_server_version,
36-
bool verify_checksum)
38+
bool verify_checksum,
39+
replication_mode_type replication_mode)
3740
: encoded_server_version_{encoded_server_version},
38-
verify_checksum_{verify_checksum},
41+
verify_checksum_{verify_checksum}, replication_mode_{replication_mode},
3942
post_header_lengths_{
4043
get_hardcoded_post_header_lengths(encoded_server_version_)} {}
4144

src/binsrv/event/reader_context.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include <cstdint>
2222

23+
#include "binsrv/replication_mode_type_fwd.hpp"
24+
2325
#include "binsrv/event/common_header_fwd.hpp"
2426
#include "binsrv/event/event_fwd.hpp"
2527
#include "binsrv/event/protocol_traits.hpp"
@@ -30,7 +32,8 @@ class [[nodiscard]] reader_context {
3032
friend class event;
3133

3234
public:
33-
reader_context(std::uint32_t encoded_server_version, bool verify_checksum);
35+
reader_context(std::uint32_t encoded_server_version, bool verify_checksum,
36+
replication_mode_type replication_mode);
3437

3538
[[nodiscard]] std::uint32_t
3639
get_current_encoded_server_version() const noexcept {
@@ -57,6 +60,7 @@ class [[nodiscard]] reader_context {
5760
state_type state_{state_type::initial};
5861
std::uint32_t encoded_server_version_;
5962
bool verify_checksum_;
63+
replication_mode_type replication_mode_;
6064
post_header_length_container post_header_lengths_{};
6165
std::uint32_t position_{0U};
6266

src/binsrv/log_severity_fwd.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include <cstdint>
2121
#include <iosfwd>
2222

23+
#include "util/nv_tuple_json_support.hpp"
24+
2325
namespace binsrv {
2426

2527
enum class log_severity : std::uint8_t;
@@ -36,4 +38,7 @@ operator>>(std::basic_istream<Char, Traits> &input, log_severity &level);
3638

3739
} // namespace binsrv
3840

41+
template <>
42+
struct util::is_string_convertable<binsrv::log_severity> : std::true_type {};
43+
3944
#endif // BINSRV_LOG_SEVERITY_FWD_HPP

src/binsrv/main_config.cpp

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,41 +22,21 @@
2222
#include <stdexcept>
2323
#include <string>
2424
#include <string_view>
25-
#include <type_traits>
2625

2726
#include <boost/json/parse.hpp>
28-
#include <boost/json/src.hpp> // IWYU pragma: keep
2927

3028
// Needed for log_severity's operator <<
3129
#include "binsrv/log_severity.hpp" // IWYU pragma: keep
32-
#include "binsrv/size_unit_fwd.hpp"
30+
// Needed for replication_mode_type's operator <<
31+
#include "binsrv/replication_mode_type.hpp" // IWYU pragma: keep
3332
// Needed for storage_backend_type's operator <<
3433
#include "binsrv/storage_backend_type.hpp" // IWYU pragma: keep
35-
#include "binsrv/time_unit_fwd.hpp"
3634

3735
// Needed for ssl_mode_type's operator <<
3836
#include "easymysql/ssl_mode_type.hpp" // IWYU pragma: keep
3937

4038
#include "util/exception_location_helpers.hpp"
4139
#include "util/nv_tuple_from_json.hpp"
42-
#include "util/nv_tuple_fwd.hpp"
43-
44-
// As this file is the only place where we call util::nv_tuple_from_json(),
45-
// which in turns calls tag_invoke() from the boost::json, we give the
46-
// serialization/unserialization hints for this library here (instead of
47-
// polluting each individual class definition).
48-
template <>
49-
struct util::is_string_convertable<binsrv::size_unit> : std::true_type {};
50-
template <>
51-
struct util::is_string_convertable<binsrv::time_unit> : std::true_type {};
52-
template <>
53-
struct util::is_string_convertable<binsrv::log_severity> : std::true_type {};
54-
template <>
55-
struct util::is_string_convertable<binsrv::storage_backend_type>
56-
: std::true_type {};
57-
template <>
58-
struct util::is_string_convertable<easymysql::ssl_mode_type> : std::true_type {
59-
};
6040

6141
namespace binsrv {
6242

src/binsrv/main_config.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@
1919
#include "binsrv/main_config_fwd.hpp" // IWYU pragma: export
2020

2121
#include "binsrv/logger_config.hpp" // IWYU pragma: export
22+
#include "binsrv/replication_config.hpp" // IWYU pragma: export
2223
#include "binsrv/storage_config.hpp" // IWYU pragma: export
2324

24-
#include "easymysql/connection_config.hpp" // IWYU pragma: export
25-
#include "easymysql/replication_config.hpp" // IWYU pragma: export
25+
#include "easymysql/connection_config.hpp" // IWYU pragma: export
2626

2727
#include "util/nv_tuple.hpp"
2828

@@ -34,7 +34,7 @@ class [[nodiscard]] main_config {
3434
// clang-format off
3535
util::nv<"logger" , logger_config>,
3636
util::nv<"connection" , easymysql::connection_config>,
37-
util::nv<"replication", easymysql::replication_config>,
37+
util::nv<"replication", binsrv::replication_config>,
3838
util::nv<"storage" , storage_config>
3939
// clang-format on
4040
>;

0 commit comments

Comments
 (0)