MySQL  8.0.18
Source Code Documentation
transaction_info.h
Go to the documentation of this file.
1 /* Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
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 == NULL; }
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 DBUG_OFF
191  bool ready_preempt; // internal in MYSQL_BIN_LOG::ordered_commit
192 #endif
193  } m_flags;
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 = NULL;
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 != NULL;
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 
260 
261  void free_memory(myf root_alloc_flags) {
262  free_root(&m_mem_root, root_alloc_flags);
263  }
264 
265  char *strmake(const char *str, size_t len) {
266  return strmake_root(&m_mem_root, str, len);
267  }
268 
270 
271  void add_changed_table(const char *key, uint32 key_length);
272 
274  return m_scope_info[scope].m_ha_list;
275  }
276 
277  const Ha_trx_info *ha_trx_info(enum_trx_scope scope) const {
278  return m_scope_info[scope].m_ha_list;
279  }
280 
281  void set_ha_trx_info(enum_trx_scope scope, Ha_trx_info *trx_info) {
282  DBUG_TRACE;
283  m_scope_info[scope].m_ha_list = trx_info;
284  return;
285  }
286 
288 
289  const XID_STATE *xid_state() const { return &m_xid_state; }
290 
292  return m_scope_info[scope].cannot_safely_rollback();
293  }
294 
295  unsigned int get_unsafe_rollback_flags(enum_trx_scope scope) const {
296  return m_scope_info[scope].get_unsafe_rollback_flags();
297  }
298 
299  void set_unsafe_rollback_flags(enum_trx_scope scope, unsigned int flags) {
301  }
302 
303  void add_unsafe_rollback_flags(enum_trx_scope scope, unsigned int flags) {
305  }
306 
309  }
310 
313  }
314 
317  }
318 
321  }
322 
324  return m_scope_info[scope].has_created_temp_table();
325  }
326 
329  }
330 
332  return m_scope_info[scope].has_dropped_temp_table();
333  }
334 
335  void reset(enum_trx_scope scope) { m_scope_info[scope].reset(); }
336 
337  bool is_empty(enum_trx_scope scope) const {
338  return m_scope_info[scope].is_empty();
339  }
340 
341  void set_no_2pc(enum_trx_scope scope, bool value) {
342  m_scope_info[scope].m_no_2pc = value;
343  }
344 
345  bool no_2pc(enum_trx_scope scope) const {
346  return m_scope_info[scope].m_no_2pc;
347  }
348 
349  int rw_ha_count(enum_trx_scope scope) const {
350  return m_scope_info[scope].m_rw_ha_count;
351  }
352 
355  }
356 
358  DBUG_TRACE;
359  m_scope_info[scope].m_ha_list = 0;
360  m_scope_info[scope].m_no_2pc = 0;
361  m_scope_info[scope].m_rw_ha_count = 0;
362  return;
363  }
364 
366  return &m_rpl_transaction_ctx;
367  }
368 
370  return &m_rpl_transaction_ctx;
371  }
372 
375  }
376 
379  }
380 
382 
384 
385  private:
389 };
390 
391 /**
392  Either statement transaction or normal transaction - related
393  thread-specific storage engine data.
394 
395  If a storage engine participates in a statement/transaction,
396  an instance of this class is present in
397  thd->m_transaction.m_scope_info[STMT|SESSION].ha_list. The addition
398  this list is made by trans_register_ha().
399 
400  When it's time to commit or rollback, each element of ha_list
401  is used to access storage engine's prepare()/commit()/rollback()
402  methods, and also to evaluate if a full two phase commit is
403  necessary.
404 
405  @sa General description of transaction handling in handler.cc.
406 */
407 
408 class Ha_trx_info {
409  public:
410  /**
411  Register this storage engine in the given transaction context.
412  */
413 
415  DBUG_TRACE;
416  DBUG_ASSERT(m_flags == 0);
417  DBUG_ASSERT(m_ht == NULL);
418  DBUG_ASSERT(m_next == NULL);
419 
420  m_ht = ht_arg;
421  m_flags = (int)TRX_READ_ONLY; /* Assume read-only at start. */
422 
423  if (trans->m_ha_list != this) {
424  m_next = trans->m_ha_list;
425  trans->m_ha_list = this;
426  }
427 
428  return;
429  }
430 
431  /**
432  Clear, prepare for reuse.
433  */
434 
435  void reset() {
436  DBUG_TRACE;
437  m_next = NULL;
438  m_ht = NULL;
439  m_flags = 0;
440  return;
441  }
442 
444 
447  m_flags |= (int)TRX_READ_WRITE;
448  }
449 
450  bool is_trx_read_write() const {
452  return m_flags & (int)TRX_READ_WRITE;
453  }
454 
455  bool is_started() const { return m_ht != NULL; }
456 
457  /**
458  Mark this transaction read-write if the argument is read-write.
459  */
460 
461  void coalesce_trx_with(const Ha_trx_info *stmt_trx) {
462  /*
463  Must be called only after the transaction has been started.
464  Can be called many times, e.g. when we have many
465  read-write statements in a transaction.
466  */
468  if (stmt_trx->is_trx_read_write()) set_trx_read_write();
469  }
470 
471  Ha_trx_info *next() const {
473  return m_next;
474  }
475 
476  handlerton *ht() const {
478  return m_ht;
479  }
480 
481  private:
482  enum { TRX_READ_ONLY = 0, TRX_READ_WRITE = 1 };
483  /**
484  Auxiliary, used for ha_list management
485  */
487 
488  /**
489  Although a given Ha_trx_info instance is currently always used
490  for the same storage engine, 'ht' is not-NULL only when the
491  corresponding storage is a part of a transaction.
492  */
494 
495  /**
496  Transaction flags related to this engine.
497  Not-null only if this instance is a part of transaction.
498  May assume a combination of enum values above.
499  */
501 };
502 
503 #endif
static unsigned int const MODIFIED_NON_TRANS_TABLE
Definition: transaction_info.h:116
handlerton * ht() const
Definition: transaction_info.h:476
unsigned char uchar
Definition: my_inttypes.h:51
bool has_modified_non_trans_table(enum_trx_scope scope) const
Definition: transaction_info.h:315
void clear_write_set()
Definition: rpl_transaction_write_set_ctx.cc:62
bool is_started() const
Definition: transaction_info.h:455
char * name
Definition: transaction_info.h:44
void set_unsafe_rollback_flags(enum_trx_scope scope, unsigned int flags)
Definition: transaction_info.h:299
void add_unsafe_rollback_flags(unsigned int flags)
Definition: transaction_info.h:129
bool xid_written
Definition: transaction_info.h:186
#define MY_KEEP_PREALLOC
Definition: my_sys.h:172
int m_rw_ha_count
Definition: transaction_info.h:63
void cleanup()
Definition: xa.h:434
bool cannot_safely_rollback() const
Definition: transaction_info.h:121
struct Transaction_ctx::@121 m_flags
XID_STATE m_xid_state
Definition: transaction_info.h:170
bool has_modified_non_trans_table() const
Definition: transaction_info.h:141
Definition: transaction_info.h:51
unsigned int m_unsafe_rollback_flags
Definition: transaction_info.h:111
Some integer typedefs for easier portability.
unsigned int get_unsafe_rollback_flags(enum_trx_scope scope) const
Definition: transaction_info.h:295
void set_trx_read_write()
Definition: transaction_info.h:445
void set_no_2pc(enum_trx_scope scope, bool value)
Definition: transaction_info.h:341
void invalidate_changed_tables_in_cache(THD *thd)
bool no_2pc(enum_trx_scope scope) const
Definition: transaction_info.h:345
void mark_modified_non_trans_table(enum_trx_scope scope)
Definition: transaction_info.h:311
bool is_empty(enum_trx_scope scope) const
Definition: transaction_info.h:337
enum_trx_scope
Definition: transaction_info.h:53
unsigned int get_unsafe_rollback_flags() const
Definition: transaction_info.h:122
bool was_trans_begin_hook_invoked()
Definition: transaction_info.h:381
size_t length
Definition: transaction_info.h:45
bool has_created_temp_table() const
Definition: transaction_info.h:148
bool is_trx_read_write() const
Definition: transaction_info.h:450
bool has_dropped_temp_table(enum_trx_scope scope) const
Definition: transaction_info.h:331
Transaction_ctx()
Definition: transaction_info.cc:43
const Ha_trx_info * ha_trx_info(enum_trx_scope scope) const
Definition: transaction_info.h:277
Rpl_transaction_write_set_ctx m_transaction_write_set_ctx
Definition: transaction_info.h:387
Definition: transaction_info.h:53
void cleanup()
Reset transaction context to default values.
Definition: rpl_transaction_ctx.cc:42
Definition: transaction_info.h:482
handlerton * m_ht
Although a given Ha_trx_info instance is currently always used for the same storage engine...
Definition: transaction_info.h:493
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:461
void register_ha(Transaction_ctx::THD_TRANS *trans, handlerton *ht_arg)
Register this storage engine in the given transaction context.
Definition: transaction_info.h:414
void mark_dropped_temp_table(enum_trx_scope scope)
Definition: transaction_info.h:327
Ha_trx_info * ha_trx_info(enum_trx_scope scope)
Definition: transaction_info.h:273
bool has_dropped_temp_table() const
Definition: transaction_info.h:155
bool ready_preempt
Definition: transaction_info.h:191
bool cannot_safely_rollback(enum_trx_scope scope) const
Definition: transaction_info.h:291
void register_ha(enum_trx_scope scope, Ha_trx_info *ha_info, handlerton *ht)
Definition: transaction_info.cc:77
void mark_created_temp_table(enum_trx_scope scope)
Definition: transaction_info.h:319
Rpl_transaction_ctx m_rpl_transaction_ctx
Definition: transaction_info.h:386
void free_memory(myf root_alloc_flags)
Definition: transaction_info.h:261
#define DBUG_PRINT(keyword, arglist)
Definition: my_dbug.h:179
#define DBUG_ASSERT(A)
Definition: my_dbug.h:197
Rpl_transaction_ctx * get_rpl_transaction_ctx()
Definition: transaction_info.h:365
void Claim()
Claim all the allocated memory for the current thread in the performance schema.
Definition: my_alloc.cc:186
uchar m_flags
Transaction flags related to this engine.
Definition: transaction_info.h:500
void merge_unsafe_rollback_flags()
Definition: transaction_info.h:240
Savepoint for MDL context.
Definition: mdl.h:1295
void add_unsafe_rollback_flags(enum_trx_scope scope, unsigned int flags)
Definition: transaction_info.h:303
int64_t int64
Definition: my_inttypes.h:67
void push_unsafe_rollback_warnings(THD *thd)
Definition: transaction_info.cc:58
virtual ~Transaction_ctx()
Definition: transaction_info.h:221
void cleanup()
Definition: transaction_info.h:223
void init_mem_root_defaults(ulong trans_alloc_block_size, ulong)
Definition: transaction_info.h:251
char * strmake(const char *str, size_t len)
Definition: transaction_info.h:265
void reset(enum_trx_scope scope)
Definition: transaction_info.h:335
MDL_savepoint mdl_savepoint
State of metadata locks before this savepoint was set.
Definition: transaction_info.h:48
void claim_memory_ownership()
Definition: transaction_info.h:259
#define MYF(v)
Definition: my_inttypes.h:114
void set_unsafe_rollback_flags(unsigned int flags)
Definition: transaction_info.h:125
uint32_t uint32
Definition: my_inttypes.h:66
bool trans_begin_hook_invoked
Definition: transaction_info.h:388
void reset_unsafe_rollback_flags()
Definition: transaction_info.h:133
handlerton is a singleton structure - one instance per storage engine - to provide access to storage ...
Definition: handler.h:2272
void set_trans_begin_hook_invoked()
Definition: transaction_info.h:383
void reset_unsafe_rollback_flags(enum_trx_scope scope)
Definition: transaction_info.h:307
void set_ha_trx_info(enum_trx_scope scope, Ha_trx_info *trx_info)
Definition: transaction_info.h:281
Definition: transaction_info.h:53
Common header for many mysys elements.
void set_rw_ha_count(enum_trx_scope scope, int value)
Definition: transaction_info.h:353
Ha_trx_info()
Definition: transaction_info.h:443
Server side support to provide a service to plugins to report if a given transaction should continue ...
Definition: rpl_transaction_ctx.h:34
DBUG_TRACE
Definition: do_ctype.cc:46
Definition: transaction_info.h:60
Ha_trx_info * m_next
Auxiliary, used for ha_list management.
Definition: transaction_info.h:486
static const char * key
Definition: suite_stubs.c:14
MEM_ROOT m_mem_root
Definition: transaction_info.h:172
static unsigned int const CREATED_TEMP_TABLE
Definition: transaction_info.h:117
Definition: transaction_info.h:482
const Rpl_transaction_write_set_ctx * get_transaction_write_set_ctx() const
Definition: transaction_info.h:377
bool real_commit
Definition: transaction_info.h:187
XID_STATE * xid_state()
Definition: transaction_info.h:287
bool enabled
Definition: transaction_info.h:185
static HashTable ht
Definition: mysql.cc:146
Server side support to provide a service to plugins to report if a given transaction should continue ...
Definition: rpl_transaction_write_set_ctx.h:40
const Rpl_transaction_ctx * get_rpl_transaction_ctx() const
Definition: transaction_info.h:369
Definition: transaction_info.h:42
void reset()
Clear, prepare for reuse.
Definition: transaction_info.h:435
bool is_active(enum_trx_scope scope) const
Definition: transaction_info.h:234
MEM_ROOT * transaction_memroot()
Definition: transaction_info.h:255
THD_TRANS m_scope_info[2]
Definition: transaction_info.h:168
int myf
Definition: my_inttypes.h:111
void * allocate_memory(unsigned int size)
Definition: transaction_info.h:257
void reset()
Definition: transaction_info.h:159
bool commit_low
Definition: transaction_info.h:188
void mark_dropped_temp_table()
Definition: transaction_info.h:151
Either statement transaction or normal transaction - related thread-specific storage engine data...
Definition: transaction_info.h:408
void mark_created_temp_table()
Definition: transaction_info.h:144
void mark_modified_non_trans_table()
Definition: transaction_info.h:137
#define NULL
Definition: types.h:55
SAVEPOINT * m_savepoints
Definition: transaction_info.h:55
bool is_empty() const
Definition: transaction_info.h:164
void * Alloc(size_t length)
Allocate memory.
Definition: my_alloc.h:134
static unsigned int const DROPPED_TEMP_TABLE
Definition: transaction_info.h:118
void store_commit_parent(int64 last_arg)
Definition: transaction_info.h:218
const string value("\alue\)
int64 last_committed
Definition: transaction_info.h:207
int rw_ha_count(enum_trx_scope scope) const
Definition: transaction_info.h:349
char * strmake_root(MEM_ROOT *root, const char *str, size_t len)
Definition: my_alloc.cc:259
Ha_trx_info * m_ha_list
Definition: transaction_info.h:65
void reset_scope(enum_trx_scope scope)
Definition: transaction_info.h:357
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:77
Definition: xa.h:360
int64 sequence_number
Definition: transaction_info.h:216
static int flags[50]
Definition: hp_test1.cc:39
void set_block_size(size_t block_size)
Set the desired size of the next block to be allocated.
Definition: my_alloc.h:277
void free_root(MEM_ROOT *root, myf flags)
Definition: my_alloc.cc:250
SAVEPOINT * prev
Definition: transaction_info.h:43
Ha_trx_info * ha_list
Definition: transaction_info.h:46
Ha_trx_info * next() const
Definition: transaction_info.h:471
bool m_no_2pc
Definition: transaction_info.h:62
unsigned long ulong
Definition: my_inttypes.h:48
bool has_created_temp_table(enum_trx_scope scope) const
Definition: transaction_info.h:323
static uint key_length
Definition: mi_test1.cc:42
void add_changed_table(const char *key, uint32 key_length)
bool run_hooks
Definition: transaction_info.h:189
Rpl_transaction_write_set_ctx * get_transaction_write_set_ctx()
Definition: transaction_info.h:373
This file follows Google coding style, except for the name MEM_ROOT (which is kept for historical rea...
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:778
const XID_STATE * xid_state() const
Definition: transaction_info.h:289