MySQL  8.0.28
Source Code Documentation
transaction_info.h
Go to the documentation of this file.
1 /* Copyright (c) 2000, 2021, 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 TRANSACTION_INFO_INCLUDED
24 #define TRANSACTION_INFO_INCLUDED
25 
26 #include <stddef.h>
27 #include <sys/types.h>
28 
29 #include "my_alloc.h"
30 #include "my_dbug.h"
31 #include "my_inttypes.h"
32 #include "my_sys.h" // strmake_root
33 #include "sql/mdl.h" // MDL_savepoint
34 #include "sql/rpl_transaction_ctx.h" // Rpl_transaction_ctx
35 #include "sql/rpl_transaction_write_set_ctx.h" // Transaction_write_set_ctx
36 #include "sql/xa.h" // XID_STATE
37 
38 class Ha_trx_info;
39 class THD;
40 struct handlerton;
41 
42 struct SAVEPOINT {
44  char *name;
45  size_t length;
47  /** State of metadata locks before this savepoint was set. */
49 };
50 
52  public:
53  enum enum_trx_scope { STMT = 0, SESSION };
54 
56 
57  void register_ha(enum_trx_scope scope, Ha_trx_info *ha_info, handlerton *ht);
58 
59  public:
60  struct THD_TRANS {
61  /* true is not all entries in the ht[] support 2pc */
62  bool m_no_2pc;
64  /* storage engines that registered in this transaction */
66 
67  private:
68  /*
69  The purpose of this member variable (i.e. flag) is to keep track of
70  statements which cannot be rolled back safely(completely).
71  For example,
72 
73  * statements that modified non-transactional tables. The value
74  MODIFIED_NON_TRANS_TABLE is set within mysql_insert, mysql_update,
75  mysql_delete, etc if a non-transactional table is modified.
76 
77  * 'DROP TEMPORARY TABLE' and 'CREATE TEMPORARY TABLE' statements.
78  The former sets the value DROPPED_TEMP_TABLE and the latter
79  the value CREATED_TEMP_TABLE.
80 
81  The tracked statements are modified in scope of:
82 
83  * transaction, when the variable is a member of
84  THD::m_transaction.m_scope_info[SESSION]
85 
86  * top-level statement or sub-statement, when the variable is a
87  member of THD::m_transaction.m_scope_info[STMT]
88 
89  This member has the following life cycle:
90 
91  * m_scope_info[STMT].m_unsafe_rollback_flags is used to keep track of
92  top-level statements which cannot be rolled back safely. At the end of the
93  statement, the value of m_scope_info[STMT].m_unsafe_rollback_flags is
94  merged with m_scope_info[SESSION].m_unsafe_rollback_flags
95  and gets reset.
96 
97  * m_scope_info[SESSION].cannot_safely_rollback is reset at the end
98  of transaction
99 
100  * Since we do not have a dedicated context for execution of
101  a sub-statement, to keep track of non-transactional changes in a
102  sub-statement, we re-use m_scope_info[STMT].m_unsafe_rollback_flags.
103  At entrance into a sub-statement, a copy of the value of
104  m_scope_info[STMT].m_unsafe_rollback_flags (containing the changes of the
105  outer statement) is saved on stack.
106  Then m_scope_info[STMT].m_unsafe_rollback_flags is reset to 0 and the
107  substatement is executed. Then the new value is merged
108  with the saved value.
109  */
110 
112  /*
113  Define the type of statements which cannot be rolled back safely.
114  Each type occupies one bit in m_unsafe_rollback_flags.
115  */
116  static unsigned int const MODIFIED_NON_TRANS_TABLE = 0x01;
117  static unsigned int const CREATED_TEMP_TABLE = 0x02;
118  static unsigned int const DROPPED_TEMP_TABLE = 0x04;
119 
120  public:
121  bool cannot_safely_rollback() const { return m_unsafe_rollback_flags > 0; }
122  unsigned int get_unsafe_rollback_flags() const {
124  }
125  void set_unsafe_rollback_flags(unsigned int flags) {
126  DBUG_PRINT("debug", ("set_unsafe_rollback_flags: %d", flags));
128  }
129  void add_unsafe_rollback_flags(unsigned int flags) {
130  DBUG_PRINT("debug", ("add_unsafe_rollback_flags: %d", flags));
132  }
134  DBUG_PRINT("debug", ("reset_unsafe_rollback_flags"));
136  }
138  DBUG_PRINT("debug", ("mark_modified_non_trans_table"));
140  }
143  }
145  DBUG_PRINT("debug", ("mark_created_temp_table"));
147  }
148  bool has_created_temp_table() const {
150  }
152  DBUG_PRINT("debug", ("mark_dropped_temp_table"));
154  }
155  bool has_dropped_temp_table() const {
157  }
158 
159  void reset() {
160  m_no_2pc = false;
161  m_rw_ha_count = 0;
163  }
164  bool is_empty() const { return m_ha_list == nullptr; }
165  };
166 
167  private:
169 
171 
172  MEM_ROOT m_mem_root; // Transaction-life memory allocation pool
173 
174  public:
175  /*
176  (Mostly) binlog-specific fields use while flushing the caches
177  and committing transactions.
178  We don't use bitfield any more in the struct. Modification will
179  be lost when concurrently updating multiple bit fields. It will
180  cause a race condition in a multi-threaded application. And we
181  already caught a race condition case between xid_written and
182  ready_preempt in MYSQL_BIN_LOG::ordered_commit.
183  */
184  struct {
185  bool enabled; // see ha_enable_transaction()
186  bool xid_written; // The session wrote an XID
187  bool real_commit; // Is this a "real" commit?
188  bool commit_low; // see MYSQL_BIN_LOG::ordered_commit
189  bool run_hooks; // Call the after_commit hook
190 #ifndef NDEBUG
191  bool ready_preempt; // internal in MYSQL_BIN_LOG::ordered_commit
192 #endif
194  /* Binlog-specific logical timestamps. */
195  /*
196  Store for the transaction's commit parent sequence_number.
197  The value specifies this transaction dependency with a "parent"
198  transaction.
199  The member is assigned, when the transaction is about to commit
200  in binlog to a value of the last committed transaction's sequence_number.
201  This and last_committed as numbers are kept ever incremented
202  regardless of binary logs being rotated or when transaction
203  is logged in multiple pieces.
204  However the logger to the binary log may convert them
205  according to its specification.
206  */
208  /*
209  The transaction's private logical timestamp assigned at the
210  transaction prepare phase. The timestamp enumerates transactions
211  in the binary log. The value is gained through incrementing (stepping) a
212  global clock.
213  Eventually the value is considered to increase max_committed_transaction
214  system clock when the transaction has committed.
215  */
217 
218  void store_commit_parent(int64 last_arg) { last_committed = last_arg; }
219 
220  Transaction_ctx();
222 
223  void cleanup() {
224  DBUG_TRACE;
225  m_savepoints = nullptr;
229  trans_begin_hook_invoked = false;
231  return;
232  }
233 
234  bool is_active(enum_trx_scope scope) const {
235  return m_scope_info[scope].m_ha_list != nullptr;
236  }
237 
239 
241  /*
242  Merge m_scope_info[STMT].unsafe_rollback_flags to
243  m_scope_info[SESSION].unsafe_rollback_flags. If the statement
244  cannot be rolled back safely, the transaction including
245  this statement definitely cannot rolled back safely.
246  */
249  }
250 
251  void init_mem_root_defaults(ulong trans_alloc_block_size, ulong) {
252  m_mem_root.set_block_size(trans_alloc_block_size);
253  }
254 
256 
257  void *allocate_memory(unsigned int size) { return m_mem_root.Alloc(size); }
258 
259  void claim_memory_ownership(bool claim) { m_mem_root.Claim(claim); }
260 
262 
263  char *strmake(const char *str, size_t len) {
264  return strmake_root(&m_mem_root, str, len);
265  }
266 
268 
270 
272  return m_scope_info[scope].m_ha_list;
273  }
274 
275  const Ha_trx_info *ha_trx_info(enum_trx_scope scope) const {
276  return m_scope_info[scope].m_ha_list;
277  }
278 
279  void set_ha_trx_info(enum_trx_scope scope, Ha_trx_info *trx_info) {
280  DBUG_TRACE;
281  m_scope_info[scope].m_ha_list = trx_info;
282  return;
283  }
284 
286 
287  const XID_STATE *xid_state() const { return &m_xid_state; }
288 
290  return m_scope_info[scope].cannot_safely_rollback();
291  }
292 
293  unsigned int get_unsafe_rollback_flags(enum_trx_scope scope) const {
294  return m_scope_info[scope].get_unsafe_rollback_flags();
295  }
296 
297  void set_unsafe_rollback_flags(enum_trx_scope scope, unsigned int flags) {
299  }
300 
301  void add_unsafe_rollback_flags(enum_trx_scope scope, unsigned int flags) {
303  }
304 
307  }
308 
311  }
312 
315  }
316 
319  }
320 
322  return m_scope_info[scope].has_created_temp_table();
323  }
324 
327  }
328 
330  return m_scope_info[scope].has_dropped_temp_table();
331  }
332 
333  void reset(enum_trx_scope scope) { m_scope_info[scope].reset(); }
334 
335  bool is_empty(enum_trx_scope scope) const {
336  return m_scope_info[scope].is_empty();
337  }
338 
339  void set_no_2pc(enum_trx_scope scope, bool value) {
340  m_scope_info[scope].m_no_2pc = value;
341  }
342 
343  bool no_2pc(enum_trx_scope scope) const {
344  return m_scope_info[scope].m_no_2pc;
345  }
346 
347  int rw_ha_count(enum_trx_scope scope) const {
348  return m_scope_info[scope].m_rw_ha_count;
349  }
350 
353  }
354 
356  DBUG_TRACE;
357  m_scope_info[scope].m_ha_list = nullptr;
358  m_scope_info[scope].m_no_2pc = false;
359  m_scope_info[scope].m_rw_ha_count = 0;
360  return;
361  }
362 
364  return &m_rpl_transaction_ctx;
365  }
366 
368  return &m_rpl_transaction_ctx;
369  }
370 
373  }
374 
377  }
378 
380 
382 
383  private:
387 };
388 
389 /**
390  Either statement transaction or normal transaction - related
391  thread-specific storage engine data.
392 
393  If a storage engine participates in a statement/transaction,
394  an instance of this class is present in
395  thd->m_transaction.m_scope_info[STMT|SESSION].ha_list. The addition
396  this list is made by trans_register_ha().
397 
398  When it's time to commit or rollback, each element of ha_list
399  is used to access storage engine's prepare()/commit()/rollback()
400  methods, and also to evaluate if a full two phase commit is
401  necessary.
402 
403  @sa General description of transaction handling in handler.cc.
404 */
405 
406 class Ha_trx_info {
407  public:
408  /**
409  Register this storage engine in the given transaction context.
410  */
411 
413  DBUG_TRACE;
414  assert(m_flags == 0);
415  assert(m_ht == nullptr);
416  assert(m_next == nullptr);
417 
418  m_ht = ht_arg;
419  m_flags = (int)TRX_READ_ONLY; /* Assume read-only at start. */
420 
421  if (trans->m_ha_list != this) {
422  m_next = trans->m_ha_list;
423  trans->m_ha_list = this;
424  }
425 
426  return;
427  }
428 
429  /**
430  Clear, prepare for reuse.
431  */
432 
433  void reset() {
434  DBUG_TRACE;
435  m_next = nullptr;
436  m_ht = nullptr;
437  m_flags = 0;
438  return;
439  }
440 
442 
444  assert(is_started());
445  m_flags |= (int)TRX_READ_WRITE;
446  }
447 
448  bool is_trx_read_write() const {
449  assert(is_started());
450  return m_flags & (int)TRX_READ_WRITE;
451  }
452 
453  bool is_started() const { return m_ht != nullptr; }
454 
455  /**
456  Mark this transaction read-write if the argument is read-write.
457  */
458 
459  void coalesce_trx_with(const Ha_trx_info *stmt_trx) {
460  /*
461  Must be called only after the transaction has been started.
462  Can be called many times, e.g. when we have many
463  read-write statements in a transaction.
464  */
465  assert(is_started());
466  if (stmt_trx->is_trx_read_write()) set_trx_read_write();
467  }
468 
469  Ha_trx_info *next() const {
470  assert(is_started());
471  return m_next;
472  }
473 
474  handlerton *ht() const {
475  assert(is_started());
476  return m_ht;
477  }
478 
479  private:
480  enum { TRX_READ_ONLY = 0, TRX_READ_WRITE = 1 };
481  /**
482  Auxiliary, used for ha_list management
483  */
485 
486  /**
487  Although a given Ha_trx_info instance is currently always used
488  for the same storage engine, 'ht' is not-NULL only when the
489  corresponding storage is a part of a transaction.
490  */
492 
493  /**
494  Transaction flags related to this engine.
495  Not-null only if this instance is a part of transaction.
496  May assume a combination of enum values above.
497  */
499 };
500 
501 #endif
Either statement transaction or normal transaction - related thread-specific storage engine data.
Definition: transaction_info.h:406
handlerton * ht() const
Definition: transaction_info.h:474
Ha_trx_info * next() const
Definition: transaction_info.h:469
bool is_started() const
Definition: transaction_info.h:453
handlerton * m_ht
Although a given Ha_trx_info instance is currently always used for the same storage engine,...
Definition: transaction_info.h:491
bool is_trx_read_write() const
Definition: transaction_info.h:448
@ TRX_READ_WRITE
Definition: transaction_info.h:480
@ TRX_READ_ONLY
Definition: transaction_info.h:480
Ha_trx_info * m_next
Auxiliary, used for ha_list management.
Definition: transaction_info.h:484
void reset()
Clear, prepare for reuse.
Definition: transaction_info.h:433
void set_trx_read_write()
Definition: transaction_info.h:443
Ha_trx_info()
Definition: transaction_info.h:441
void coalesce_trx_with(const Ha_trx_info *stmt_trx)
Mark this transaction read-write if the argument is read-write.
Definition: transaction_info.h:459
void register_ha(Transaction_ctx::THD_TRANS *trans, handlerton *ht_arg)
Register this storage engine in the given transaction context.
Definition: transaction_info.h:412
uchar m_flags
Transaction flags related to this engine.
Definition: transaction_info.h:498
Savepoint for MDL context.
Definition: mdl.h:1312
Server side support to provide a service to plugins to report if a given transaction should continue ...
Definition: rpl_transaction_ctx.h:35
void cleanup()
Reset transaction context to default values.
Definition: rpl_transaction_ctx.cc:41
Thread class responsible for the collection of write sets associated to a transaction.
Definition: rpl_transaction_write_set_ctx.h:100
void reset_state()
Reset the object so it can be used for a new transaction.
Definition: rpl_transaction_write_set_ctx.cc:102
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:945
Definition: transaction_info.h:51
Rpl_transaction_write_set_ctx * get_transaction_write_set_ctx()
Definition: transaction_info.h:371
void set_rw_ha_count(enum_trx_scope scope, int value)
Definition: transaction_info.h:351
void merge_unsafe_rollback_flags()
Definition: transaction_info.h:240
Rpl_transaction_write_set_ctx m_transaction_write_set_ctx
Definition: transaction_info.h:385
bool has_created_temp_table(enum_trx_scope scope) const
Definition: transaction_info.h:321
XID_STATE * xid_state()
Definition: transaction_info.h:285
bool is_active(enum_trx_scope scope) const
Definition: transaction_info.h:234
bool cannot_safely_rollback(enum_trx_scope scope) const
Definition: transaction_info.h:289
bool enabled
Definition: transaction_info.h:185
void register_ha(enum_trx_scope scope, Ha_trx_info *ha_info, handlerton *ht)
Definition: transaction_info.cc:76
virtual ~Transaction_ctx()
Definition: transaction_info.h:221
bool was_trans_begin_hook_invoked()
Definition: transaction_info.h:379
bool no_2pc(enum_trx_scope scope) const
Definition: transaction_info.h:343
void set_trans_begin_hook_invoked()
Definition: transaction_info.h:381
MEM_ROOT m_mem_root
Definition: transaction_info.h:172
SAVEPOINT * m_savepoints
Definition: transaction_info.h:55
int64 last_committed
Definition: transaction_info.h:207
bool real_commit
Definition: transaction_info.h:187
struct Transaction_ctx::@169 m_flags
void reset_unsafe_rollback_flags(enum_trx_scope scope)
Definition: transaction_info.h:305
Transaction_ctx()
Definition: transaction_info.cc:42
const XID_STATE * xid_state() const
Definition: transaction_info.h:287
void push_unsafe_rollback_warnings(THD *thd)
Definition: transaction_info.cc:57
MEM_ROOT * transaction_memroot()
Definition: transaction_info.h:255
const Ha_trx_info * ha_trx_info(enum_trx_scope scope) const
Definition: transaction_info.h:275
bool run_hooks
Definition: transaction_info.h:189
bool commit_low
Definition: transaction_info.h:188
XID_STATE m_xid_state
Definition: transaction_info.h:170
void reset(enum_trx_scope scope)
Definition: transaction_info.h:333
void * allocate_memory(unsigned int size)
Definition: transaction_info.h:257
int64 sequence_number
Definition: transaction_info.h:216
void init_mem_root_defaults(ulong trans_alloc_block_size, ulong)
Definition: transaction_info.h:251
void store_commit_parent(int64 last_arg)
Definition: transaction_info.h:218
int rw_ha_count(enum_trx_scope scope) const
Definition: transaction_info.h:347
void add_changed_table(const char *key, uint32 key_length)
bool trans_begin_hook_invoked
Definition: transaction_info.h:386
void set_unsafe_rollback_flags(enum_trx_scope scope, unsigned int flags)
Definition: transaction_info.h:297
bool xid_written
Definition: transaction_info.h:186
void claim_memory_ownership(bool claim)
Definition: transaction_info.h:259
unsigned int get_unsafe_rollback_flags(enum_trx_scope scope) const
Definition: transaction_info.h:293
void mark_modified_non_trans_table(enum_trx_scope scope)
Definition: transaction_info.h:309
void reset_scope(enum_trx_scope scope)
Definition: transaction_info.h:355
void free_memory()
Definition: transaction_info.h:261
void invalidate_changed_tables_in_cache(THD *thd)
void add_unsafe_rollback_flags(enum_trx_scope scope, unsigned int flags)
Definition: transaction_info.h:301
const Rpl_transaction_write_set_ctx * get_transaction_write_set_ctx() const
Definition: transaction_info.h:375
void cleanup()
Definition: transaction_info.h:223
void mark_created_temp_table(enum_trx_scope scope)
Definition: transaction_info.h:317
Rpl_transaction_ctx * get_rpl_transaction_ctx()
Definition: transaction_info.h:363
void set_no_2pc(enum_trx_scope scope, bool value)
Definition: transaction_info.h:339
bool has_dropped_temp_table(enum_trx_scope scope) const
Definition: transaction_info.h:329
bool has_modified_non_trans_table(enum_trx_scope scope) const
Definition: transaction_info.h:313
bool ready_preempt
Definition: transaction_info.h:191
void mark_dropped_temp_table(enum_trx_scope scope)
Definition: transaction_info.h:325
Ha_trx_info * ha_trx_info(enum_trx_scope scope)
Definition: transaction_info.h:271
Rpl_transaction_ctx m_rpl_transaction_ctx
Definition: transaction_info.h:384
THD_TRANS m_scope_info[2]
Definition: transaction_info.h:168
void set_ha_trx_info(enum_trx_scope scope, Ha_trx_info *trx_info)
Definition: transaction_info.h:279
bool is_empty(enum_trx_scope scope) const
Definition: transaction_info.h:335
const Rpl_transaction_ctx * get_rpl_transaction_ctx() const
Definition: transaction_info.h:367
enum_trx_scope
Definition: transaction_info.h:53
@ SESSION
Definition: transaction_info.h:53
@ STMT
Definition: transaction_info.h:53
char * strmake(const char *str, size_t len)
Definition: transaction_info.h:263
Definition: xa.h:369
void cleanup()
Definition: xa.h:443
DBUG_TRACE
Definition: do_ctype.cc:46
char * strmake_root(MEM_ROOT *root, const char *str, size_t len)
Definition: my_alloc.cc:276
static int flags[50]
Definition: hp_test1.cc:39
static uint key_length
Definition: mi_test1.cc:42
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:180
Some integer typedefs for easier portability.
unsigned char uchar
Definition: my_inttypes.h:51
int64_t int64
Definition: my_inttypes.h:67
uint32_t uint32
Definition: my_inttypes.h:66
Common header for many mysys elements.
static HashTable ht
Definition: mysql.cc:147
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1053
const string value("\"Value\"")
required string key
Definition: replication_asynchronous_connection_failover.proto:59
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:78
void Claim(bool claim)
Claim all the allocated memory for the current thread in the performance schema.
Definition: my_alloc.cc:212
void * Alloc(size_t length)
Allocate memory.
Definition: my_alloc.h:136
void set_block_size(size_t block_size)
Set the desired size of the next block to be allocated.
Definition: my_alloc.h:283
void Clear()
Deallocate all the RAM used.
Definition: my_alloc.cc:163
void ClearForReuse()
Similar to Clear(), but anticipates that the block will be reused for further allocations.
Definition: my_alloc.cc:181
Definition: transaction_info.h:42
size_t length
Definition: transaction_info.h:45
char * name
Definition: transaction_info.h:44
Ha_trx_info * ha_list
Definition: transaction_info.h:46
SAVEPOINT * prev
Definition: transaction_info.h:43
MDL_savepoint mdl_savepoint
State of metadata locks before this savepoint was set.
Definition: transaction_info.h:48
Definition: transaction_info.h:60
void add_unsafe_rollback_flags(unsigned int flags)
Definition: transaction_info.h:129
void mark_modified_non_trans_table()
Definition: transaction_info.h:137
bool has_modified_non_trans_table() const
Definition: transaction_info.h:141
void mark_dropped_temp_table()
Definition: transaction_info.h:151
bool m_no_2pc
Definition: transaction_info.h:62
unsigned int get_unsafe_rollback_flags() const
Definition: transaction_info.h:122
static unsigned int const DROPPED_TEMP_TABLE
Definition: transaction_info.h:118
void reset_unsafe_rollback_flags()
Definition: transaction_info.h:133
bool is_empty() const
Definition: transaction_info.h:164
bool cannot_safely_rollback() const
Definition: transaction_info.h:121
void mark_created_temp_table()
Definition: transaction_info.h:144
void set_unsafe_rollback_flags(unsigned int flags)
Definition: transaction_info.h:125
Ha_trx_info * m_ha_list
Definition: transaction_info.h:65
int m_rw_ha_count
Definition: transaction_info.h:63
bool has_dropped_temp_table() const
Definition: transaction_info.h:155
static unsigned int const MODIFIED_NON_TRANS_TABLE
Definition: transaction_info.h:116
static unsigned int const CREATED_TEMP_TABLE
Definition: transaction_info.h:117
unsigned int m_unsafe_rollback_flags
Definition: transaction_info.h:111
void reset()
Definition: transaction_info.h:159
bool has_created_temp_table() const
Definition: transaction_info.h:148
handlerton is a singleton structure - one instance per storage engine - to provide access to storage ...
Definition: handler.h:2398