MySQL 8.0.30
Source Code Documentation
rpl_injector.h
Go to the documentation of this file.
1/* Copyright (c) 2006, 2022, 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 also distributed 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 included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23#ifndef INJECTOR_H
24#define INJECTOR_H
25
26#include <stddef.h>
27
28#include "lex_string.h"
29#include "libbinlogevents/include/control_events.h" // enum_incidents
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
147
148 char const *db_name() const { return m_table->s->db.str; }
149 char const *table_name() const { return m_table->s->table_name.str; }
150 TABLE *get_table() const { return m_table; }
151 bool is_transactional() const { return m_is_transactional; }
152
153 private:
156 };
157
158 /*
159 Binlog position as a structure.
160 */
162 friend class transaction;
163
164 public:
165 char const *file_name() const { return m_file_name; }
166 my_off_t file_pos() const { return m_file_pos; }
167
168 private:
169 char const *m_file_name;
171 };
172
175 ~transaction();
176
177 /* Clear transaction, i.e., make calls to 'good()' return false. */
178 void clear() { m_thd = nullptr; }
179
180 /* Is the transaction in a good state? */
181 bool good() const { return m_thd != nullptr; }
182
183 /* Default assignment operator: standard implementation */
185 swap(t);
186 return *this;
187 }
188
189 /*
190
191 DESCRIPTION
192
193 Register table for use within the transaction. All tables
194 that are going to be used need to be registered before being
195 used below. The member function will fail with an error if
196 use_table() is called after any *_row() function has been
197 called for the transaction.
198
199 RETURN VALUE
200
201 0 All OK
202 >0 Failure
203
204 */
205 int use_table(server_id_type sid, table tbl);
206
207 /*
208 Add a 'write row' entry to the transaction.
209 */
210 int write_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
211 record_type record, const unsigned char *extra_row_info);
212 int write_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
214
215 /*
216 Add a 'delete row' entry to the transaction.
217 */
218 int delete_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
219 record_type record, const unsigned char *extra_row_info);
220 int delete_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
222 /*
223 Add an 'update row' entry to the transaction.
224 */
225 int update_row(server_id_type sid, table tbl, MY_BITMAP const *before_cols,
226 MY_BITMAP const *after_cols, record_type before,
227 record_type after, const unsigned char *extra_row_info);
228 int update_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
229 record_type before, record_type after);
230
231 /*
232 Commit a transaction.
233
234 This member function will clean up after a sequence of *_row calls by,
235 for example, releasing resource and unlocking files.
236 */
237 int commit();
238
239 /*
240 Rollback a transaction.
241
242 This member function will clean up after a sequence of *_row calls by,
243 for example, releasing resource and unlocking files.
244 */
245 int rollback();
246
247 /*
248 Get the position for the start of the transaction.
249
250 This is the current 'tail of Binlog' at the time the transaction
251 was started. The first event recorded by the transaction may
252 be at this, or some subsequent position. The first event recorded
253 by the transaction will not be before this position.
254 */
255 binlog_pos start_pos() const;
256
257 /*
258 Get the next position after the end of the transaction
259
260 This call is only valid after a transaction has been committed.
261 It returns the next Binlog position after the committed transaction.
262 It is guaranteed that no other events will be recorded between the
263 COMMIT event of the Binlog transaction, and this position.
264 Note that this position may be in a different log file to the COMMIT
265 event.
266
267 If the commit had an error, or the transaction was empty and nothing
268 was binlogged then the next_pos will have a NULL file_name(), and
269 0 file_pos().
270
271 */
272 binlog_pos next_pos() const;
273
274 private:
275 /* Only the injector may construct these object */
277
278 void swap(transaction &o) {
279 /* std::swap(m_start_pos, o.m_start_pos); */
280 {
281 binlog_pos const tmp = m_start_pos;
283 o.m_start_pos = tmp;
284 }
285
286 /* std::swap(m_end_pos, o.m_end_pos); */
287 {
288 binlog_pos const tmp = m_next_pos;
290 o.m_next_pos = tmp;
291 }
292
293 /* std::swap(m_thd, o.m_thd); */
294 {
295 THD *const tmp = m_thd;
296 m_thd = o.m_thd;
297 o.m_thd = tmp;
298 }
299 {
300 enum_state const tmp = m_state;
301 m_state = o.m_state;
302 o.m_state = tmp;
303 }
304 }
305
307 START_STATE, /* Start state */
308 TABLE_STATE, /* At least one table has been registered */
309 ROW_STATE, /* At least one row has been registered */
310 STATE_COUNT /* State count and sink state */
312
313 /*
314 Check and update the state.
315
316 PARAMETER(S)
317
318 target_state
319 The state we are moving to: TABLE_STATE if we are
320 writing a table and ROW_STATE if we are writing a row.
321
322 DESCRIPTION
323
324 The internal state will be updated to the target state if
325 and only if it is a legal move. The only legal moves are:
326
327 START_STATE -> START_STATE
328 START_STATE -> TABLE_STATE
329 TABLE_STATE -> TABLE_STATE
330 TABLE_STATE -> ROW_STATE
331
332 That is:
333 - It is not possible to write any row before having written at
334 least one table
335 - It is not possible to write a table after at least one row
336 has been written
337
338 RETURN VALUE
339
340 0 All OK
341 -1 Incorrect call sequence
342 */
343 int check_state(enum_state const target_state) {
344#ifndef NDEBUG
345 static char const *state_name[] = {"START_STATE", "TABLE_STATE",
346 "ROW_STATE", "STATE_COUNT"};
347
348 assert(0 <= target_state && target_state <= STATE_COUNT);
349 DBUG_PRINT("info", ("In state %s", state_name[m_state]));
350#endif
351
352 if (m_state <= target_state && target_state <= m_state + 1 &&
354 m_state = target_state;
355 else
357 return m_state == STATE_COUNT ? 1 : 0;
358 }
359
363 };
364
365 /*
366 Create a new transaction. This member function will prepare for a
367 sequence of *_row calls by, for example, reserving resources and
368 locking files. The call uses placement semantics and will overwrite
369 the transaction.
370
371 injector::transaction trans2;
372 inj->new_trans(thd, &trans);
373 */
374 void new_trans(THD *, transaction *);
375
377 LEX_CSTRING const message);
378
379 private:
380 explicit injector();
381 ~injector() = default; /* Nothing needs to be done */
382 injector(injector const &); /* You're not allowed to copy injector
383 instances.
384 */
385};
386
387#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_class.h:922
enum_incident
Enumeration of the incidents that can occur for the server.
Definition: control_events.h:436
Definition: rpl_injector.h:161
char const * m_file_name
Definition: rpl_injector.h:169
char const * file_name() const
Definition: rpl_injector.h:165
my_off_t file_pos() const
Definition: rpl_injector.h:166
my_off_t m_file_pos
Definition: rpl_injector.h:170
Definition: rpl_injector.h:124
MY_BITMAP * save_write_set
Definition: rpl_injector.h:142
~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
TABLE * m_table
Definition: rpl_injector.h:140
Definition: rpl_injector.h:122
table(TABLE *table, bool is_transactional)
Definition: rpl_injector.h:145
char const * db_name() const
Definition: rpl_injector.h:148
TABLE * get_table() const
Definition: rpl_injector.h:150
TABLE * m_table
Definition: rpl_injector.h:154
bool m_is_transactional
Definition: rpl_injector.h:155
char const * table_name() const
Definition: rpl_injector.h:149
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:181
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:166
void clear()
Definition: rpl_injector.h:178
enum_state
Definition: rpl_injector.h:306
@ ROW_STATE
Definition: rpl_injector.h:309
@ START_STATE
Definition: rpl_injector.h:307
@ STATE_COUNT
Definition: rpl_injector.h:310
@ TABLE_STATE
Definition: rpl_injector.h:308
binlog_pos m_start_pos
Definition: rpl_injector.h:360
binlog_pos next_pos() const
Definition: rpl_injector.cc:244
~transaction()
Definition: rpl_injector.cc:77
binlog_pos m_next_pos
Definition: rpl_injector.h:361
THD * m_thd
Definition: rpl_injector.h:362
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:190
int commit()
Definition: rpl_injector.cc:97
int use_table(server_id_type sid, table tbl)
Definition: rpl_injector.cc:151
uint32 server_id_type
Definition: rpl_injector.h:83
int check_state(enum_state const target_state)
Definition: rpl_injector.h:343
transaction(transaction const &)
binlog_pos start_pos() const
Definition: rpl_injector.cc:240
void swap(transaction &o)
Definition: rpl_injector.h:278
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:213
enum injector::transaction::enum_state m_state
transaction()
Definition: rpl_injector.h:173
int rollback()
Definition: rpl_injector.cc:140
transaction & operator=(transaction t)
Definition: rpl_injector.h:184
Definition: rpl_injector.h:50
static injector * instance()
Definition: rpl_injector.cc:256
static void free_instance()
Definition: rpl_injector.cc:262
int record_incident(THD *, binary_log::Incident_event::enum_incident incident, LEX_CSTRING const message)
Definition: rpl_injector.cc:281
injector(injector const &)
void new_trans(THD *, transaction *)
Definition: rpl_injector.cc:271
~injector()=default
Contains the classes representing events operating in the replication stream properties.
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:221
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:180
Some integer typedefs for easier portability.
ulonglong my_off_t
Definition: my_inttypes.h:71
unsigned char uchar
Definition: my_inttypes.h:51
uint32_t uint32
Definition: my_inttypes.h:66
Definition: mysql_lex_string.h:39
const char * str
Definition: mysql_lex_string.h:40
Definition: my_bitmap.h:42
LEX_CSTRING table_name
Definition: table.h:771
LEX_CSTRING db
Definition: table.h:770
Definition: table.h:1394
void column_bitmaps_set_no_signal(MY_BITMAP *read_set_arg, MY_BITMAP *write_set_arg)
Definition: table.h:1812
TABLE_SHARE * s
Definition: table.h:1395
Definition: mi_test3.cc:54