MySQL 26.7.0
Source Code Documentation
log0redo.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2023, 2026, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is designed to work with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation. The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26*****************************************************************************/
27
28/** @file include/log0redo.h
29 Redo log parsing and applying.
30
31 ****************************************************************************/
32
33#ifndef log0redo_h
34#define log0redo_h
35
36#include <cstdint>
37#include <memory>
38#include <optional>
39#include <span>
40#include <type_traits>
41#include <vector>
42
43#include "ut0expected.h"
44
45/* Required inside Page_handle_wrapper */
46struct buf_block_t;
47
48namespace ib::redo {
49
50/** This class represents a parsed redo record.
51@note The body field refers to the original parsing buffer,
52 so a caller must ensure that the buffer's lifetime is
53 not less than the parsed record's lifetime. */
55 public:
56 /** Possible record kinds. */
57 enum class Kind {
58 /** Auxiliary record. */
59 Aux,
60
61 /** Page data record. */
62 Page,
63
64 /** Table metadata record. */
65 Table,
66
67 /** Table space record. */
68 Space,
69 };
70
71 /** Auxiliary record tag. */
72 struct Aux_tag {
73 static constexpr Kind kind = Kind::Aux;
74 };
75
76 /** Page data record tag. */
77 struct Page_tag {
78 static constexpr Kind kind = Kind::Page;
79
80 /** Tablespace id. */
81 uint32_t space_id;
82
83 /** Page number. */
84 uint32_t page_no;
85 };
86
87 /** Table metadata tag. */
88 struct Table_tag {
89 static constexpr Kind kind = Kind::Table;
90
91 /** Table id. */
92 uint64_t table_id;
93
94 /** Metadata version. */
95 uint64_t version;
96 };
97
98 /** Table space tag. */
99 struct Space_tag {
100 static constexpr Kind kind = Kind::Space;
101
102 /** Space id. */
103 uint32_t space_id;
104 };
105
106 template <typename Tag>
107 constexpr Record_view(int type, size_t size, std::span<const uint8_t> body,
108 Tag &&tag)
109 : m_kind(Tag::kind),
110 m_type(type),
111 m_size(size),
112 m_body(body),
113 m_tag(std::forward<Tag>(tag)) {}
114
115 /** Returns record kind. */
116 [[nodiscard]] constexpr Kind kind() const noexcept { return m_kind; }
117
118 /** Returns record type with MLOG_SINGLE_REC_FLAG cleared. */
119 [[nodiscard]] constexpr int type() const noexcept { return m_type; }
120
121 /** Returns record size in bytes occupied in the parsing buffer. */
122 [[nodiscard]] constexpr size_t size() const noexcept { return m_size; }
123
124 /** Returns reference to record body. */
125 [[nodiscard]] constexpr std::span<const uint8_t> body() const noexcept {
126 return m_body;
127 }
128
129 /** Returns page data tag. */
130 [[nodiscard]] constexpr const Page_tag &page() const noexcept {
132 return m_tag.page;
133 }
134
135 /** Returns table metadata tag. */
136 [[nodiscard]] constexpr const Table_tag &table() const noexcept {
138 return m_tag.table;
139 }
140
141 /** Returns table space tag. */
142 [[nodiscard]] constexpr const Space_tag &space() const noexcept {
144 return m_tag.space;
145 }
146
147 private:
149
150 /** Record type with MLOG_SINGLE_REC_FLAG cleared. */
152
153 /** Full record size in bytes occupied in the parsing buffer. */
154 size_t m_size;
155
156 /** Record data excluding what consumed by m_type and m_tag. */
157 std::span<const uint8_t> m_body;
158
159 union Tag {
164
165 constexpr Tag(Aux_tag &&tag) : aux(std::forward<Aux_tag>(tag)) {}
166 constexpr Tag(Page_tag &&tag) : page(std::forward<Page_tag>(tag)) {}
167 constexpr Tag(Table_tag &&tag) : table(std::forward<Table_tag>(tag)) {}
168 constexpr Tag(Space_tag &&tag) : space(std::forward<Space_tag>(tag)) {}
170};
171
172using Record_list = std::vector<Record_view>;
173
174/** This class represents a list of parsed redo records that form an mtr. */
175class Mtr_view {
176 public:
177 /** Returns mtr size in bytes occupied in the parsing buffer. */
178 [[nodiscard]] constexpr size_t size() const noexcept { return m_size; }
179
180 /** Returns true if mtr contains no records. */
181 [[nodiscard]] constexpr bool empty() const noexcept { return m_size == 0; }
182
183 /** Returns record list. */
184 [[nodiscard]] constexpr const Record_list &records() const noexcept {
185 return m_records;
186 }
187
188 /** Add record to the list. */
189 template <typename T>
191 m_size += record.size();
192 m_records.emplace_back(std::forward<T>(record));
193 }
194
195 private:
196 /** Full mtr size in bytes occupied in the parsing buffer. */
197 size_t m_size = 0;
198
200};
201
202/** Parse error description. */
204 public:
205 /** Buffer is too short to parse. */
206 static constexpr int Incomplete = 1;
207
208 /** Buffer contains corrupted data. */
209 static constexpr int Corrupted = 2;
210
211 /** Returns position in parsing buffer where the error occurred.
212 The position is aligned to the record boundary. */
213 [[nodiscard]] constexpr size_t pos() const noexcept { return m_pos; }
214
215 /** Add position to error description.
216 @param pos error position
217 @return Reference to self. */
218 [[nodiscard]] auto &with_pos(size_t pos) {
219 m_pos = pos;
220 return *this;
221 }
222
223 constexpr Parse_error(int code) noexcept : m_code(code) {}
224
225 constexpr operator int() const noexcept { return m_code; }
226
227 private:
229 size_t m_pos = 0;
230};
231
232template <typename T>
234
235/** The handle that represents the page where redo log records are applied.
236It includes the compressed and uncompressed page buffers which are named
237as frame as per the convention used in InnoDB. If handle represents a
238compressed page, then it must maintain metadata which may have updated
239during applying the log records.
240
241@note 'const' page buffers in the handle mean that you can't modify direct
242fields of them, so you can't change .data nor .size, i.e. can't re-point them
243to anything else, or decide to change their size. OTOH, you can change values
244of bytes within these buffers. */
245struct Page_handle final {
246 /** Tablespace id. */
247 const uint32_t space_id;
248
249 /** Page number. */
250 const uint32_t page_no;
251
252 /** Page buffer */
253 const std::span<uint8_t> frame;
254
255 /** Compressed page buffer and metadata about the compressed page */
256 struct Zipped {
257 /** Compressed page buffer */
258 const std::span<uint8_t> frame;
259 struct Metadata {
260 /** Start offset of the modification log that is right after the
261 compressed image in the page */
262 uint16_t start_offset;
263 /** End offset of the modification log */
264 uint16_t end_offset;
265 /** Number of externally stored columns on the page; the maximum is 744
266 on a 16 KiB page */
267 uint16_t n_blobs;
269 };
270
271 /** An optional compressed page buffer that needs to be initialized iff this
272 handle represents a compressed page */
273 std::optional<Zipped> zipped;
274};
275
276/** A convenience wrapper over the Page_handle (where redo log records are
277applied). It initializes the page handle from the buffer block and keep them
278sane. User must update the block after the redo log records are applied
279on the page handle. */
281 public:
283
284 // Move constructor
286 : m_block(other.m_block),
287 m_page_handle(std::move(other.m_page_handle))
288#ifdef UNIV_DEBUG
289 ,
290 m_need_to_update_block(other.m_need_to_update_block)
291#endif
292 {
293#ifdef UNIV_DEBUG
294 // no need to update the temporary object
295 other.m_need_to_update_block = false;
296#endif
297 }
298
299 // Explicitly delete copy operations
301
302#ifdef UNIV_DEBUG
304#endif
305
306 [[nodiscard]] constexpr buf_block_t &block() noexcept { return m_block; }
307
308 [[nodiscard]] constexpr Page_handle &handle() noexcept {
309 return m_page_handle;
310 }
311
312 /** If it is compressed page then update the compressed page metadata in the
313 block. Metadata may have changed during applying the log record */
314 void update_block();
315
316 private:
319#ifdef UNIV_DEBUG
321#endif /* UNIV_DEBUG */
322};
323
324/* Page_handle is part of an interface and should be kept simple */
325static_assert(std::is_standard_layout_v<Page_handle>);
326
327/** The handle that represents a log record. It contains record type and the
328record body. */
330 /** Record type */
331 uint8_t type;
332
333 /** Record body */
334 std::span<const uint8_t> body;
335};
336
337/* Record_handle is part of an interface and should be kept simple */
338static_assert(std::is_standard_layout_v<Record_handle>);
339
340/** This class allows to parse and apply redo records. */
341class Redo_applier final {
342 public:
343 Redo_applier();
344
346
347 /** Parse an mtr from a buffer.
348 @param buffer buffer to parse
349 @return Parsed mtr or error. */
350 [[nodiscard]] Parse_result<Mtr_view> parse_mtr(
351 std::span<const uint8_t> buffer);
352
353 /** Apply a parsed redo record to a page.
354 @param record_handle record to apply
355 @param page_handle Page handle to apply the record to
356 @return True on success, false on error. In case of error page may
357 contain garbage. */
358 [[nodiscard]] bool apply(const Record_handle &record_handle,
359 Page_handle &page_handle);
360
361 private:
362 class Impl;
363 std::unique_ptr<Impl> m_impl;
364};
365
366} // namespace ib::redo
367
368#endif /* !log0redo_h */
This class represents a list of parsed redo records that form an mtr.
Definition: log0redo.h:175
size_t m_size
Full mtr size in bytes occupied in the parsing buffer.
Definition: log0redo.h:197
constexpr size_t size() const noexcept
Returns mtr size in bytes occupied in the parsing buffer.
Definition: log0redo.h:178
constexpr bool empty() const noexcept
Returns true if mtr contains no records.
Definition: log0redo.h:181
void add_record(T &&record)
Add record to the list.
Definition: log0redo.h:190
Record_list m_records
Definition: log0redo.h:199
constexpr const Record_list & records() const noexcept
Returns record list.
Definition: log0redo.h:184
A convenience wrapper over the Page_handle (where redo log records are applied).
Definition: log0redo.h:280
buf_block_t & m_block
Definition: log0redo.h:317
Page_handle m_page_handle
Definition: log0redo.h:318
Page_handle_wrapper(buf_block_t &block)
Definition: log0redo.cc:901
void update_block()
If it is compressed page then update the compressed page metadata in the block.
Definition: log0redo.cc:917
constexpr buf_block_t & block() noexcept
Definition: log0redo.h:306
constexpr Page_handle & handle() noexcept
Definition: log0redo.h:308
~Page_handle_wrapper()
Definition: log0redo.h:303
Page_handle_wrapper(Page_handle_wrapper &&other) noexcept
Definition: log0redo.h:285
bool m_need_to_update_block
Definition: log0redo.h:320
Page_handle_wrapper(const Page_handle_wrapper &)=delete
Parse error description.
Definition: log0redo.h:203
size_t m_pos
Definition: log0redo.h:229
constexpr size_t pos() const noexcept
Returns position in parsing buffer where the error occurred.
Definition: log0redo.h:213
constexpr Parse_error(int code) noexcept
Definition: log0redo.h:223
int m_code
Definition: log0redo.h:228
static constexpr int Corrupted
Buffer contains corrupted data.
Definition: log0redo.h:209
auto & with_pos(size_t pos)
Add position to error description.
Definition: log0redo.h:218
static constexpr int Incomplete
Buffer is too short to parse.
Definition: log0redo.h:206
This class represents a parsed redo record.
Definition: log0redo.h:54
constexpr std::span< const uint8_t > body() const noexcept
Returns reference to record body.
Definition: log0redo.h:125
int m_type
Record type with MLOG_SINGLE_REC_FLAG cleared.
Definition: log0redo.h:151
constexpr const Table_tag & table() const noexcept
Returns table metadata tag.
Definition: log0redo.h:136
Kind
Possible record kinds.
Definition: log0redo.h:57
@ Page
Page data record.
@ Aux
Auxiliary record.
@ Table
Table metadata record.
@ Space
Table space record.
constexpr Kind kind() const noexcept
Returns record kind.
Definition: log0redo.h:116
Kind m_kind
Definition: log0redo.h:148
constexpr const Page_tag & page() const noexcept
Returns page data tag.
Definition: log0redo.h:130
size_t m_size
Full record size in bytes occupied in the parsing buffer.
Definition: log0redo.h:154
union ib::redo::Record_view::Tag m_tag
constexpr size_t size() const noexcept
Returns record size in bytes occupied in the parsing buffer.
Definition: log0redo.h:122
std::span< const uint8_t > m_body
Record data excluding what consumed by m_type and m_tag.
Definition: log0redo.h:157
constexpr const Space_tag & space() const noexcept
Returns table space tag.
Definition: log0redo.h:142
constexpr int type() const noexcept
Returns record type with MLOG_SINGLE_REC_FLAG cleared.
Definition: log0redo.h:119
constexpr Record_view(int type, size_t size, std::span< const uint8_t > body, Tag &&tag)
Definition: log0redo.h:107
Definition: log0redo.cc:70
This class allows to parse and apply redo records.
Definition: log0redo.h:341
std::unique_ptr< Impl > m_impl
Definition: log0redo.h:362
Redo_applier()
Definition: log0redo.cc:887
bool apply(const Record_handle &record_handle, Page_handle &page_handle)
Apply a parsed redo record to a page.
Definition: log0redo.cc:896
Parse_result< Mtr_view > parse_mtr(std::span< const uint8_t > buffer)
Parse an mtr from a buffer.
Definition: log0redo.cc:891
C++23 std::expected.
Definition: ut0expected.h:74
#define T
Definition: jit_executor_value.cc:373
static int record
Definition: mysqltest.cc:195
Definition: log0common.h:32
std::vector< Record_view > Record_list
Definition: log0redo.h:172
noexcept
The return type for any call_and_catch(f, args...) call where f(args...) returns Type.
Definition: call_and_catch.h:76
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:418
Define std::hash<Gtid>.
Definition: gtid.h:355
The buffer control block structure.
Definition: buf0buf.h:1756
Definition: log0redo.h:259
uint16_t end_offset
End offset of the modification log.
Definition: log0redo.h:264
uint16_t n_blobs
Number of externally stored columns on the page; the maximum is 744 on a 16 KiB page.
Definition: log0redo.h:267
uint16_t start_offset
Start offset of the modification log that is right after the compressed image in the page.
Definition: log0redo.h:262
Compressed page buffer and metadata about the compressed page.
Definition: log0redo.h:256
const std::span< uint8_t > frame
Compressed page buffer.
Definition: log0redo.h:258
struct ib::redo::Page_handle::Zipped::Metadata metadata
The handle that represents the page where redo log records are applied.
Definition: log0redo.h:245
std::optional< Zipped > zipped
An optional compressed page buffer that needs to be initialized iff this handle represents a compress...
Definition: log0redo.h:273
const std::span< uint8_t > frame
Page buffer.
Definition: log0redo.h:253
const uint32_t space_id
Tablespace id.
Definition: log0redo.h:247
const uint32_t page_no
Page number.
Definition: log0redo.h:250
The handle that represents a log record.
Definition: log0redo.h:329
std::span< const uint8_t > body
Record body.
Definition: log0redo.h:334
uint8_t type
Record type.
Definition: log0redo.h:331
Auxiliary record tag.
Definition: log0redo.h:72
static constexpr Kind kind
Definition: log0redo.h:73
Page data record tag.
Definition: log0redo.h:77
uint32_t space_id
Tablespace id.
Definition: log0redo.h:81
uint32_t page_no
Page number.
Definition: log0redo.h:84
static constexpr Kind kind
Definition: log0redo.h:78
Table space tag.
Definition: log0redo.h:99
static constexpr Kind kind
Definition: log0redo.h:100
uint32_t space_id
Space id.
Definition: log0redo.h:103
Table metadata tag.
Definition: log0redo.h:88
static constexpr Kind kind
Definition: log0redo.h:89
uint64_t table_id
Table id.
Definition: log0redo.h:92
uint64_t version
Metadata version.
Definition: log0redo.h:95
Definition: log0redo.h:159
constexpr Tag(Page_tag &&tag)
Definition: log0redo.h:166
Aux_tag aux
Definition: log0redo.h:160
Page_tag page
Definition: log0redo.h:161
constexpr Tag(Space_tag &&tag)
Definition: log0redo.h:168
Table_tag table
Definition: log0redo.h:162
constexpr Tag(Table_tag &&tag)
Definition: log0redo.h:167
Space_tag space
Definition: log0redo.h:163
constexpr Tag(Aux_tag &&tag)
Definition: log0redo.h:165
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:109
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:97
Minimal implementation of C++23 std::expected.