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