MySQL 8.0.39
Source Code Documentation
rpl_injector.h
Go to the documentation of this file.
1/* Copyright (c) 2006, 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 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 A transaction where rows can be added.
71
72 DESCRIPTION
73 The transaction class satisfy the **CopyConstructible** and
74 **Assignable** requirements. Note that the transaction is *not*
75 default constructible.
76 */
78 friend class injector;
79
80 public:
81 /* Convenience definitions */
84
85 /*
86 Table reference.
87
88 RESPONSIBILITY
89
90 The class contains constructors to handle several forms of
91 references to tables. The constructors can implicitly be used to
92 construct references from, e.g., strings containing table names.
93
94 EXAMPLE
95
96 The class is intended to be used *by value*. Please, do not try to
97 construct objects of this type using 'new'; instead construct an
98 object, possibly a temporary object. For example:
99
100 injector::transaction::table tbl(share->table, true);
101 MY_BITMAP cols;
102 bitmap_init(&cols, NULL, (i + 7) / 8, false);
103 inj->write_row(::server_id, tbl, &cols, row_data);
104
105 or
106
107 MY_BITMAP cols;
108 bitmap_init(&cols, NULL, (i + 7) / 8, false);
109 inj->write_row(::server_id,
110 injector::transaction::table(share->table, true),
111 &cols, row_data);
112
113 This will work, be more efficient, and have greater chance of
114 inlining, not run the risk of losing pointers.
115
116 COLLABORATION
117
118 injector::transaction
119 Provide a flexible interface to the representation of tables.
120
121 */
122 class table {
123 public:
124 class save_sets {
125 public:
126 save_sets(table const &tbl, MY_BITMAP const *new_rs,
127 MY_BITMAP const *new_ws)
128 : m_table(tbl.get_table()),
129 save_read_set(m_table->read_set),
130 save_write_set(m_table->write_set) {
132 const_cast<MY_BITMAP *>(new_rs), const_cast<MY_BITMAP *>(new_ws));
133 }
134
137 }
138
139 private:
143 };
144
146 : m_table(table),
149
150 TABLE *get_table() const { return m_table; }
151 bool is_transactional() const { return m_is_transactional; }
152 bool skip_hash() const { return m_skip_hash; }
153
154 private:
157 const bool m_skip_hash;
158 };
159
160 /*
161 Binlog position as a structure.
162 */
164 friend class transaction;
165
166 public:
167 char const *file_name() const { return m_file_name; }
168 my_off_t file_pos() const { return m_file_pos; }
169
170 private:
171 char const *m_file_name;
173 };
174
177 ~transaction();
178
179 /* Clear transaction, i.e., make calls to 'good()' return false. */
180 void clear() { m_thd = nullptr; }
181
182 /* Is the transaction in a good state? */
183 bool good() const { return m_thd != nullptr; }
184
185 /* Default assignment operator: standard implementation */
187 swap(t);
188 return *this;
189 }
190
191 /*
192
193 DESCRIPTION
194
195 Register table for use within the transaction. All tables
196 that are going to be used need to be registered before being
197 used below. The member function will fail with an error if
198 use_table() is called after any *_row() function has been
199 called for the transaction.
200
201 RETURN VALUE
202
203 0 All OK
204 >0 Failure
205
206 */
207 int use_table(server_id_type sid, table tbl);
208
209 /*
210 Add a 'write row' entry to the transaction.
211 */
212 int write_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
213 record_type record, const unsigned char *extra_row_info);
214 int write_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
216
217 /*
218 Add a 'delete row' entry to the transaction.
219 */
220 int delete_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
221 record_type record, const unsigned char *extra_row_info);
222 int delete_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
224 /*
225 Add an 'update row' entry to the transaction.
226 */
227 int update_row(server_id_type sid, table tbl, MY_BITMAP const *before_cols,
228 MY_BITMAP const *after_cols, record_type before,
229 record_type after, const unsigned char *extra_row_info);
230 int update_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
231 record_type before, record_type after);
232
233 /*
234 Commit a transaction.
235
236 This member function will clean up after a sequence of *_row calls by,
237 for example, releasing resource and unlocking files.
238 */
239 int commit();
240
241 /*
242 Rollback a transaction.
243
244 This member function will clean up after a sequence of *_row calls by,
245 for example, releasing resource and unlocking files.
246 */
247 int rollback();
248
249 /*
250 Get the position for the start of the transaction.
251
252 This is the current 'tail of Binlog' at the time the transaction
253 was started. The first event recorded by the transaction may
254 be at this, or some subsequent position. The first event recorded
255 by the transaction will not be before this position.
256 */
257 binlog_pos start_pos() const;
258
259 /*
260 Get the next position after the end of the transaction
261
262 This call is only valid after a transaction has been committed.
263 It returns the next Binlog position after the committed transaction.
264 It is guaranteed that no other events will be recorded between the
265 COMMIT event of the Binlog transaction, and this position.
266 Note that this position may be in a different log file to the COMMIT
267 event.
268
269 If the commit had an error, or the transaction was empty and nothing
270 was binlogged then the next_pos will have a NULL file_name(), and
271 0 file_pos().
272
273 */
274 binlog_pos next_pos() const;
275
276 private:
277 /* Only the injector may construct these object */
279
280 void swap(transaction &o) {
281 /* std::swap(m_start_pos, o.m_start_pos); */
282 {
283 binlog_pos const tmp = m_start_pos;
285 o.m_start_pos = tmp;
286 }
287
288 /* std::swap(m_end_pos, o.m_end_pos); */
289 {
290 binlog_pos const tmp = m_next_pos;
292 o.m_next_pos = tmp;
293 }
294
295 /* std::swap(m_thd, o.m_thd); */
296 {
297 THD *const tmp = m_thd;
298 m_thd = o.m_thd;
299 o.m_thd = tmp;
300 }
301 {
302 enum_state const tmp = m_state;
303 m_state = o.m_state;
304 o.m_state = tmp;
305 }
306 }
307
309 START_STATE, /* Start state */
310 TABLE_STATE, /* At least one table has been registered */
311 ROW_STATE, /* At least one row has been registered */
312 STATE_COUNT /* State count and sink state */
314
315 /*
316 Check and update the state.
317
318 PARAMETER(S)
319
320 target_state
321 The state we are moving to: TABLE_STATE if we are
322 writing a table and ROW_STATE if we are writing a row.
323
324 DESCRIPTION
325
326 The internal state will be updated to the target state if
327 and only if it is a legal move. The only legal moves are:
328
329 START_STATE -> START_STATE
330 START_STATE -> TABLE_STATE
331 TABLE_STATE -> TABLE_STATE
332 TABLE_STATE -> ROW_STATE
333
334 That is:
335 - It is not possible to write any row before having written at
336 least one table
337 - It is not possible to write a table after at least one row
338 has been written
339
340 RETURN VALUE
341
342 0 All OK
343 -1 Incorrect call sequence
344 */
345 int check_state(enum_state const target_state) {
346#ifndef NDEBUG
347 static char const *state_name[] = {"START_STATE", "TABLE_STATE",
348 "ROW_STATE", "STATE_COUNT"};
349
350 assert(0 <= target_state && target_state <= STATE_COUNT);
351 DBUG_PRINT("info", ("In state %s", state_name[m_state]));
352#endif
353
354 if (m_state <= target_state && target_state <= m_state + 1 &&
356 m_state = target_state;
357 else
359 return m_state == STATE_COUNT ? 1 : 0;
360 }
361
365 };
366
367 /*
368 Create a new transaction. This member function will prepare for a
369 sequence of *_row calls by, for example, reserving resources and
370 locking files. The call uses placement semantics and will overwrite
371 the transaction.
372
373 injector::transaction trans2;
374 inj->new_trans(thd, &trans);
375 */
376 void new_trans(THD *, transaction *);
377
378 int record_incident(THD *, std::string_view message);
379
380 private:
381 explicit injector();
382 ~injector() = default; /* Nothing needs to be done */
383 injector(injector const &); /* You're not allowed to copy injector
384 instances.
385 */
386};
387
388#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:163
char const * m_file_name
Definition: rpl_injector.h:171
char const * file_name() const
Definition: rpl_injector.h:167
my_off_t file_pos() const
Definition: rpl_injector.h:168
my_off_t m_file_pos
Definition: rpl_injector.h:172
Definition: rpl_injector.h:124
MY_BITMAP * save_write_set
Definition: rpl_injector.h:142
TABLE *const m_table
Definition: rpl_injector.h:140
~save_sets()
Definition: rpl_injector.h:135
MY_BITMAP * save_read_set
Definition: rpl_injector.h:141
save_sets(table const &tbl, MY_BITMAP const *new_rs, MY_BITMAP const *new_ws)
Definition: rpl_injector.h:126
Definition: rpl_injector.h:122
const bool m_is_transactional
Definition: rpl_injector.h:156
const bool m_skip_hash
Definition: rpl_injector.h:157
TABLE * get_table() const
Definition: rpl_injector.h:150
TABLE *const m_table
Definition: rpl_injector.h:155
table(TABLE *table, bool is_transactional, bool skip_hash=false)
Definition: rpl_injector.h:145
bool skip_hash() const
Definition: rpl_injector.h:152
bool is_transactional() const
Definition: rpl_injector.h:151
Definition: rpl_injector.h:77
uchar * record_type
Definition: rpl_injector.h:82
bool good() const
Definition: rpl_injector.h:183
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:180
enum_state
Definition: rpl_injector.h:308
@ ROW_STATE
Definition: rpl_injector.h:311
@ START_STATE
Definition: rpl_injector.h:309
@ STATE_COUNT
Definition: rpl_injector.h:312
@ TABLE_STATE
Definition: rpl_injector.h:310
binlog_pos m_start_pos
Definition: rpl_injector.h:362
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:363
THD * m_thd
Definition: rpl_injector.h:364
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:83
int check_state(enum_state const target_state)
Definition: rpl_injector.h:345
transaction(transaction const &)
binlog_pos start_pos() const
Definition: rpl_injector.cc:278
void swap(transaction &o)
Definition: rpl_injector.h:280
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:175
int rollback()
Definition: rpl_injector.cc:141
transaction & operator=(transaction t)
Definition: rpl_injector.h:186
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
~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
static int record
Definition: mysqltest.cc:188
Definition: my_bitmap.h:43
Definition: table.h:1399
void column_bitmaps_set_no_signal(MY_BITMAP *read_set_arg, MY_BITMAP *write_set_arg)
Definition: table.h:1907