MySQL 8.4.0
Source Code Documentation
binlog_reader.h
Go to the documentation of this file.
1/* Copyright (c) 2018, 2024, Oracle 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 designed to work with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have either included with
13 the program or referenced in the documentation.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License, version 2.0, for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
23
24#ifndef BINLOG_READER_INCLUDED
25#define BINLOG_READER_INCLUDED
26#include "sql/binlog_istream.h"
27#include "sql/log_event.h"
28
29/**
30 Deserialize a binlog event from event_data. event_data is serialized
31 event object. It is a chunk of data in buffer.
32
33 @param[in] event_data The event data used for deserialization.
34 @param[in] event_data_len Length of event_data
35 @param[in] fde The format_description_event of the event
36 @param[in] verify_checksum Verify event_data's checksum if it is true.
37 @param[out] event the event object generated.
38
39 @retval Binlog_read_error::SUCCESS Success
40 @retval Other than Binlog_read_error::SUCCESS Error
41*/
43 const unsigned char *event_data, unsigned int event_data_len,
45 bool verify_checksum, Log_event **event);
46
48 public:
50 unsigned char *allocate(size_t);
51 void deallocate(unsigned char *ptr);
52};
53/**
54 Binlog_event_data_istream fetches byte data from Basic_istream and
55 divides them into event_data chunk according to the format. Event_data is a
56 serialized event object. It is a chunk of data in buffer.
57*/
59 public:
61 unsigned int max_event_size);
65 delete;
66 virtual ~Binlog_event_data_istream() = default;
67
68 /**
69 Read an event data from the stream and verify its checksum if
70 verify_checksum is true.
71
72 @param[out] data The pointer of the event data
73 @param[out] length The length of the event data
74 @param[in] allocator It is used to allocate memory for the event data.
75 @param[in] verify_checksum Verify the event data's checksum if it is true.
76 @param[in] checksum_alg Checksum algorithm for verifying the event data. It
77 is used only when verify_checksum is true.
78 @retval false Success
79 @retval true Error
80 */
81 template <class ALLOCATOR>
83 unsigned char **data, unsigned int *length, ALLOCATOR *allocator,
84 bool verify_checksum,
87 if (read_event_header() || check_event_header()) return true;
88
89 unsigned char *event_data = allocator->allocate(m_event_length);
90 if (event_data == nullptr)
92
93 if (fill_event_data(event_data, verify_checksum, checksum_alg)) {
94 allocator->deallocate(event_data);
95 return true;
96 }
97 *data = event_data;
99 return false;
100 }
101
102 protected:
104 /**
105 Read the event header from the Basic_istream
106
107 @retval false Success
108 @retval true Error
109 */
110 virtual bool read_event_header();
111 /**
112 Check if it is a valid event header
113
114 @retval false Success
115 @retval true Error
116 */
117 bool check_event_header();
118 /**
119 Read fixed length of data from Basic_istream. It sets error to
120 - Binlog_read_error::SYTEM_IO if Basic_istream returns error.
121 - Binlog_read_error::TRUNC_EVENT if less than length is read.
122 - ERROR_TYPE if zero byte is read. ERROR_TYPE is either TRUNC_EVENT or
123 READ_EOF.
124
125 @param[in] data The buffer where the data stored.
126 @param[in] length Bytes of the data to be read.
127 @retval false Success
128 @retval true Error
129 */
130 template <Binlog_read_error::Error_type ERROR_TYPE>
131 bool read_fixed_length(unsigned char *data, unsigned int length) {
133 if (length == 0) return false;
134
135 longlong ret = m_istream->read(data, length);
136 if (ret == length) return false;
137 switch (ret) {
138 case -1:
140 case 0:
141 return m_error->set_type(ERROR_TYPE);
142 default:
144 }
145 }
146
147 /**
148 It is convenient for caller to share a Binlog_read_error object between
149 streams. So Binlog_read_error pointer is defined here. It should be
150 initialized in constructor by caller.
151 */
153
154 private:
156 unsigned int m_max_event_size;
157 unsigned int m_event_length = 0;
158
159 /**
160 Fill the event data into the given buffer and verify checksum if
161 'verify_checksum' is true.
162
163 @param[in] event_data The buffer where the event data will be stored.
164 @param[in] verify_checksum Verify the event data's checksum if it is true.
165 @param[in] checksum_alg Checksum algorithm for verifying the event data. It
166 is used only when verify_checksum is true.
167 @retval false Success
168 @retval true Error
169 */
170 bool fill_event_data(
171 unsigned char *event_data, bool verify_checksum,
173};
174
175/**
176 It reads event_data from an event_data stream and deserialize them to event
177 object.
178*/
179template <class EVENT_DATA_ISTREAM>
181 public:
183 EVENT_DATA_ISTREAM *istream)
184 : m_error(error), m_data_istream(istream) {}
185
189 delete;
190
191 /**
192 Read an event object from the stream
193
194 @param[in] fde The Format_description_event for deserialization.
195 @param[in] verify_checksum Verify the checksum of the event_data before
196 @param[in] allocator It is used to allocate memory for the event data.
197 @return An valid event object if success.
198 @retval nullptr Error
199 */
200 template <class ALLOCATOR>
203 bool verify_checksum, ALLOCATOR *allocator) {
205 unsigned char *data = nullptr;
206 unsigned int length = 0;
207
208 if (m_data_istream->read_event_data(&data, &length, allocator, false,
209 fde.footer()->checksum_alg))
210 return nullptr;
211
212 Log_event *event = nullptr;
214 verify_checksum, &event))) {
215 allocator->deallocate(data);
216 return nullptr;
217 }
218
219 event->register_temp_buf(reinterpret_cast<char *>(data),
220 ALLOCATOR::DELEGATE_MEMORY_TO_EVENT_OBJECT);
221 return event;
222 }
223
224 private:
225 /**
226 It is convenient for caller to share a Binlog_read_error object between
227 streams. So Binlog_read_error pointer is defined here. It should be
228 initialized in constructor by caller.
229 */
231 EVENT_DATA_ISTREAM *m_data_istream = nullptr;
232};
233
234/// Interface class that all specializations of
235/// template <...> Basic_binlog_file_reader inherit from.
237 public:
243 virtual ~IBasic_binlog_file_reader() = default;
244
245 /// Return true if there was a previous error.
246 virtual bool has_fatal_error() const = 0;
247
248 /// Return the type of error.
250
251 /// Return a string representing the error.
252 ///
253 /// The return value is static memory that is never deallocated.
254 virtual const char *get_error_str() const = 0;
255
256 /// Return the current position in bytes, relative to the beginning
257 /// of the file.
258 virtual my_off_t position() const = 0;
259
260 /// Read the next event from the stream.
261 ///
262 /// This function creates the object with "new". It is the caller's
263 /// responsibility to delete it.
264 ///
265 /// @return Log_event on success, nullptr on error. More
266 /// information about the error can be found using `get_error_type`
267 /// and `get_error_str`.
269
270 /// Return a pointer the currently used
271 /// Format_description_log_event.
272 ///
273 /// The event is a member by this reader, so the caller must not use
274 /// the returned reference after this reader has been deleted.
277};
278
279/**
280 It owns an allocator, a byte stream, an event_data stream and an event object
281 stream. The stream pipeline is setup in the constructor. All the objects
282 required for reading a binlog file is initialized in reader class.
283
284 It maintains the Format_description_event which is needed for reading the
285 following binlog events. A default format_description_event is initialized
286 at the beginning. Then it will be replaced by the one read from the binlog
287 file.
288
289 Some convenient functions is added to encapsulate the access of IFILE,
290 EVENT_DATA_ISTREAM, EVENT_OBJECT_ISTREAM. It makes the code
291 simpler for reading a binlog file.
292*/
293template <class IFILE, class EVENT_DATA_ISTREAM,
294 template <class> class EVENT_OBJECT_ISTREAM, class ALLOCATOR>
296 public:
297 typedef EVENT_DATA_ISTREAM Event_data_istream;
298 typedef EVENT_OBJECT_ISTREAM<Event_data_istream> Event_object_istream;
299
300 Basic_binlog_file_reader(bool verify_checksum,
301 unsigned int max_event_size = UINT_MAX)
302 : m_ifile(&m_error),
303 m_data_istream(&m_error, &m_ifile, max_event_size),
306 m_verify_checksum(verify_checksum),
307 m_file_name("") {}
308
312 delete;
314 delete;
316
317 /**
318 Open a binlog file and set read position to offset. It will read and store
319 Format_description_event automatically if offset is bigger than current
320 position and fde is nullptr. Otherwise fde is use instead of finding fde
321 from the file if fde is not null.
322
323 @param[in] file_name name of the binlog file which will be opened.
324 @param[in] offset The position where it starts to read.
325 @param[out] fdle For returning an Format_description_log_event object.
326 @retval false Success
327 @retval true Error
328 */
329 bool open(const char *file_name, my_off_t offset = 0,
330 Format_description_log_event **fdle = nullptr) {
332 if (m_ifile.open(file_name)) return true;
333
335 if (!fd) return has_fatal_error();
336
337 if (position() < offset && seek(offset)) {
338 delete fd;
339 return true;
340 }
341 if (fdle)
342 *fdle = fd;
343 else
344 delete fd;
346 return false;
347 }
348 /**
349 Close the binlog file.
350 */
351 void close() {
352 m_ifile.close();
355 }
356
357 bool is_open() const { return m_ifile.is_open(); }
358 my_off_t position() const override { return m_ifile.position(); }
359 bool seek(my_off_t pos) { return m_ifile.seek(pos); }
360
361 /**
362 Wrapper of EVENT_DATA_ISTREAM::read_event_data.
363 */
364 bool read_event_data(unsigned char **data, unsigned int *length) {
366 return m_data_istream.read_event_data(data, length, &m_allocator,
369 }
370 /**
371 wrapper of EVENT_OBJECT_ISTREAM::read_event_object.
372 */
375 Log_event *ev = m_object_istream.read_event_object(m_fde, m_verify_checksum,
376 &m_allocator);
377 if (ev != nullptr &&
379 m_fde =
381 return ev;
382 }
383
384 bool has_fatal_error() const override { return m_error.has_fatal_error(); }
385 /**
386 Return the error happened in the stream pipeline.
387 */
389 return m_error.get_type();
390 }
391 /**
392 Return the error message of the error happened in the stream pipeline.
393 */
394 const char *get_error_str() const override { return m_error.get_str(); }
395
396 IFILE *ifile() { return &m_ifile; }
399 ALLOCATOR *allocator() { return &m_allocator; }
400
403 m_fde = fde;
404 }
406 format_description_event() const override {
407 return m_fde;
408 }
410
411 /**
412 @brief Resets the error. Sets it to Binlog_read_error::SUCCESS.
413 */
415 const char *get_file_name() const { return m_file_name; }
416
417 private:
419
420 IFILE m_ifile;
423 ALLOCATOR m_allocator;
424
426 bool m_verify_checksum = false;
427 const char *m_file_name{""};
429
430 /**
431 Read the Format_description_log_events before 'offset'.
432
433 @param[in] offset The position where the read should stop.
434 @return A valid Format_description_log_event pointer or nullptr.
435 */
439 Format_description_log_event *fdle = nullptr;
440 /*
441 Format_description_event is skipped, so we initialize m_fde here. For
442 relay log, it need to find master's Format_description_event. master's
443 Format_description_event is the 3rd or 4th event of a relay log file.
444 Relay log's format looks like:
445 Format_description_event : relay log's Format_description_event
446 Previous_gtid_event
447 [Rotate_event] : In the case rotating relaylog, no Rotate here
448 Format_description_event : master's Format_description_event
449 */
450 while (position() < offset) {
452
453 Log_event *ev = m_object_istream.read_event_object(
455
456 if (ev == nullptr) break;
457 if (ev->get_type_code() ==
459 delete fdle;
460 fdle = dynamic_cast<Format_description_log_event *>(ev);
461 m_fde = *fdle;
462 } else {
464 delete ev;
467 break;
468 }
469 }
470 if (has_fatal_error()) {
471 delete fdle;
472 return nullptr;
473 }
474 return fdle;
475 }
476};
477
478#ifdef MYSQL_SERVER
487#endif // MYSQL_SERVER
488#endif // BINLOG_READER_INCLUDED
#define LOG_EVENT_MINIMAL_HEADER_LEN
Fixed header length, where 4.x and 5.0 agree.
Definition: binlog_event.h:457
Binlog_read_error::Error_type binlog_event_deserialize(const unsigned char *event_data, unsigned int event_data_len, const mysql::binlog::event::Format_description_event *fde, bool verify_checksum, Log_event **event)
Deserialize a binlog event from event_data.
Definition: binlog_reader.cc:125
Basic_binlog_file_reader< Binlog_ifile, Binlog_event_data_istream, Binlog_event_object_istream, Default_binlog_event_allocator > Binlog_file_reader
Definition: binlog_reader.h:482
Basic_binlog_file_reader< Relaylog_ifile, Binlog_event_data_istream, Binlog_event_object_istream, Default_binlog_event_allocator > Relaylog_file_reader
Definition: binlog_reader.h:486
It owns an allocator, a byte stream, an event_data stream and an event object stream.
Definition: binlog_reader.h:295
Event_data_istream m_data_istream
Definition: binlog_reader.h:421
Event_data_istream * event_data_istream()
Definition: binlog_reader.h:397
EVENT_DATA_ISTREAM Event_data_istream
Definition: binlog_reader.h:297
Format_description_log_event * read_fdle(my_off_t offset)
Read the Format_description_log_events before 'offset'.
Definition: binlog_reader.h:436
void set_format_description_event(const mysql::binlog::event::Format_description_event &fde)
Definition: binlog_reader.h:401
bool open(const char *file_name, my_off_t offset=0, Format_description_log_event **fdle=nullptr)
Open a binlog file and set read position to offset.
Definition: binlog_reader.h:329
~Basic_binlog_file_reader() override
Definition: binlog_reader.h:315
const char * m_file_name
Definition: binlog_reader.h:427
const char * get_error_str() const override
Return the error message of the error happened in the stream pipeline.
Definition: binlog_reader.h:394
bool m_verify_checksum
Definition: binlog_reader.h:426
Binlog_read_error::Error_type get_error_type() const override
Return the error happened in the stream pipeline.
Definition: binlog_reader.h:388
ALLOCATOR m_allocator
Definition: binlog_reader.h:423
Event_object_istream * event_object_istream()
Definition: binlog_reader.h:398
bool is_open() const
Definition: binlog_reader.h:357
bool has_fatal_error() const override
Return true if there was a previous error.
Definition: binlog_reader.h:384
Basic_binlog_file_reader & operator=(const Basic_binlog_file_reader &&)=delete
my_off_t event_start_pos()
Definition: binlog_reader.h:409
Binlog_read_error m_error
Definition: binlog_reader.h:418
Basic_binlog_file_reader & operator=(const Basic_binlog_file_reader &)=delete
EVENT_OBJECT_ISTREAM< Event_data_istream > Event_object_istream
Definition: binlog_reader.h:298
Event_object_istream m_object_istream
Definition: binlog_reader.h:422
ALLOCATOR * allocator()
Definition: binlog_reader.h:399
void close()
Close the binlog file.
Definition: binlog_reader.h:351
IFILE m_ifile
Definition: binlog_reader.h:420
mysql::binlog::event::Format_description_event m_fde
Definition: binlog_reader.h:425
bool read_event_data(unsigned char **data, unsigned int *length)
Wrapper of EVENT_DATA_ISTREAM::read_event_data.
Definition: binlog_reader.h:364
my_off_t m_event_start_pos
Definition: binlog_reader.h:428
Basic_binlog_file_reader(bool verify_checksum, unsigned int max_event_size=UINT_MAX)
Definition: binlog_reader.h:300
my_off_t position() const override
Return the current position in bytes, relative to the beginning of the file.
Definition: binlog_reader.h:358
Basic_binlog_file_reader(const Basic_binlog_file_reader &&)=delete
const mysql::binlog::event::Format_description_event & format_description_event() const override
Return a pointer the currently used Format_description_log_event.
Definition: binlog_reader.h:406
IFILE * ifile()
Definition: binlog_reader.h:396
Basic_binlog_file_reader(const Basic_binlog_file_reader &)=delete
Log_event * read_event_object() override
wrapper of EVENT_OBJECT_ISTREAM::read_event_object.
Definition: binlog_reader.h:373
const char * get_file_name() const
Definition: binlog_reader.h:415
void reset_error()
Resets the error.
Definition: binlog_reader.h:414
bool seek(my_off_t pos)
Definition: binlog_reader.h:359
The abstract class for basic byte input streams which provides read operations.
Definition: basic_istream.h:35
virtual ssize_t read(unsigned char *buffer, size_t length)=0
Read some bytes from the input stream.
Binlog_event_data_istream fetches byte data from Basic_istream and divides them into event_data chunk...
Definition: binlog_reader.h:58
unsigned int m_max_event_size
Definition: binlog_reader.h:156
bool read_event_data(unsigned char **data, unsigned int *length, ALLOCATOR *allocator, bool verify_checksum, mysql::binlog::event::enum_binlog_checksum_alg checksum_alg)
Read an event data from the stream and verify its checksum if verify_checksum is true.
Definition: binlog_reader.h:82
Basic_istream * m_istream
Definition: binlog_reader.h:155
bool read_fixed_length(unsigned char *data, unsigned int length)
Read fixed length of data from Basic_istream.
Definition: binlog_reader.h:131
Binlog_read_error * m_error
It is convenient for caller to share a Binlog_read_error object between streams.
Definition: binlog_reader.h:152
unsigned int m_event_length
Definition: binlog_reader.h:157
Binlog_event_data_istream & operator=(const Binlog_event_data_istream &)=delete
bool check_event_header()
Check if it is a valid event header.
Definition: binlog_reader.cc:108
virtual bool read_event_header()
Read the event header from the Basic_istream.
Definition: binlog_reader.cc:74
virtual ~Binlog_event_data_istream()=default
Binlog_event_data_istream(const Binlog_event_data_istream &)=delete
bool fill_event_data(unsigned char *event_data, bool verify_checksum, mysql::binlog::event::enum_binlog_checksum_alg checksum_alg)
Fill the event data into the given buffer and verify checksum if 'verify_checksum' is true.
Definition: binlog_reader.cc:79
unsigned char m_header[LOG_EVENT_MINIMAL_HEADER_LEN]
Definition: binlog_reader.h:103
It reads event_data from an event_data stream and deserialize them to event object.
Definition: binlog_reader.h:180
Binlog_read_error * m_error
It is convenient for caller to share a Binlog_read_error object between streams.
Definition: binlog_reader.h:230
EVENT_DATA_ISTREAM * m_data_istream
Definition: binlog_reader.h:231
Binlog_event_object_istream(const Binlog_event_object_istream &)=delete
Binlog_event_object_istream & operator=(const Binlog_event_object_istream &)=delete
Binlog_event_object_istream(Binlog_read_error *error, EVENT_DATA_ISTREAM *istream)
Definition: binlog_reader.h:182
Log_event * read_event_object(const mysql::binlog::event::Format_description_event &fde, bool verify_checksum, ALLOCATOR *allocator)
Read an event object from the stream.
Definition: binlog_reader.h:201
Binlog input file.
Definition: binlog_istream.h:241
It defines the error types which could happen when reading binlog files or deserializing binlog event...
Definition: binlog_istream.h:37
Error_type get_type() const
Return the error encountered when reading events.
Definition: binlog_istream.h:88
Error_type
Possible errors which happens when reading an event.
Definition: binlog_istream.h:42
@ MEM_ALLOCATE
Definition: binlog_istream.h:56
@ SUCCESS
Definition: binlog_istream.h:44
@ SYSTEM_IO
Definition: binlog_istream.h:54
@ TRUNC_EVENT
Definition: binlog_istream.h:58
bool set_type(Error_type type)
Set m_error to error.
Definition: binlog_istream.h:106
const char * get_str() const
Return error message of the error type.
Definition: binlog_istream.cc:34
bool has_fatal_error() const
Definition: binlog_istream.h:83
Definition: binlog_reader.h:47
unsigned char * allocate(size_t)
Definition: binlog_reader.cc:33
void deallocate(unsigned char *ptr)
Definition: binlog_reader.cc:39
@ DELEGATE_MEMORY_TO_EVENT_OBJECT
Definition: binlog_reader.h:49
For binlog version 4.
Definition: log_event.h:1525
Interface class that all specializations of template <...> Basic_binlog_file_reader inherit from.
Definition: binlog_reader.h:236
IBasic_binlog_file_reader(IBasic_binlog_file_reader &)=delete
IBasic_binlog_file_reader & operator=(IBasic_binlog_file_reader &&)=delete
virtual ~IBasic_binlog_file_reader()=default
IBasic_binlog_file_reader & operator=(IBasic_binlog_file_reader &)=delete
virtual const char * get_error_str() const =0
Return a string representing the error.
virtual my_off_t position() const =0
Return the current position in bytes, relative to the beginning of the file.
IBasic_binlog_file_reader(IBasic_binlog_file_reader &&)=delete
IBasic_binlog_file_reader()=default
virtual Binlog_read_error::Error_type get_error_type() const =0
Return the type of error.
virtual const mysql::binlog::event::Format_description_event & format_description_event() const =0
Return a pointer the currently used Format_description_log_event.
virtual Log_event * read_event_object()=0
Read the next event from the stream.
virtual bool has_fatal_error() const =0
Return true if there was a previous error.
This is the abstract base class for binary log events.
Definition: log_event.h:538
virtual mysql::binlog::event::Log_event_type get_type_code() const
Definition: log_event.h:797
void register_temp_buf(char *buf, bool free_in_destructor=true)
Definition: log_event.h:865
Relaylog input file.
Definition: binlog_istream.h:253
const Log_event_footer * footer() const
Return a const pointer to the footer of the log event.
Definition: binlog_event.h:967
For binlog version 4.
Definition: control_events.h:239
mysql::binlog::event::Format_description_event Format_description_event
Definition: file_storage.cc:40
#define BINLOG_VERSION
binlog_version 3 is MySQL 4.x; 4 is MySQL 5.0.0.
Definition: binlog_event.h:106
Binary log event definitions.
#define DBUG_TRACE
Definition: my_dbug.h:146
ulonglong my_off_t
Definition: my_inttypes.h:72
long long int longlong
Definition: my_inttypes.h:55
static char * server_version
Definition: mysql.cc:120
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:76
std::string file_name(Log_file_id file_id)
Provides name of the log file with the given file id, e.g.
Definition: log0pre_8_0_30.cc:94
Log_event_type
Enumeration type for the different types of log events.
Definition: binlog_event.h:286
@ FORMAT_DESCRIPTION_EVENT
Definition: binlog_event.h:312
@ PREVIOUS_GTIDS_LOG_EVENT
Definition: binlog_event.h:355
@ ROTATE_EVENT
Definition: binlog_event.h:302
enum_binlog_checksum_alg
Enumeration spcifying checksum algorithm used to encode a binary log event.
Definition: binlog_event.h:462
required string type
Definition: replication_group_member_actions.proto:34
required string event
Definition: replication_group_member_actions.proto:32