diff --git a/CMakeLists.txt b/CMakeLists.txt index a9d8887..7571045 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -256,6 +256,9 @@ set(source_files src/easymysql/library_fwd.hpp src/easymysql/library.hpp src/easymysql/library.cpp + + src/easymysql/replication_config_fwd.hpp + src/easymysql/replication_config.hpp ) add_executable(binlog_server ${source_files}) diff --git a/main_config.json b/main_config.json index 28d4452..abcd55a 100644 --- a/main_config.json +++ b/main_config.json @@ -12,6 +12,10 @@ "read_timeout": 60, "write_timeout": 60 }, + "replication": { + "server_id": 42, + "idle_time": 10 + }, "storage": { "uri": "file:///home/user/vault" } diff --git a/mtr/binlog_streaming/t/binsrv.test b/mtr/binlog_streaming/t/binsrv.test index 62ac0d4..c4a5172 100644 --- a/mtr/binlog_streaming/t/binsrv.test +++ b/mtr/binlog_streaming/t/binsrv.test @@ -110,6 +110,10 @@ eval SET @binsrv_config_json = JSON_OBJECT( 'read_timeout', 60, 'write_timeout', 60 ), + 'replication', JSON_OBJECT( + 'server_id', @@server_id + 1, + 'idle_time', 10 + ), 'storage', JSON_OBJECT( 'uri', @storage_uri ) diff --git a/src/app.cpp b/src/app.cpp index 1f46672..dd5a5cb 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -61,6 +61,36 @@ namespace { +void log_connection_config_info( + binsrv::basic_logger &logger, + const easymysql::connection_config &connection_config) { + std::string msg; + msg = "mysql connection string: "; + msg += connection_config.get_connection_string(); + logger.log(binsrv::log_severity::info, msg); + + msg = "mysql connect timeout (seconds): "; + msg += std::to_string(connection_config.get<"connect_timeout">()); + logger.log(binsrv::log_severity::info, msg); + + msg = "mysql read timeout (seconds): "; + msg += std::to_string(connection_config.get<"read_timeout">()); + logger.log(binsrv::log_severity::info, msg); + + msg = "mysql write timeout (seconds): "; + msg += std::to_string(connection_config.get<"write_timeout">()); + logger.log(binsrv::log_severity::info, msg); +} + +void log_replication_info( + binsrv::basic_logger &logger, + const easymysql::replication_config &replication_config) { + std::string msg; + msg = "mysql replication server id: "; + msg += std::to_string(replication_config.get<"server_id">()); + logger.log(binsrv::log_severity::info, msg); +} + void log_storage_info(binsrv::basic_logger &logger, const binsrv::storage &storage) { std::string msg{}; @@ -324,7 +354,9 @@ int main(int argc, char *argv[]) { std::cerr << "usage: " << executable_name << " (fetch|pull))" << " " " " - " " + " " + "" + " " " \n" << " " << executable_name << " (fetch|pull)) \n"; @@ -346,24 +378,22 @@ int main(int argc, char *argv[]) { logger->log(binsrv::log_severity::delimiter, util::get_readable_command_line_arguments(cmd_args)); - if (operation_mode == binsrv::operation_mode_type::fetch) { - logger->log(binsrv::log_severity::delimiter, - "'fetch' operation mode specified"); - } else if (operation_mode == binsrv::operation_mode_type::pull) { - logger->log(binsrv::log_severity::delimiter, - "'pull' operation mode specified"); - } else { - assert(false); - } + assert(operation_mode == binsrv::operation_mode_type::fetch || + operation_mode == binsrv::operation_mode_type::pull); + std::string msg; + msg = '\''; + msg += boost::lexical_cast(operation_mode); + msg += "' operation mode specified"; + logger->log(binsrv::log_severity::delimiter, msg); binsrv::main_config_ptr config; if (number_of_cmd_args == 3U) { logger->log(binsrv::log_severity::delimiter, - "reading connection configuration from the JSON file."); + "reading configuration from the JSON file."); config = std::make_shared(cmd_args[2]); } else if (number_of_cmd_args == binsrv::main_config::flattened_size + 2U) { logger->log(binsrv::log_severity::delimiter, - "reading connection configuration from the command line " + "reading configuration from the command line " "arguments."); config = std::make_shared(cmd_args.subspan(2U)); } else { @@ -388,12 +418,10 @@ int main(int argc, char *argv[]) { "logging level set to \""s + std::string{log_level_label} + '"'); - std::string msg; const auto &storage_config = config->root().get<"storage">(); auto storage_backend{ binsrv::storage_backend_factory::create(storage_config)}; - logger->log(binsrv::log_severity::info, "created binlog storage backend"); - msg = "description: "; + msg = "created binlog storage backend: "; msg += storage_backend->get_description(); logger->log(binsrv::log_severity::info, msg); @@ -404,16 +432,13 @@ int main(int argc, char *argv[]) { log_storage_info(*logger, storage); const auto &connection_config = config->root().get<"connection">(); - logger->log(binsrv::log_severity::info, - "mysql connection string: " + - connection_config.get_connection_string()); + log_connection_config_info(*logger, connection_config); - // TODO: put these parameters into configuration - static constexpr std::uint32_t default_server_id{42U}; - static constexpr std::uint32_t default_idle_time_seconds{5U}; + const auto &replication_config = config->root().get<"replication">(); + log_replication_info(*logger, replication_config); - const auto server_id{default_server_id}; - const auto idle_time_seconds{default_idle_time_seconds}; + const auto server_id{replication_config.get<"server_id">()}; + const auto idle_time_seconds{replication_config.get<"idle_time">()}; const easymysql::library mysql_lib; logger->log(binsrv::log_severity::info, "initialized mysql client library"); @@ -428,9 +453,13 @@ int main(int argc, char *argv[]) { while (true) { std::this_thread::sleep_for(std::chrono::seconds(idle_time_seconds)); - logger->log(binsrv::log_severity::info, - "awoke after sleep and trying to reconnect (" + - std::to_string(iteration_number) + ")"); + msg = "awoke after sleeping for "; + msg += std::to_string(idle_time_seconds); + msg += " seconds and trying to reconnect (iteration "; + msg += std::to_string(iteration_number); + msg += ')'; + logger->log(binsrv::log_severity::info, msg); + receive_binlog_events(operation_mode, *logger, mysql_lib, connection_config, server_id, storage); ++iteration_number; diff --git a/src/binsrv/main_config.hpp b/src/binsrv/main_config.hpp index e8d924d..faf4dd2 100644 --- a/src/binsrv/main_config.hpp +++ b/src/binsrv/main_config.hpp @@ -21,7 +21,8 @@ #include "binsrv/logger_config.hpp" // IWYU pragma: export #include "binsrv/storage_config.hpp" // IWYU pragma: export -#include "easymysql/connection_config.hpp" // IWYU pragma: export +#include "easymysql/connection_config.hpp" // IWYU pragma: export +#include "easymysql/replication_config.hpp" // IWYU pragma: export #include "util/command_line_helpers_fwd.hpp" #include "util/nv_tuple.hpp" @@ -32,9 +33,10 @@ class [[nodiscard]] main_config { private: using impl_type = util::nv_tuple< // clang-format off - util::nv<"logger" , logger_config>, - util::nv<"connection", easymysql::connection_config>, - util::nv<"storage" , storage_config> + util::nv<"logger" , logger_config>, + util::nv<"connection" , easymysql::connection_config>, + util::nv<"replication", easymysql::replication_config>, + util::nv<"storage" , storage_config> // clang-format on >; diff --git a/src/easymysql/replication_config.hpp b/src/easymysql/replication_config.hpp new file mode 100644 index 0000000..d20ea3a --- /dev/null +++ b/src/easymysql/replication_config.hpp @@ -0,0 +1,37 @@ +// Copyright (c) 2023-2024 Percona 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 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 EASYMYSQL_REPLICATION_CONFIG_HPP +#define EASYMYSQL_REPLICATION_CONFIG_HPP + +#include "easymysql/replication_config_fwd.hpp" // IWYU pragma: export + +#include + +#include "util/nv_tuple.hpp" + +namespace easymysql { + +struct [[nodiscard]] replication_config + : util::nv_tuple< + // clang-format off + util::nv<"server_id", std::uint32_t>, + util::nv<"idle_time", std::uint32_t> + // clang-format on + > {}; + +} // namespace easymysql + +#endif // EASYMYSQL_REPLICATION_CONFIG_HPP diff --git a/src/easymysql/replication_config_fwd.hpp b/src/easymysql/replication_config_fwd.hpp new file mode 100644 index 0000000..b25aa81 --- /dev/null +++ b/src/easymysql/replication_config_fwd.hpp @@ -0,0 +1,25 @@ +// Copyright (c) 2023-2024 Percona 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 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 EASYMYSQL_REPLICATION_CONFIG_FWD_HPP +#define EASYMYSQL_REPLICATION_CONFIG_FWD_HPP + +namespace easymysql { + +struct replication_config; + +} // namespace easymysql + +#endif // EASYMYSQL_REPLICATION_CONFIG_FWD_HPP