MySQL 8.4.0
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 "my_dbug.h"
31#include "my_inttypes.h"
32#include "my_io.h" // FN_REFLEN
33#include "mysql/binlog/event/control_events.h" // enum_incidents
34#include "sql/table.h" // TABLE
35
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 public:
80 /* Convenience definitions */
83
84 /*
85 Table reference.
86
87 RESPONSIBILITY
88
89 The class contains constructors to handle several forms of
90 references to tables. The constructors can implicitly be used to
91 construct references from, e.g., strings containing table names.
92
93 EXAMPLE
94
95 The class is intended to be used *by value*. Please, do not try to
96 construct objects of this type using 'new'; instead construct an
97 object, possibly a temporary object. For example:
98
99 injector::transaction::table tbl(share->table, true);
100 MY_BITMAP cols;
101 bitmap_init(&cols, NULL, (i + 7) / 8, false);
102 inj->write_row(::server_id, tbl, &cols, row_data);
103
104 or
105
106 MY_BITMAP cols;
107 bitmap_init(&cols, NULL, (i + 7) / 8, false);
108 inj->write_row(::server_id,
109 injector::transaction::table(share->table, true),
110 &cols, row_data);
111
112 This will work, be more efficient, and have greater chance of
113 inlining, not run the risk of losing pointers.
114
115 COLLABORATION
116
117 injector::transaction
118 Provide a flexible interface to the representation of tables.
119
120 */
121 class table {
122 public:
123 class save_sets {
124 public:
125 save_sets(table const &tbl, MY_BITMAP const *new_rs,
126 MY_BITMAP const *new_ws)
127 : m_table(tbl.get_table()),
128 save_read_set(m_table->read_set),
129 save_write_set(m_table->write_set) {
131 const_cast<MY_BITMAP *>(new_rs), const_cast<MY_BITMAP *>(new_ws));
132 }
133
136 }
137
138 private:
142 };
143
145 : m_table(table),
148
149 char const *db_name() const { return m_table->s->db.str; }
150 char const *table_name() const { return m_table->s->table_name.str; }
151 TABLE *get_table() const { return m_table; }
152 bool is_transactional() const { return m_is_transactional; }
153 bool skip_hash() const { return m_skip_hash; }
154
155 private:
158 const bool m_skip_hash;
159 };
160
161 /*
162 Binlog position as a structure.
163 */
165 friend class transaction;
166
167 public:
168 char const *file_name() const { return m_file_name; }
169 my_off_t file_pos() const { return m_file_pos; }
170
171 private:
172 char const *m_file_name;
174 };
175
176 /*
177 Create a new transaction.
178
179 The parameter "calc_writeset_hash" controls whether writeset hashes for
180 transaction dependencies will be calculated for rows added to the
181 transaction, without this the list of hashes will be empty and thus no
182 dependencies are detected. The ability to control this is important where
183 MTA is not used, calculating writeset hashes is wasted work, and in NDB
184 all binlog content is processed by a single thread and CPU consumption
185 might be a bottleneck.
186 */
187 transaction(THD *thd, bool calc_writeset_hash);
188 transaction(const transaction &) = delete;
189 transaction(const transaction &&) = delete;
191 transaction &operator=(const transaction &&) = delete;
192
194
195 /*
196
197 DESCRIPTION
198
199 Register table for use within the transaction. All tables
200 that are going to be used need to be registered before being
201 used below. The member function will fail with an error if
202 use_table() is called after any *_row() function has been
203 called for the transaction.
204
205 RETURN VALUE
206
207 0 All OK
208 >0 Failure
209
210 */
211 int use_table(server_id_type sid, table tbl);
212
213 /*
214 Add a 'write row' entry to the transaction.
215 */
216 int write_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
217 record_type record, const unsigned char *extra_row_info);
218
219 /*
220 Add a 'delete row' entry to the transaction.
221 */
222 int delete_row(server_id_type sid, table tbl, MY_BITMAP const *cols,
223 record_type record, const unsigned char *extra_row_info);
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
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:
276 START_STATE, /* Start state */
277 TABLE_STATE, /* At least one table has been registered */
278 ROW_STATE, /* At least one row has been registered */
279 STATE_COUNT /* State count and sink state */
281
282 /*
283 Check and update the state.
284
285 PARAMETER(S)
286
287 target_state
288 The state we are moving to: TABLE_STATE if we are
289 writing a table and ROW_STATE if we are writing a row.
290
291 DESCRIPTION
292
293 The internal state will be updated to the target state if
294 and only if it is a legal move. The only legal moves are:
295
296 START_STATE -> START_STATE
297 START_STATE -> TABLE_STATE
298 TABLE_STATE -> TABLE_STATE
299 TABLE_STATE -> ROW_STATE
300
301 That is:
302 - It is not possible to write any row before having written at
303 least one table
304 - It is not possible to write a table after at least one row
305 has been written
306
307 RETURN VALUE
308
309 0 All OK
310 -1 Incorrect call sequence
311 */
312 int check_state(enum_state const target_state) {
313#ifndef NDEBUG
314 static char const *state_name[] = {"START_STATE", "TABLE_STATE",
315 "ROW_STATE", "STATE_COUNT"};
316
317 assert(0 <= target_state && target_state <= STATE_COUNT);
318 DBUG_PRINT("info", ("In state %s", state_name[m_state]));
319#endif
320
321 if (m_state <= target_state && target_state <= m_state + 1 &&
323 m_state = target_state;
324 else
326 return m_state == STATE_COUNT ? 1 : 0;
327 }
328
333 THD *const m_thd;
334 const bool m_calc_writeset_hash{false};
335 };
336
337 int record_incident(
339 const LEX_CSTRING &message);
340
341 private:
342 explicit injector();
343 ~injector() = default; /* Nothing needs to be done */
344 injector(injector const &); /* You're not allowed to copy injector
345 instances.
346 */
347};
348
349#endif /* INJECTOR_H */
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:36
Definition: rpl_injector.h:164
char const * m_file_name
Definition: rpl_injector.h:172
char const * file_name() const
Definition: rpl_injector.h:168
my_off_t file_pos() const
Definition: rpl_injector.h:169
my_off_t m_file_pos
Definition: rpl_injector.h:173
Definition: rpl_injector.h:123
MY_BITMAP * save_write_set
Definition: rpl_injector.h:141
TABLE *const m_table
Definition: rpl_injector.h:139
~save_sets()
Definition: rpl_injector.h:134
MY_BITMAP * save_read_set
Definition: rpl_injector.h:140
save_sets(table const &tbl, MY_BITMAP const *new_rs, MY_BITMAP const *new_ws)
Definition: rpl_injector.h:125
Definition: rpl_injector.h:121
char const * db_name() const
Definition: rpl_injector.h:149
const bool m_is_transactional
Definition: rpl_injector.h:157
const bool m_skip_hash
Definition: rpl_injector.h:158
TABLE * get_table() const
Definition: rpl_injector.h:151
TABLE *const m_table
Definition: rpl_injector.h:156
table(TABLE *table, bool is_transactional, bool skip_hash=false)
Definition: rpl_injector.h:144
bool skip_hash() const
Definition: rpl_injector.h:153
char const * table_name() const
Definition: rpl_injector.h:150
bool is_transactional() const
Definition: rpl_injector.h:152
Definition: rpl_injector.h:78
transaction(const transaction &)=delete
uchar * record_type
Definition: rpl_injector.h:81
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:152
enum_state
Definition: rpl_injector.h:275
@ ROW_STATE
Definition: rpl_injector.h:278
@ START_STATE
Definition: rpl_injector.h:276
@ STATE_COUNT
Definition: rpl_injector.h:279
@ TABLE_STATE
Definition: rpl_injector.h:277
binlog_pos m_start_pos
Definition: rpl_injector.h:331
transaction & operator=(const transaction &&)=delete
binlog_pos next_pos() const
Definition: rpl_injector.cc:236
~transaction()
Definition: rpl_injector.h:193
binlog_pos m_next_pos
Definition: rpl_injector.h:332
THD *const m_thd
Definition: rpl_injector.h:333
char m_end_name_buf[FN_REFLEN]
Definition: rpl_injector.h:330
transaction & operator=(const transaction &)=delete
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:177
int commit()
Definition: rpl_injector.cc:73
int use_table(server_id_type sid, table tbl)
Definition: rpl_injector.cc:140
transaction(const transaction &&)=delete
uint32 server_id_type
Definition: rpl_injector.h:82
int check_state(enum_state const target_state)
Definition: rpl_injector.h:312
transaction(THD *thd, bool calc_writeset_hash)
Definition: rpl_injector.cc:38
binlog_pos start_pos() const
Definition: rpl_injector.cc:232
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:202
char m_start_name_buf[FN_REFLEN]
Definition: rpl_injector.h:329
enum injector::transaction::enum_state m_state
int rollback()
Definition: rpl_injector.cc:116
const bool m_calc_writeset_hash
Definition: rpl_injector.h:334
Definition: rpl_injector.h:51
static injector * instance()
Definition: rpl_injector.cc:248
int record_incident(THD *, mysql::binlog::event::Incident_event::enum_incident incident, const LEX_CSTRING &message)
Definition: rpl_injector.cc:263
static void free_instance()
Definition: rpl_injector.cc:254
injector(injector const &)
~injector()=default
enum_incident
Enumeration of the incidents that can occur for the server.
Definition: control_events.h:445
Contains the classes representing events operating in the replication stream properties.
#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
Common #defines and includes for file and socket I/O.
#define FN_REFLEN
Definition: my_io.h:83
static int record
Definition: mysqltest.cc:195
static PFS_engine_table_share_proxy table
Definition: pfs.cc:61
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:779
LEX_CSTRING db
Definition: table.h:778
Definition: table.h:1405
void column_bitmaps_set_no_signal(MY_BITMAP *read_set_arg, MY_BITMAP *write_set_arg)
Definition: table.h:1961
TABLE_SHARE * s
Definition: table.h:1406