Skip to content

Commit 3c9124f

Browse files
PS-10242 feature: Add support for processing PREVIOUS_GTIDS_LOG events (#78)
https://perconadev.atlassian.net/browse/PS-10242 Added new template specializations for 'generic_post_header_impl' and 'generic_body_impl' for 'code_type::previous_gtids_log' ('PREVIOUS_GTIDS_LOG' event). 'binsrv::gtids::gtid_set' class is now capable of deserializing binary data from the blob encoded into the 'PREVIOUS_GTIDS_LOG' event. Introduced 'binsrv::gtids::gtid_set_storage' typedef - a vector-like container with 96 bytes SBO (based on 'boost::container::small_vector'). This type is used to store the blob mentioned above. The number 96 is chosen so that the size of the 'binsrv::event::event::body_variant' wouldnt grow. 'binsrv::gtids::gtid_set' interface extended with additional method 'add_interval()' for adding gno ranges. Fixed the way how 'binsrv::gtids::gtid_set' is printed to std::ostream - it now corresponds to the format used by '@@gtid_executed' MySQL system variable. Introduced new class 'binsrv::gtids::uuid' as a wrapper around 'boost::uuids::uuid' that can be constructed from 'binsrv::gtids::uuid_storage'. Unit tests updated to cover new methods in 'binsrv::gtids::gtid_set'. Added new 'test_uuid' unit test.
1 parent 86fb949 commit 3c9124f

29 files changed

Lines changed: 864 additions & 105 deletions

CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,13 @@ set(source_files
159159
src/binsrv/event/gtid_tagged_log_post_header_impl_fwd.hpp
160160
src/binsrv/event/gtid_tagged_log_post_header_impl.hpp
161161

162+
src/binsrv/event/previous_gtids_log_body_impl_fwd.hpp
163+
src/binsrv/event/previous_gtids_log_body_impl.hpp
164+
src/binsrv/event/previous_gtids_log_body_impl.cpp
165+
166+
src/binsrv/event/previous_gtids_log_post_header_impl_fwd.hpp
167+
src/binsrv/event/previous_gtids_log_post_header_impl.hpp
168+
162169
src/binsrv/event/protocol_traits_fwd.hpp
163170
src/binsrv/event/protocol_traits.hpp
164171
src/binsrv/event/protocol_traits.cpp
@@ -191,16 +198,23 @@ set(source_files
191198

192199
# gtid data structure files
193200
src/binsrv/gtids/common_types.hpp
201+
194202
src/binsrv/gtids/gtid_fwd.hpp
195203
src/binsrv/gtids/gtid.hpp
196204
src/binsrv/gtids/gtid.cpp
205+
197206
src/binsrv/gtids/gtid_set_fwd.hpp
198207
src/binsrv/gtids/gtid_set.hpp
199208
src/binsrv/gtids/gtid_set.cpp
209+
200210
src/binsrv/gtids/tag_fwd.hpp
201211
src/binsrv/gtids/tag.hpp
202212
src/binsrv/gtids/tag.cpp
203213

214+
src/binsrv/gtids/uuid_fwd.hpp
215+
src/binsrv/gtids/uuid.hpp
216+
src/binsrv/gtids/uuid.cpp
217+
204218
# binlog files
205219
src/binsrv/basic_logger_fwd.hpp
206220
src/binsrv/basic_logger.hpp

src/binsrv/event/event.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@
4444
#include "binsrv/event/gtid_log_post_header_impl.hpp" // IWYU pragma: export
4545
#include "binsrv/event/gtid_tagged_log_body_impl.hpp" // IWYU pragma: export
4646
#include "binsrv/event/gtid_tagged_log_post_header_impl.hpp" // IWYU pragma: export
47+
#include "binsrv/event/previous_gtids_log_body_impl.hpp" // IWYU pragma: export
48+
#include "binsrv/event/previous_gtids_log_post_header_impl.hpp" // IWYU pragma: export
4749
#include "binsrv/event/reader_context_fwd.hpp"
4850
#include "binsrv/event/rotate_body_impl.hpp" // IWYU pragma: export
4951
#include "binsrv/event/rotate_post_header_impl.hpp" // IWYU pragma: export

src/binsrv/event/format_description_post_header_impl.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
#include "binsrv/event/protocol_traits.hpp"
2929

30-
#include "util/bounded_string_storage_fwd.hpp"
30+
#include "util/bounded_string_storage.hpp"
3131
#include "util/byte_span_fwd.hpp"
3232

3333
namespace binsrv::event {

src/binsrv/event/gtid_log_post_header.cpp

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,19 @@
1515

1616
#include "binsrv/event/gtid_log_post_header.hpp"
1717

18-
#include <algorithm>
1918
#include <cstdint>
2019
#include <iterator>
2120
#include <ostream>
2221
#include <stdexcept>
2322
#include <string>
24-
#include <tuple>
2523

26-
#include <boost/align/align_up.hpp>
24+
#include <boost/lexical_cast.hpp>
2725

28-
#include <boost/uuid/uuid.hpp>
29-
#include <boost/uuid/uuid_io.hpp>
26+
#include <boost/align/align_up.hpp>
3027

3128
#include "binsrv/event/gtid_log_flag_type.hpp"
3229

33-
#include "binsrv/gtids/common_types.hpp"
30+
#include "binsrv/gtids/uuid.hpp"
3431

3532
#include "util/byte_span.hpp"
3633
#include "util/byte_span_extractors.hpp"
@@ -128,19 +125,11 @@ gtid_log_post_header::get_flags() const noexcept {
128125
}
129126

130127
[[nodiscard]] gtids::uuid gtid_log_post_header::get_uuid() const noexcept {
131-
gtids::uuid result;
132-
const auto &uuid_raw{get_uuid_raw()};
133-
static_assert(std::tuple_size_v<decltype(uuid_)> ==
134-
boost::uuids::uuid::static_size());
135-
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
136-
std::copy_n(reinterpret_cast<const boost::uuids::uuid::value_type *>(
137-
std::data(uuid_raw)),
138-
boost::uuids::uuid::static_size(), std::begin(result));
139-
return result;
128+
return gtids::uuid{get_uuid_raw()};
140129
}
141130

142131
[[nodiscard]] std::string gtid_log_post_header::get_readable_uuid() const {
143-
return boost::uuids::to_string(get_uuid());
132+
return boost::lexical_cast<std::string>(get_uuid());
144133
}
145134

146135
std::ostream &operator<<(std::ostream &output,

src/binsrv/event/gtid_log_post_header.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "binsrv/event/gtid_log_flag_type_fwd.hpp"
2525

2626
#include "binsrv/gtids/common_types.hpp"
27+
#include "binsrv/gtids/uuid.hpp"
2728

2829
#include "util/byte_span_fwd.hpp"
2930

src/binsrv/event/gtid_tagged_log_body_impl.cpp

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515

1616
#include "binsrv/event/gtid_tagged_log_body_impl.hpp"
1717

18-
#include <algorithm>
1918
#include <cassert>
2019
#include <cstddef>
2120
#include <cstdint>
@@ -27,20 +26,19 @@
2726
#include <stdexcept>
2827
#include <string>
2928
#include <string_view>
30-
#include <tuple>
29+
30+
#include <boost/lexical_cast.hpp>
3131

3232
#include <boost/align/align_up.hpp>
33+
3334
#include <boost/date_time/posix_time/conversion.hpp>
3435
#include <boost/date_time/posix_time/ptime.hpp>
3536
#include <boost/date_time/posix_time/time_formatters_limited.hpp>
3637

37-
#include <boost/uuid/uuid.hpp>
38-
#include <boost/uuid/uuid_io.hpp>
39-
4038
#include "binsrv/event/code_type.hpp"
4139
#include "binsrv/event/gtid_log_flag_type.hpp"
4240

43-
#include "binsrv/gtids/common_types.hpp"
41+
#include "binsrv/gtids/uuid.hpp"
4442

4543
#include "util/bounded_string_storage.hpp"
4644
#include "util/byte_span.hpp"
@@ -154,20 +152,12 @@ generic_body_impl<code_type::gtid_tagged_log>::get_readable_flags() const {
154152

155153
[[nodiscard]] gtids::uuid
156154
generic_body_impl<code_type::gtid_tagged_log>::get_uuid() const noexcept {
157-
gtids::uuid result;
158-
const auto &uuid_raw{get_uuid_raw()};
159-
static_assert(std::tuple_size_v<decltype(uuid_)> ==
160-
boost::uuids::uuid::static_size());
161-
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
162-
std::copy_n(reinterpret_cast<const boost::uuids::uuid::value_type *>(
163-
std::data(uuid_raw)),
164-
boost::uuids::uuid::static_size(), std::begin(result));
165-
return result;
155+
return gtids::uuid{get_uuid_raw()};
166156
}
167157

168158
[[nodiscard]] std::string
169159
generic_body_impl<code_type::gtid_tagged_log>::get_readable_uuid() const {
170-
return boost::uuids::to_string(get_uuid());
160+
return boost::lexical_cast<std::string>(get_uuid());
171161
}
172162

173163
[[nodiscard]] std::string_view
@@ -298,8 +288,7 @@ void generic_body_impl<code_type::gtid_tagged_log>::process_field_data(
298288
std::size_t extracted_tag_length{};
299289
varlen_int_extractor(remainder, extracted_tag_length, "tag length");
300290
tag_.resize(extracted_tag_length);
301-
const std::span<gtids::tag_storage::value_type> tag_subrange{
302-
std::data(tag_), extracted_tag_length};
291+
const std::span<gtids::tag_storage::value_type> tag_subrange{tag_};
303292
if (!util::extract_byte_span_from_byte_span_checked(remainder,
304293
tag_subrange)) {
305294
util::exception_location().raise<std::invalid_argument>(

src/binsrv/event/gtid_tagged_log_body_impl.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
#include "binsrv/event/gtid_log_flag_type_fwd.hpp"
2525

2626
#include "binsrv/gtids/common_types.hpp"
27+
#include "binsrv/gtids/uuid.hpp"
2728

29+
#include "util/bounded_string_storage.hpp"
2830
#include "util/byte_span_fwd.hpp"
2931
#include "util/semantic_version_fwd.hpp"
3032

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright (c) 2023-2024 Percona and/or its affiliates.
2+
//
3+
// This program is free software; you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License, version 2.0,
5+
// as published by the Free Software Foundation.
6+
//
7+
// This program is distributed in the hope that it will be useful,
8+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
// GNU General Public License, version 2.0, for more details.
11+
//
12+
// You should have received a copy of the GNU General Public License
13+
// along with this program; if not, write to the Free Software
14+
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
16+
#include "binsrv/event/previous_gtids_log_body_impl.hpp"
17+
18+
#include <cstddef>
19+
#include <iterator>
20+
#include <ostream>
21+
#include <span>
22+
#include <string>
23+
24+
#include <boost/lexical_cast.hpp>
25+
26+
#include "binsrv/event/code_type.hpp"
27+
28+
#include "binsrv/gtids/common_types.hpp"
29+
#include "binsrv/gtids/gtid_set.hpp"
30+
31+
#include "util/byte_span.hpp"
32+
#include "util/byte_span_extractors.hpp"
33+
34+
namespace binsrv::event {
35+
36+
generic_body_impl<code_type::previous_gtids_log>::generic_body_impl(
37+
util::const_byte_span portion) {
38+
// TODO: rework with direct member initialization
39+
40+
auto remainder = portion;
41+
const std::size_t gtids_size{std::size(remainder)};
42+
gtids_.resize(gtids_size);
43+
const std::span<gtids::gtid_set_storage::value_type> gtids_range{gtids_};
44+
util::extract_byte_span_from_byte_span(remainder, gtids_range);
45+
}
46+
47+
[[nodiscard]] gtids::gtid_set
48+
generic_body_impl<code_type::previous_gtids_log>::get_gtids() const {
49+
return gtids::gtid_set{gtids_};
50+
}
51+
52+
[[nodiscard]] std::string
53+
generic_body_impl<code_type::previous_gtids_log>::get_readable_gtids() const {
54+
return boost::lexical_cast<std::string>(get_gtids());
55+
}
56+
57+
std::ostream &
58+
operator<<(std::ostream &output,
59+
const generic_body_impl<code_type::previous_gtids_log> &obj) {
60+
return output << "gtid_set: " << obj.get_readable_gtids();
61+
}
62+
63+
} // namespace binsrv::event
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2023-2024 Percona and/or its affiliates.
2+
//
3+
// This program is free software; you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License, version 2.0,
5+
// as published by the Free Software Foundation.
6+
//
7+
// This program is distributed in the hope that it will be useful,
8+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
// GNU General Public License, version 2.0, for more details.
11+
//
12+
// You should have received a copy of the GNU General Public License
13+
// along with this program; if not, write to the Free Software
14+
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
16+
#ifndef BINSRV_EVENT_PREVIOUS_GTIDS_LOG_BODY_IMPL_HPP
17+
#define BINSRV_EVENT_PREVIOUS_GTIDS_LOG_BODY_IMPL_HPP
18+
19+
#include "binsrv/event/previous_gtids_log_body_impl_fwd.hpp" // IWYU pragma: export
20+
21+
#include <cstddef>
22+
#include <cstdint>
23+
24+
#include <boost/container/small_vector.hpp>
25+
26+
#include "binsrv/gtids/common_types.hpp"
27+
#include "binsrv/gtids/gtid_set_fwd.hpp"
28+
29+
#include "util/byte_span_fwd.hpp"
30+
31+
namespace binsrv::event {
32+
33+
template <>
34+
class [[nodiscard]] generic_body_impl<code_type::previous_gtids_log> {
35+
public:
36+
// https://github.com/mysql/mysql-server/blob/mysql-8.4.6/libs/mysql/binlog/event/control_events.h#L1354
37+
38+
explicit generic_body_impl(util::const_byte_span portion);
39+
40+
[[nodiscard]] const gtids::gtid_set_storage &get_gtids_raw() const noexcept {
41+
return gtids_;
42+
}
43+
[[nodiscard]] gtids::gtid_set get_gtids() const;
44+
[[nodiscard]] std::string get_readable_gtids() const;
45+
46+
private:
47+
gtids::gtid_set_storage gtids_;
48+
};
49+
50+
} // namespace binsrv::event
51+
52+
#endif // BINSRV_EVENT_PREVIOUS_GTIDS_LOG_BODY_IMPL_HPP
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2023-2024 Percona and/or its affiliates.
2+
//
3+
// This program is free software; you can redistribute it and/or modify
4+
// it under the terms of the GNU General Public License, version 2.0,
5+
// as published by the Free Software Foundation.
6+
//
7+
// This program is distributed in the hope that it will be useful,
8+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10+
// GNU General Public License, version 2.0, for more details.
11+
//
12+
// You should have received a copy of the GNU General Public License
13+
// along with this program; if not, write to the Free Software
14+
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
15+
16+
#ifndef BINSRV_EVENT_PREVIOUS_GTIDS_LOG_BODY_IMPL_FWD_HPP
17+
#define BINSRV_EVENT_PREVIOUS_GTIDS_LOG_BODY_IMPL_FWD_HPP
18+
19+
#include "binsrv/event/code_type.hpp"
20+
#include "binsrv/event/generic_body_fwd.hpp"
21+
22+
namespace binsrv::event {
23+
24+
template <> class generic_body_impl<code_type::previous_gtids_log>;
25+
26+
std::ostream &
27+
operator<<(std::ostream &output,
28+
const generic_body_impl<code_type::previous_gtids_log> &obj);
29+
30+
} // namespace binsrv::event
31+
32+
#endif // BINSRV_EVENT_PREVIOUS_GTIDS_LOG_BODY_IMPL_FWD_HPP

0 commit comments

Comments
 (0)