MySQL 8.0.46
Source Code Documentation
rpl_injector.h
Go to the documentation of this file.
1/* Copyright (c) 2006, 2026, 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 INJECTOR_H
25#define INJECTOR_H
26
27#include <stddef.h>
28#include <string_view>
29
30#include "my_dbug.h"
31#include "my_inttypes.h"
32#include "sql/table.h" // TABLE
33
34class MYSQL_BIN_LOG;
35class THD;
36struct MY_BITMAP;
37
38/*
39 Injector to inject rows into the MySQL server.
40
41 The injector class is used to notify the MySQL server of new rows that have
42 appeared outside of MySQL control.
43
44 The original purpose of this is to allow clusters---which handle replication
45 inside the cluster through other means---to insert new rows into binary log.
46 Note, however, that the injector should be used whenever rows are altered in
47 any manner that is outside of MySQL server visibility and which therefore
48 are not seen by the MySQL server.
49 */
50class injector {
51 public:
52 /*
53 Get an instance of the injector.
54
55 DESCRIPTION
56 The injector is a Singleton, so this static function return the
57 available instance of the injector.
58
59 RETURN VALUE
60 A pointer to the available injector object.
61 */
62 static injector *instance();
63
64 /*
65 Delete the singleton instance (if allocated). Used during server shutdown.
66 */
67 static void free_instance();
68
69 /*
70 Return current binlog filename into provided buffer.
71
72 Writes an empty string if no binlog file is active.
73
74 Only buffers of size FN_REFLEN are supported (compile-time enforced).
75 */
77
78 /*
79 A transaction where rows can be added.
80
81 DESCRIPTION
82 The transaction class satisfy the **CopyConstructible** and
83 **Assignable** requirements. Note that the transaction is *not*
84 default constructible.
85 */
87 friend class injector;
88
89 public:
90 /* Convenience definitions */
93
94 /*
95 Table reference.
96
97 RESPONSIBILITY
98
99 The class contains constructors to handle several forms of
100 references to tables. The constructors can implicitly be used to
101 construct references from, e.g., strings containing table names.
102
103 EXAMPLE
104
105 The class is intended to be used *by value*. Please, do not try to
106 construct objects of this type using 'new'; instead construct an
107 object, possibly a temporary object. For example:
108
109 injector::transaction::table tbl(share->table, true);
110 MY_BITMAP cols;
111 bitmap_init(&cols, NULL, (i + 7) / 8, false);
112 inj->write_row(::server_id, tbl, &cols, row_data);
113
114 or
115
116 MY_BITMAP cols;
117 bitmap_init(&cols, NULL, (i + 7) / 8, false);
118 inj->write_row(::server_id,
119 injector::transaction::table(share->table, true),
120 &cols, row_data);
121
122 This will work, be more efficient, and have greater chance of
123 inlining, not run the risk of losing pointers.
124
125 COLLABORATION
126
127 injector::transaction
128 Provide a flexible interface to the representation of tables.
129
130 */
131 class table {
132 public:
133 class save_sets {
134 public:
135 save_sets(table const &tbl, MY_BITMAP const *new_rs,
136 MY_BITMAP const *new_ws)
137 : m_table(tbl.get_table()),
138 save_read_set(m_table->read_set),
139 save_write_set(m_table->write_set) {
141 const_cast<MY_BITMAP *>(new_rs), const_cast<MY_BITMAP *>(new_ws));
142 }
143
146 }
147
148 private:
152 };
153
155 : m_table(table),
158
159 TABLE *get_table() const { return m_table; }
160 bool is_transactional() const { return m_is_transactional; }
161 bool skip_hash() const { return m_skip_hash; }
162
163 private:
166 const bool m_skip_hash;
167 };
168
169 /*
170 Binlog position as a structure.
171 */
173 friend class transaction;
174
175 public:
176 char const *file_name() const { return m_file_name; }
177 my_off_t file_pos() const { return m_file_pos; }
178
179 private:
180 char const *m_file_name;
182 };
183
186 ~transaction();
187
188 /* Clear transaction, i.e., make calls to 'good()' return false. */
189 void clear() { m_thd = nullptr; }
190
191 /* Is the transaction in a good state? */
192 bool good() const { return m_thd != nullptr; }
193
194 /* Default assignment operator: standard implementation */
196 swap(t);
197 return *this;
198 }
199
200 /*
201
202 DESCRIPTION
203
204 Register table for use within the transaction. All tables
205 that are going to be used need to be registered before being
206 used below. The member function will fail with an error if
207 use_table() is called after any *_row() function has been
208 called for the transaction.
209
210 RETURN VALUE
211
212 0 All OK
213 >0 Failure
214
215 */
216 int use_table(server_id_type sid, table tbl);
217
218 /*
219 Add a 'write row' entry to the transaction.
220 */
221 int write_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
222 record_type record, const unsigned char *extra_row_info);
223 int write_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
225
226 /*
227 Add a 'delete row' entry to the transaction.
228 */
229 int delete_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
230 record_type record, const unsigned char *extra_row_info);
231 int delete_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
233 /*
234 Add an 'update row' entry to the transaction.
235 */
236 int update_row(server_id_type sid, table tbl, MY_BITMAP const *before_cols,
237 MY_BITMAP const *after_cols, record_type before,
238 record_type after, const unsigned char *extra_row_info);
239 int update_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
240 record_type before, record_type after);
241
242 /*
243 Commit a transaction.
244
245 This member function will clean up after a sequence of *_row calls by,
246 for example, releasing resource and unlocking files.
247 */
248 int commit();
249
250 /*
251 Rollback a transaction.
252
253 This member function will clean up after a sequence of *_row calls by,
254 for example, releasing resource and unlocking files.
255 */
256 int rollback();
257
258 /*
259 Get the position for the start of the transaction.
260
261 This is the current 'tail of Binlog' at the time the transaction
262 was started. The first event recorded by the transaction may
263 be at this, or some subsequent position. The first event recorded
264 by the transaction will not be before this position.
265 */
266 binlog_pos start_pos() const;
267
268 /*
269 Get the next position after the end of the transaction
270
271 This call is only valid after a transaction has been committed.
272 It returns the next Binlog position after the committed transaction.
273 It is guaranteed that no other events will be recorded between the
274 COMMIT event of the Binlog transaction, and this position.
275 Note that this position may be in a different log file to the COMMIT
276 event.
277
278 If the commit had an error, or the transaction was empty and nothing
279 was binlogged then the next_pos will have a NULL file_name(), and
280 0 file_pos().
281
282 */
283 binlog_pos next_pos() const;
284
285 private:
286 /* Only the injector may construct these object */
288
289 void swap(transaction &o) {
290 /* std::swap(m_start_pos, o.m_start_pos); */
291 {
292 binlog_pos const tmp = m_start_pos;
294 o.m_start_pos = tmp;
295 }
296
297 /* std::swap(m_end_pos, o.m_end_pos); */
298 {
299 binlog_pos const tmp = m_next_pos;
301 o.m_next_pos = tmp;
302 }
303
304 /* std::swap(m_thd, o.m_thd); */
305 {
306 THD *const tmp = m_thd;
307 m_thd = o.m_thd;
308 o.m_thd = tmp;
309 }
310 {
311 enum_state const tmp = m_state;
312 m_state = o.m_state;
313 o.m_state = tmp;
314 }
315 }
316
318 START_STATE, /* Start state */
319 TABLE_STATE, /* At least one table has been registered */
320 ROW_STATE, /* At least one row has been registered */
321 STATE_COUNT /* State count and sink state */
323
324 /*
325 Check and update the state.
326
327 PARAMETER(S)
328
329 target_state
330 The state we are moving to: TABLE_STATE if we are
331 writing a table and ROW_STATE if we are writing a row.
332
333 DESCRIPTION
334
335 The internal state will be updated to the target state if
336 and only if it is a legal move. The only legal moves are:
337
338 START_STATE -> START_STATE
339 START_STATE -> TABLE_STATE
340 TABLE_STATE -> TABLE_STATE
341 TABLE_STATE -> ROW_STATE
342
343 That is:
344 - It is not possible to write any row before having written at
345 least one table
346 - It is not possible to write a table after at least one row
347 has been written
348
349 RETURN VALUE
350
351 0 All OK
352 -1 Incorrect call sequence
353 */
354 int check_state(enum_state const target_state) {
355#ifndef NDEBUG
356 static char const *state_name[] = {"START_STATE", "TABLE_STATE",
357 "ROW_STATE", "STATE_COUNT"};
358
359 assert(0 <= target_state && target_state <= STATE_COUNT);
360 DBUG_PRINT("info", ("In state %s", state_name[m_state]));
361#endif
362
363 if (m_state <= target_state && target_state <= m_state + 1 &&
365 m_state = target_state;
366 else
368 return m_state == STATE_COUNT ? 1 : 0;
369 }
370
374 };
375
376 /*
377 Create a new transaction. This member function will prepare for a
378 sequence of *_row calls by, for example, reserving resources and
379 locking files. The call uses placement semantics and will overwrite
380 the transaction.
381
382 injector::transaction trans2;
383 inj->new_trans(thd, &trans);
384 */
385 void new_trans(THD *, transaction *);
386
387 int record_incident(THD *, std::string_view message);
388
389 private:
390 explicit injector();
391 ~injector() = default; /* Nothing needs to be done */
392 injector(injector const &); /* You're not allowed to copy injector
393 instances.
394 */
395};
396
397#endif /* INJECTOR_H */
Definition: binlog.h:139
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:34
Definition: rpl_injector.h:172
char const * m_file_name
Definition: rpl_injector.h:180
char const * file_name() const
Definition: rpl_injector.h:176
my_off_t file_pos() const
Definition: rpl_injector.h:177
my_off_t m_file_pos
Definition: rpl_injector.h:181
Definition: rpl_injector.h:133
MY_BITMAP * save_write_set
Definition: rpl_injector.h:151
TABLE *const m_table
Definition: rpl_injector.h:149
~save_sets()
Definition: rpl_injector.h:144
MY_BITMAP * save_read_set
Definition: rpl_injector.h:150
save_sets(table const &tbl, MY_BITMAP const *new_rs, MY_BITMAP const *new_ws)
Definition: rpl_injector.h:135
Definition: rpl_injector.h:131
const bool m_is_transactional
Definition: rpl_injector.h:165
const bool m_skip_hash
Definition: rpl_injector.h:166
TABLE * get_table() const
Definition: rpl_injector.h:159
TABLE *const m_table
Definition: rpl_injector.h:164
table(TABLE *table, bool is_transactional, bool skip_hash=false)
Definition: rpl_injector.h:154
bool skip_hash() const
Definition: rpl_injector.h:161
bool is_transactional() const
Definition: rpl_injector.h:160
Definition: rpl_injector.h:86
uchar * record_type
Definition: rpl_injector.h:91
bool good() const
Definition: rpl_injector.h:192
int write_row(server_id_type sid, table tbl, MY_BITMAP const *cols, record_type record, const unsigned char *extra_row_info)
Definition: rpl_injector.cc:177
void clear()
Definition: rpl_injector.h:189
enum_state
Definition: rpl_injector.h:317
@ ROW_STATE
Definition: rpl_injector.h:320
@ START_STATE
Definition: rpl_injector.h:318
@ STATE_COUNT
Definition: rpl_injector.h:321
@ TABLE_STATE
Definition: rpl_injector.h:319
binlog_pos m_start_pos
Definition: rpl_injector.h:371
binlog_pos next_pos() const
Definition: rpl_injector.cc:282
~transaction()
Definition: rpl_injector.cc:78
binlog_pos m_next_pos
Definition: rpl_injector.h:372
THD * m_thd
Definition: rpl_injector.h:373
int delete_row(server_id_type sid, table tbl, MY_BITMAP const *cols, record_type record, const unsigned char *extra_row_info)
Definition: rpl_injector.cc:209
int commit()
Definition: rpl_injector.cc:98
int use_table(server_id_type sid, table tbl)
Definition: rpl_injector.cc:165
uint32 server_id_type
Definition: rpl_injector.h:92
int check_state(enum_state const target_state)
Definition: rpl_injector.h:354
transaction(transaction const &)
binlog_pos start_pos() const
Definition: rpl_injector.cc:278
void swap(transaction &o)
Definition: rpl_injector.h:289
int update_row(server_id_type sid, table tbl, MY_BITMAP const *before_cols, MY_BITMAP const *after_cols, record_type before, record_type after, const unsigned char *extra_row_info)
Definition: rpl_injector.cc:241
enum injector::transaction::enum_state m_state
transaction()
Definition: rpl_injector.h:184
int rollback()
Definition: rpl_injector.cc:141
transaction & operator=(transaction t)
Definition: rpl_injector.h:195
Definition: rpl_injector.h:50
static injector * instance()
Definition: rpl_injector.cc:294
int record_incident(THD *, std::string_view message)
Definition: rpl_injector.cc:319
static void free_instance()
Definition: rpl_injector.cc:300
injector(injector const &)
void new_trans(THD *, transaction *)
Definition: rpl_injector.cc:309
static void get_current_binlog_filename(char(&filename)[FN_REFLEN])
Definition: rpl_injector.cc:323
~injector()=default
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:222
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:181
Some integer typedefs for easier portability.
ulonglong my_off_t
Definition: my_inttypes.h:72
unsigned char uchar
Definition: my_inttypes.h:52
uint32_t uint32
Definition: my_inttypes.h:67
#define FN_REFLEN
Definition: my_io.h:83
static int record
Definition: mysqltest.cc:188
const char * filename
Definition: pfs_example_component_population.cc:67
Definition: my_bitmap.h:43
Definition: table.h:1400
void column_bitmaps_set_no_signal(MY_BITMAP *read_set_arg, MY_BITMAP *write_set_arg)
Definition: table.h:1908