MySQL 8.3.0
Source Code Documentation
trx0trx.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1996, 2023, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is also distributed with certain software (including but not
10limited to OpenSSL) that is licensed under separate terms, as designated in a
11particular file or component or in included license documentation. The authors
12of MySQL hereby grant you an additional permission to link the program and
13your derivative works with the separately licensed software that they have
14included with MySQL.
15
16This program is distributed in the hope that it will be useful, but WITHOUT
17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
19for more details.
20
21You should have received a copy of the GNU General Public License along with
22this program; if not, write to the Free Software Foundation, Inc.,
2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
24
25*****************************************************************************/
26
27/** @file include/trx0trx.h
28 The transaction
29
30 Created 3/26/1996 Heikki Tuuri
31 *******************************************************/
32
33#ifndef trx0trx_h
34#define trx0trx_h
35
36#include <atomic>
37#include <set>
38
39#include "ha_prototypes.h"
40
41#include "dict0types.h"
42#include "trx0types.h"
43#include "ut0new.h"
44
45#include "lock0types.h"
46#include "mem0mem.h"
47#include "que0types.h"
48#include "trx0xa.h"
49#include "usr0types.h"
50#include "ut0vec.h"
51#ifndef UNIV_HOTBACKUP
52#include "fts0fts.h"
53#endif /* !UNIV_HOTBACKUP */
54#include "read0read.h"
55#include "sql/handler.h" // Xa_state_list
56#include "srv0srv.h"
57
58/* std::vector to store the trx id & table id of tables that needs to be
59 * rollbacked. We take SHARED MDL on these tables inside
60 * trx_recovery_rollback_thread before letting server accept connections */
61extern std::vector<std::pair<trx_id_t, table_id_t>> to_rollback_trx_tables;
62
63// Forward declaration
64struct mtr_t;
65
66// Forward declaration
67class ReadView;
68
69// Forward declaration
70class Flush_observer;
71
72/** Dummy session used currently in MySQL interface */
74
75#ifndef UNIV_HOTBACKUP
76/** Set flush observer for the transaction
77@param[in,out] trx transaction struct
78@param[in] observer flush observer */
79void trx_set_flush_observer(trx_t *trx, Flush_observer *observer);
80
81/** Set detailed error message for the transaction.
82@param[in] trx Transaction struct
83@param[in] msg Detailed error message */
84void trx_set_detailed_error(trx_t *trx, const char *msg);
85
86/** Set detailed error message for the transaction from a file. Note that the
87 file is rewinded before reading from it. */
89 trx_t *trx, /*!< in: transaction struct */
90 FILE *file); /*!< in: file to read message from */
91/** Retrieves the error_info field from a trx.
92 @return the error index */
93static inline const dict_index_t *trx_get_error_index(
94 const trx_t *trx); /*!< in: trx object */
95/** Creates a transaction object for MySQL.
96 @return own: transaction object */
98/** Creates a transaction object for background operations by the master thread.
99 @return own: transaction object */
101
102/** Resurrect table locks for resurrected transactions.
103@param[in] all false: resurrect locks for dictionary transactions,
104 true : resurrect locks for all transactions. */
105void trx_resurrect_locks(bool all);
106
107/** Clear all resurrected table IDs. Needs to be called after all tables locks
108are resurrected. */
110
111/** Free and initialize a transaction object instantiated during recovery.
112@param[in,out] trx transaction object to free and initialize */
113void trx_free_resurrected(trx_t *trx);
114
115/** Free a transaction that was allocated by background or user threads.
116@param[in,out] trx transaction object to free */
118
119/** At shutdown, frees a transaction object that represents either:
120 - a PREPARED transaction,
121 - or a recovered ACTIVE transaction.
122@param[in, out] trx transaction object to free */
124
125/** Free a transaction object for MySQL.
126@param[in,out] trx transaction */
127void trx_free_for_mysql(trx_t *trx);
128
129/** Disconnect a transaction from MySQL.
130@param[in,out] trx transaction */
131void trx_disconnect_plain(trx_t *trx);
132
133/** Disconnect a prepared transaction from MySQL.
134@param[in,out] trx transaction */
136
137/** Creates trx objects for transactions and initializes the trx list of
138 trx_sys at database start. Rollback segment and undo log lists must
139 already exist when this function is called, because the lists of
140 transactions to be rolled back or cleaned up are built based on the
141 undo log lists. */
143
144/** Starts the transaction if it is not yet started.
145@param[in,out] trx Transaction
146@param[in] read_write True if read write transaction */
147void trx_start_if_not_started_xa_low(trx_t *trx, bool read_write);
148
149/** Starts the transaction if it is not yet started.
150@param[in] trx Transaction
151@param[in] read_write True if read write transaction */
152void trx_start_if_not_started_low(trx_t *trx, bool read_write);
153
154/** Starts a transaction for internal processing. */
155void trx_start_internal_low(trx_t *trx); /*!< in/out: transaction */
156
157/** Starts a read-only transaction for internal processing.
158@param[in,out] trx transaction to be started */
160
161/** Commits a transaction. */
162void trx_commit(trx_t *trx); /*!< in/out: transaction */
163
164/** Commits a transaction and a mini-transaction.
165@param[in,out] trx Transaction
166@param[in,out] mtr Mini-transaction (will be committed), or null if trx made no
167modifications */
168void trx_commit_low(trx_t *trx, mtr_t *mtr);
169
170/** Cleans up a transaction at database startup. The cleanup is needed if
171 the transaction already got to the middle of a commit when the database
172 crashed, and we cannot roll it back. */
173void trx_cleanup_at_db_startup(trx_t *trx); /*!< in: transaction */
174/** Does the transaction commit for MySQL.
175 @return DB_SUCCESS or error number */
176dberr_t trx_commit_for_mysql(trx_t *trx); /*!< in/out: transaction */
177
178/**
179Does the transaction prepare for MySQL.
180@param[in, out] trx Transaction instance to prepare */
181
183
184/** This function is used to find number of prepared transactions and
185 their transaction objects for a recovery.
186 @return number of prepared transactions */
188 XA_recover_txn *txn_list, /*!< in/out: prepared transactions */
189 ulint len, /*!< in: number of slots in xid_list */
190 MEM_ROOT *mem_root); /*!< in: memory for table names */
191
192/** Find prepared transactions that are marked as prepared in TC, for recovery
193purposes.
194@param[in,out] xa_list prepared transactions state
195@return 0 if successful or error number */
197
198/** This function is used to find one X/Open XA distributed transaction
199 which is in the prepared state
200 @param[in] xid X/Open XA transaction identifier
201 @return trx or NULL; on match, the trx->xid will be invalidated;
202 note that the trx may have been committed */
203trx_t *trx_get_trx_by_xid(const XID *xid);
204
205/** If required, flushes the log to disk if we called trx_commit_for_mysql()
206 with trx->flush_log_later == true. */
207void trx_commit_complete_for_mysql(trx_t *trx); /*!< in/out: transaction */
208/** Marks the latest SQL statement ended. */
209void trx_mark_sql_stat_end(trx_t *trx); /*!< in: trx handle */
210/** Assigns a read view for a consistent read query. All the consistent reads
211 within the same transaction will get the same read view, which is created
212 when this function is first called for a new started transaction. */
213ReadView *trx_assign_read_view(trx_t *trx); /*!< in: active transaction */
214
215/** @return the transaction's read view or NULL if one not assigned. */
216static inline ReadView *trx_get_read_view(trx_t *trx);
217
218/** @return the transaction's read view or NULL if one not assigned. */
219static inline const ReadView *trx_get_read_view(const trx_t *trx);
220
221/** Prepares a transaction for commit/rollback. */
222void trx_commit_or_rollback_prepare(trx_t *trx); /*!< in/out: transaction */
223/** Creates a commit command node struct.
224 @return own: commit node struct */
226 mem_heap_t *heap); /*!< in: mem heap where created */
227/** Performs an execution step for a commit type node in a query graph.
228 @return query thread to run next, or NULL */
229que_thr_t *trx_commit_step(que_thr_t *thr); /*!< in: query thread */
230
231/** Prints info about a transaction.
232 Caller must hold trx_sys->mutex. */
233void trx_print_low(FILE *f,
234 /*!< in: output stream */
235 const trx_t *trx,
236 /*!< in: transaction */
237 ulint max_query_len,
238 /*!< in: max query length to print,
239 must be positive */
240 ulint n_rec_locks,
241 /*!< in: lock_number_of_rows_locked(&trx->lock) */
242 ulint n_trx_locks,
243 /*!< in: length of trx->lock.trx_locks */
244 ulint heap_size);
245/*!< in: mem_heap_get_size(trx->lock.lock_heap) */
246
247/** Prints info about a transaction.
248The caller must hold lock_sys exclusive global latch and trx_sys->mutex.
249@param[in] f output stream
250@param[in] trx transaction
251@param[in] max_query_len max query length to print, must be positive */
252void trx_print_latched(FILE *f, const trx_t *trx, ulint max_query_len);
253
254/** Prints info about a transaction.
255Acquires and releases lock_sys exclusive global latch and trx_sys->mutex.
256@param[in] f output stream
257@param[in] trx transaction
258@param[in] max_query_len max query length to print, must be positive */
259void trx_print(FILE *f, const trx_t *trx, ulint max_query_len);
260
261/** Determine if a transaction is a dictionary operation.
262 @return dictionary operation mode */
263[[nodiscard]] static inline enum trx_dict_op_t trx_get_dict_operation(
264 const trx_t *trx); /*!< in: transaction */
265
266/** Flag a transaction a dictionary operation.
267@param[in,out] trx transaction
268@param[in] op operation, not TRX_DICT_OP_NONE */
269static inline void trx_set_dict_operation(trx_t *trx, enum trx_dict_op_t op);
270
271/** Determines if a transaction is in the given state.
272The caller must hold trx_sys->mutex, or it must be the thread
273that is serving a running transaction.
274A running RW transaction must be in trx_sys->rw_trx_list.
275@param[in] trx Transaction.
276@param[in] state State.
277@return true if trx->state == state */
278[[nodiscard]] static inline bool trx_state_eq(const trx_t *trx,
279 trx_state_t state);
280#ifdef UNIV_DEBUG
281/** Determines if trx can be handled by current thread, which is when
282trx->mysql_thd is nullptr (a "background" trx) or equals current_thd.
283@param[in] trx The transaction to check
284@return true iff current thread can handle the transaction
285*/
287
288/** Determines if trx can be handled by current thread, which is when
289trx->mysql_thd is nullptr (a "background" trx) or equals current_thd,
290or is a victim being killed by HP transaction run by the current thread.
291@param[in] trx The transaction to check
292@return true iff current thread can handle the transaction
293*/
295
296/** Asserts that a transaction has been started.
297 The caller must hold trx_sys->mutex.
298 @return true if started */
299[[nodiscard]] bool trx_assert_started(const trx_t *trx); /*!< in: transaction */
300#endif /* UNIV_DEBUG */
301
302/** Determines if the currently running transaction has been interrupted.
303 @return true if interrupted */
304bool trx_is_interrupted(const trx_t *trx); /*!< in: transaction */
305/** Determines if the currently running transaction is in strict mode.
306 @return true if strict */
307bool trx_is_strict(trx_t *trx); /*!< in: transaction */
308
309/** Compares the "weight" (or size) of two transactions. Transactions that
310 have edited non-transactional tables are considered heavier than ones
311 that have not.
312 @return true if weight(a) >= weight(b) */
313bool trx_weight_ge(const trx_t *a, /*!< in: the transaction to be compared */
314 const trx_t *b); /*!< in: the transaction to be compared */
315/* Maximum length of a string that can be returned by
316trx_get_que_state_str(). */
317constexpr uint32_t TRX_QUE_STATE_STR_MAX_LEN = 12; /* "ROLLING BACK" */
318
319/** Retrieves transaction's que state in a human readable string. The string
320 should not be free()'d or modified.
321 @return string in the data segment */
322static inline const char *trx_get_que_state_str(
323 const trx_t *trx); /*!< in: transaction */
324
325/** Retreieves the transaction ID.
326In a given point in time it is guaranteed that IDs of the running
327transactions are unique. The values returned by this function for readonly
328transactions may be reused, so a subsequent RO transaction may get the same ID
329as a RO transaction that existed in the past. The values returned by this
330function should be used for printing purposes only.
331@param[in] trx transaction whose id to retrieve
332@return transaction id */
333static inline trx_id_t trx_get_id_for_print(const trx_t *trx);
334
335/** Assign a temp-tablespace bound rollback-segment to a transaction.
336@param[in,out] trx transaction that involves write to temp-table. */
337void trx_assign_rseg_temp(trx_t *trx);
338
339/** Create the trx_t pool */
340void trx_pool_init();
341
342/** Destroy the trx_t pool */
343void trx_pool_close();
344
345/**
346Set the transaction as a read-write transaction if it is not already
347tagged as such.
348@param[in,out] trx Transaction that needs to be "upgraded" to RW from RO */
349void trx_set_rw_mode(trx_t *trx);
350
351/**
352@param[in] requestor Transaction requesting the lock
353@param[in] holder Transaction holding the lock
354@return the transaction that will be rolled back, null don't care */
355
356static inline const trx_t *trx_arbitrate(const trx_t *requestor,
357 const trx_t *holder);
358
359/**
360@param[in] trx Transaction to check
361@return true if the transaction is a high priority transaction.*/
362static inline bool trx_is_high_priority(const trx_t *trx);
363
364/**
365If this is a high priority transaction,
366kill all transactions that are blocking this transaction from acquiring locks.
367@param[in,out] trx High priority transaction */
368void trx_kill_blocking(trx_t *trx);
369
370/** Provides an id of the transaction which does not change over time.
371Contrast this with trx->id and trx_get_id_for_print(trx) which change value once
372a transaction can no longer be treated as read-only and becomes read-write.
373@param[in] trx The transaction for which you want an immutable id
374@return the transaction's immutable id */
375static inline uint64_t trx_immutable_id(const trx_t *trx) {
376 return (uint64_t{reinterpret_cast<uintptr_t>(trx)});
377}
378
379/**
380Check if redo/noredo rseg is modified for insert/update.
381@param[in] trx Transaction to check */
382static inline bool trx_is_rseg_updated(const trx_t *trx);
383#endif /* !UNIV_HOTBACKUP */
384
385typedef std::vector<ib_lock_t *, ut::allocator<ib_lock_t *>> lock_pool_t;
386
387/** Latching protocol for trx_lock_t::que_state. trx_lock_t::que_state
388 captures the state of the query thread during the execution of a query.
389 This is different from a transaction state. The query state of a transaction
390 can be updated asynchronously by other threads. The other threads can be
391 system threads, like the timeout monitor thread or user threads executing
392 other queries. Another thing to be mindful of is that there is a delay between
393 when a query thread is put into LOCK_WAIT state and before it actually starts
394 waiting. Between these two events it is possible that the query thread is
395 granted the lock it was waiting for, which implies that the state can be
396 changed asynchronously.
397
398 All these operations take place within the context of locking. Therefore state
399 changes within the locking code must latch the shard with the wait_lock and
400 the trx->mutex when changing trx->lock.que_state to TRX_QUE_LOCK_WAIT or
401 trx->lock.wait_lock to non-NULL but when the lock wait ends it is sufficient
402 to only acquire the trx->mutex.
403 To query the state either of the mutexes is sufficient within the locking
404 code and no mutex is required when the query thread is no longer waiting. */
405
406/** The locks and state of an active transaction.
407Protected by exclusive lock_sys latch or trx->mutex combined with shared
408lock_sys latch (unless stated otherwise for particular field). */
410 /** Default constructor. */
411 trx_lock_t() = default;
412
413 ulint n_active_thrs; /*!< number of active query threads */
414
415 trx_que_t que_state; /*!< valid when trx->state
416 == TRX_STATE_ACTIVE: TRX_QUE_RUNNING,
417 TRX_QUE_LOCK_WAIT, ... */
418
419 /** Incremented each time a lock is added or removed from the
420 trx->lock.trx_locks, so that the thread which iterates over the list can spot
421 a change if it occurred while it was reacquiring latches.
422 Protected by trx->mutex. */
424
425 /** If this transaction is waiting for a lock, then blocking_trx points to a
426 transaction which holds a conflicting lock.
427 It is possible that the transaction has trx->lock.wait_lock == nullptr, yet it
428 has non-null value of trx->lock.blocking_trx. For example this can happen when
429 we are in the process of moving locks from one heap_no to another. This
430 however is always done while the lock_sys shards which contain the queues
431 involved are latched and conceptually it is true that the blocking_trx is
432 the one for which the transaction waits, even though temporarily there is no
433 pointer to a particular WAITING lock object.
434
435 This field is changed from null to non-null, when holding this->mutex and
436 mutex for lock_sys shard containing the new value of trx->lock.wait_lock.
437 The field is changed from non-null to different non-null value, while holding
438 mutex for lock_sys shard containing the trx->lock.wait_lock.
439 The field is changed from non-null to null, while holding this->mutex,
440 mutex for lock_sys shard containing the old value of trx->lock.wait_lock,
441 before it was changed to null.
442
443 Readers might read it without any latch, but then they should validate the
444 value, i.e. test if it is not-null, and points to a valid trx.
445 To make any definite judgments one needs to latch the lock_sys shard
446 containing the trx->lock.wait_lock. */
447 std::atomic<trx_t *> blocking_trx;
448
449 /** The lock request of this transaction is waiting for.
450 It might be NULL if the transaction is not currently waiting, or if the lock
451 was temporarily removed during B-tree reorganization and will be recreated in
452 a different queue. Such move is protected by latching the shards containing
453 both queues, so the intermediate state should not be observed by readers who
454 latch the old shard.
455
456 Changes from NULL to non-NULL while holding trx->mutex and latching the shard
457 containing the new wait_lock value.
458 Changes from non-NULL to NULL while latching the shard containing the old
459 wait_lock value.
460 Never changes from non-NULL to other non-NULL directly.
461
462 Readers should hold exclusive global latch on lock_sys, as in general they
463 can't know what shard the lock belongs to before reading it.
464 However, in debug assertions, where we strongly believe to know the value of
465 this field in advance, we can:
466 - read without any latch if we believe the value should be NULL
467 - read latching only the shard containing the wait_lock we expect */
468 std::atomic<lock_t *> wait_lock;
469
470 /** Stores the type of the most recent lock for which this trx had to wait.
471 Set to lock_get_type_low(wait_lock) together with wait_lock in
472 lock_set_lock_and_trx_wait().
473 This field is not cleared when wait_lock is set to NULL during
474 lock_reset_lock_and_trx_wait() as in lock_wait_suspend_thread() we are
475 interested in reporting the last known value of this field via
476 thd_wait_begin(). When a thread has to wait for a lock, it first releases
477 lock-sys latch, and then calls lock_wait_suspend_thread() where among other
478 things it tries to report statistic via thd_wait_begin() about the kind of
479 lock (THD_WAIT_ROW_LOCK vs THD_WAIT_TABLE_LOCK) that caused the wait. But
480 there is a possibility that before it gets to call thd_wait_begin() some other
481 thread could latch lock-sys and grant the lock and call
482 lock_reset_lock_and_trx_wait(). In other words: in case another thread was
483 quick enough to grant the lock, we still would like to report the reason for
484 attempting to sleep.
485 Another common scenario of "setting trx->lock.wait_lock to NULL" is page
486 reorganization: when we have to move records between pages, we also move
487 locks, and when doing so, we temporarily remove the old waiting lock, and then
488 add another one. For example look at lock_rec_move_low(). It first calls
489 lock_reset_lock_and_trx_wait() which changes trx->lock.wait_lock to NULL, but
490 then calls lock_rec_add_to_queue() -> RecLock::create() -> RecLock::lock_add()
491 -> lock_set_lock_and_trx_wait() to set it again to the new lock. This all
492 happens while holding lock-sys latch, but we read wait_lock_type without this
493 latch, so we should not clear the wait_lock_type simply because somebody
494 changed wait_lock to NULL.
495 Protected by trx->mutex. */
497
499 /*!< when the transaction decides to
500 wait for a lock, it sets this to false;
501 if another transaction chooses this
502 transaction as a victim in deadlock
503 resolution, it sets this to true.
504 Protected by trx->mutex. */
505
506 /** Lock wait started at this time.
507 Writes under shared lock_sys latch combined with trx->mutex.
508 Reads require either trx->mutex or exclusive lock_sys latch. */
509 std::chrono::system_clock::time_point wait_started;
510
511 /** query thread belonging to this trx that is in QUE_THR_LOCK_WAIT state.
512 For threads suspended in a lock wait, this is protected by lock_sys latch for
513 the wait_lock's shard.
514 Otherwise, this may only be modified by the thread that is serving the running
515 transaction.
516 */
518
519 /** Pre-allocated record locks. Protected by trx->mutex. */
521
522 /** Pre-allocated table locks. Protected by trx->mutex. */
524
525 /** Next free record lock in pool. Protected by trx->mutex. */
527
528 /** Next free table lock in pool. Protected by trx->mutex. */
530
531 /** Memory heap for trx_locks. Protected by trx->mutex */
533
534 /** Locks requested by the transaction.
535 It is sorted so that LOCK_TABLE locks are before LOCK_REC locks.
536 Modifications are protected by trx->mutex and shard of lock_sys mutex.
537 Reads can be performed while holding trx->mutex or exclusive lock_sys latch.
538 One can also check if this list is empty or not from the thread running this
539 transaction without holding any latches, keeping in mind that other threads
540 might modify the list in parallel (for example during implicit-to-explicit
541 conversion, or when B-tree split or merge causes locks to be moved from one
542 page to another) - we rely on assumption that such operations do not change
543 the "emptiness" of the list and that one can check for emptiness in a safe
544 manner (in current implementation length of the list is stored explicitly so
545 one can read it without risking unsafe pointer operations) */
546 trx_lock_list_t trx_locks;
547
548 /** AUTOINC locks held by this transaction.
549 Note that these are also in the trx_locks list.
550 This vector needs to be freed explicitly when the trx instance is destroyed.
551 Protected by trx->mutex. */
553
554 /** Number of rec locks in this trx.
555 It is modified with shared lock_sys latch.
556 It is read with exclusive lock_sys latch. */
557 std::atomic<ulint> n_rec_locks;
558
559 /** Used to indicate that every lock of this transaction placed on a record
560 which is being purged should be inherited to the gap.
561 Readers should hold a latch on the lock they'd like to learn about whether or
562 not it should be inherited.
563 Writers who want to set it to true, should hold a latch on the lock-sys queue
564 they intend to add a lock to.
565 Writers may set it to false at any time. */
566 std::atomic<bool> inherit_all;
567
568 /** Weight of the waiting transaction used for scheduling.
569 The higher the weight the more we are willing to grant a lock to this
570 transaction.
571 Values are updated and read without any synchronization beyond that provided
572 by atomics, as slightly stale values do not hurt correctness, just the
573 performance. */
574 std::atomic<trx_schedule_weight_t> schedule_weight;
575
576#ifdef UNIV_DEBUG
577 /** When a transaction is forced to rollback due to a deadlock
578 check or by another high priority transaction this is true. Used
579 by debug checks in lock0lock.cc */
581#endif /* UNIV_DEBUG */
582
583 /** The transaction called ha_innobase::start_stmt() to
584 lock a table. Most likely a temporary table. */
586};
587
588/** Type used to store the list of tables that are modified by a given
589transaction. We store pointers to the table objects in memory because
590we know that a table object will not be destroyed while a transaction
591that modified it is running. */
592typedef std::set<dict_table_t *, std::less<dict_table_t *>,
595
596/** The transaction handle
597
598Normally, there is a 1:1 relationship between a transaction handle
599(trx) and a session (client connection). One session is associated
600with exactly one user transaction. There are some exceptions to this:
601
602* For DDL operations, a subtransaction is allocated that modifies the
603data dictionary tables. Lock waits and deadlocks are prevented by
604acquiring the dict_operation_lock before starting the subtransaction
605and releasing it after committing the subtransaction.
606
607* The purge system uses a special transaction that is not associated
608with any session.
609
610* If the system crashed or it was quickly shut down while there were
611transactions in the ACTIVE or PREPARED state, these transactions would
612no longer be associated with a session when the server is restarted.
613
614A session may be served by at most one thread at a time. The serving
615thread of a session might change in some MySQL implementations.
616Therefore we do not have std::this_thread::get_id() assertions in the code.
617
618Normally, only the thread that is currently associated with a running
619transaction may access (read and modify) the trx object, and it may do
620so without holding any mutex. The following are exceptions to this:
621
622* trx_rollback_resurrected() may access resurrected (connectionless)
623transactions while the system is already processing new user
624transactions. The trx_sys->mutex prevents a race condition between it
625and lock_trx_release_locks() [invoked by trx_commit()].
626
627* Print of transactions may access transactions not associated with
628the current thread. The caller must be holding trx_sys->mutex and
629exclusive global lock_sys latch.
630
631* When a transaction handle is in the trx_sys->mysql_trx_list or
632trx_sys->trx_list, some of its fields must not be modified without
633holding trx_sys->mutex exclusively.
634
635* The locking code (in particular, deadlock checking and implicit to
636explicit conversion) will access transactions associated to other
637connections. The locks of transactions are protected by lock_sys latches
638and sometimes by trx->mutex.
639
640* Killing of asynchronous transactions. */
641
642/** Represents an instance of rollback segment along with its state variables.*/
644 /** @return true iff no undo segment is allocated yet. */
645 bool is_empty() { return (insert_undo == nullptr && update_undo == nullptr); }
646
647 /** @return true iff only insert undo segment is allocated. */
649 return (insert_undo != nullptr && update_undo == nullptr);
650 }
651
652 /** @return true iff update undo segment is allocated. */
653 bool is_update() { return update_undo != nullptr; }
654
655 trx_rseg_t *rseg; /*!< rollback segment assigned to the
656 transaction, or NULL if not assigned
657 yet */
658 trx_undo_t *insert_undo; /*!< pointer to the insert undo log, or
659 NULL if no inserts performed yet */
660 trx_undo_t *update_undo; /*!< pointer to the update undo log, or
661 NULL if no update performed yet */
662};
663
664/** Rollback segments assigned to a transaction for undo logging. */
666 /** undo log ptr holding reference to a rollback segment that resides in
667 system/undo tablespace used for undo logging of tables that needs
668 to be recovered on crash. */
670
671 /** undo log ptr holding reference to a rollback segment that resides in
672 temp tablespace used for undo logging of tables that doesn't need
673 to be recovered on crash. */
675};
676
678 TRX_RSEG_TYPE_NONE = 0, /*!< void rollback segment type. */
679 TRX_RSEG_TYPE_REDO, /*!< redo rollback segment. */
680 TRX_RSEG_TYPE_NOREDO /*!< non-redo rollback segment. */
682
683struct trx_t {
685
686 /** dirty read: non-locking SELECTs are performed so that we
687 do not look at a possible earlier version of a record; thus
688 they are not 'consistent' reads under this isolation level;
689 otherwise like level 2 */
691
692 /** somewhat Oracle-like isolation, except that in range UPDATE
693 and DELETE we must block phantom rows with next-key locks;
694 SELECT ... FOR UPDATE and ... LOCK IN SHARE MODE only lock
695 the index records, NOT the gaps before them, and thus allow
696 free inserting; each consistent read reads its own snapshot */
698
699 /** this is the default; all consistent reads in the same trx
700 read the same snapshot; full next-key locking used in locking
701 reads to block insertions into gaps */
703
704 /** all plain SELECTs are converted to LOCK IN SHARE MODE
705 reads */
707 };
708
709 /** Default constructor */
710 trx_t() = default;
711
712 /** Mutex protecting the fields `state` and `lock` (except some fields of
713 `lock`, which are protected by lock_sys latches) */
715
716 /* Note: in_depth was split from in_innodb for fixing a RO
717 performance issue. Acquiring the trx_t::mutex for each row
718 costs ~3% in performance. It is not required for correctness.
719 Therefore we increment/decrement in_depth without holding any
720 mutex. The assumption is that the Server will only ever call
721 the handler from one thread. This is not true for kill_connection.
722 Therefore in innobase_kill_connection. We don't increment this
723 counter via TrxInInnoDB. */
724
725 uint32_t in_depth; /*!< Track nested TrxInInnoDB
726 count */
727
728 uint32_t in_innodb; /*!< if the thread is executing
729 in the InnoDB context count > 0. */
730
731 bool abort; /*!< if this flag is set then
732 this transaction must abort when
733 it can */
734
735 trx_id_t id; /*!< transaction id */
736
737 trx_id_t no; /*!< transaction serialization number:
738 max trx id shortly before the
739 transaction is moved to
740 COMMITTED_IN_MEMORY state.
741 Protected by trx_sys_t::mutex
742 when trx->in_rw_trx_list. Initially
743 set to TRX_ID_MAX. */
744
745 /** State of the trx from the point of view of concurrency control
746 and the valid state transitions.
747
748 Possible states:
749
750 TRX_STATE_NOT_STARTED
751 TRX_STATE_FORCED_ROLLBACK
752 TRX_STATE_ACTIVE
753 TRX_STATE_PREPARED
754 TRX_STATE_COMMITTED_IN_MEMORY (alias below COMMITTED)
755
756 Valid state transitions are:
757
758 Regular transactions:
759 * NOT_STARTED -> ACTIVE -> COMMITTED -> NOT_STARTED
760
761 Auto-commit non-locking read-only:
762 * NOT_STARTED -> ACTIVE -> NOT_STARTED
763
764 XA (2PC):
765 * NOT_STARTED -> ACTIVE -> PREPARED -> COMMITTED -> NOT_STARTED
766
767 Recovered XA:
768 * NOT_STARTED -> PREPARED -> COMMITTED -> (freed)
769
770 XA (2PC) (shutdown or disconnect before ROLLBACK or COMMIT):
771 * NOT_STARTED -> PREPARED -> (freed)
772
773 Disconnected XA can become recovered:
774 * ... -> ACTIVE -> PREPARED (connected) -> PREPARED (disconnected)
775 Disconnected means from mysql e.g due to the mysql client disconnection.
776 Latching and various transaction lists membership rules:
777
778 XA (2PC) transactions are always treated as non-autocommit.
779
780 Transitions to ACTIVE or NOT_STARTED occur when
781 !in_rw_trx_list (no trx_sys->mutex needed).
782
783 Autocommit non-locking read-only transactions move between states
784 without holding any mutex. They are !in_rw_trx_list.
785
786 All transactions, unless they are determined to be ac-nl-ro,
787 explicitly tagged as read-only or read-write, will first be put
788 on the read-only transaction list. Only when a !read-only transaction
789 in the read-only list tries to acquire an X or IX lock on a table
790 do we remove it from the read-only list and put it on the read-write
791 list. During this switch we assign it a rollback segment.
792
793 When a transaction is NOT_STARTED, it can be in_mysql_trx_list if
794 it is a user transaction. It cannot be in rw_trx_list.
795
796 ACTIVE->PREPARED->COMMITTED is only possible when trx->in_rw_trx_list.
797 The transition ACTIVE->PREPARED is protected by trx_sys->mutex.
798
799 ACTIVE->COMMITTED is possible when the transaction is in
800 rw_trx_list.
801
802 Transitions to COMMITTED are protected by trx->mutex.
803
804 NOTE: Some of these state change constraints are an overkill,
805 currently only required for a consistent view for printing stats.
806 This unnecessarily adds a huge cost for the general case. */
807
808 std::atomic<trx_state_t> state;
809
810 /* If set, this transaction should stop inheriting (GAP)locks.
811 Generally set to true during transaction prepare for RC or lower
812 isolation, if requested. Needed for replication replay where
813 we don't want to get blocked on GAP locks taken for protecting
814 concurrent unique insert or replace operation. */
816
817 ReadView *read_view; /*!< consistent read view used in the
818 transaction, or NULL if not yet set */
819
821 trx_list; /*!< list of transactions;
822 protected by trx_sys->mutex. */
824 no_list; /*!< Required during view creation
825 to check for the view limit for
826 transactions that are committing */
827
828 /** Information about the transaction locks and state.
829 Protected by trx->mutex or lock_sys latches or both */
831
832 /**
833 false: a normal transaction
834 true: a recovered transaction
835
836 Set to true when srv_is_being_started for recovered transactions.
837 Set to false without any protection in trx_init (where no other thread should
838 access this object anyway).
839 Can be read safely when holding trx_sys->mutex and trx belongs to rw_trx_list,
840 as trx_init can not be called until trx leaves rw_trx_list which requires the
841 trx_sys->mutex.
842 */
844
845 std::atomic<std::thread::id> killed_by; /*!< The thread ID that wants to
846 kill this transaction asynchronously.
847 This is required because we recursively
848 enter the handlerton methods and need
849 to distinguish between the kill thread
850 and the transaction thread.
851
852 Note: We need to be careful w.r.t the
853 Thread Pool. The thread doing the kill
854 should not leave InnoDB between the
855 mark and the actual async kill because
856 the running thread can change. */
857
858 /* These fields are not protected by any mutex. */
859 const char *op_info; /*!< English text describing the
860 current operation, or an empty
861 string */
862
863 /** Current isolation level */
865
866 bool check_foreigns; /*!< normally true, but if the user
867 wants to suppress foreign key checks,
868 (in table imports, for example) we
869 set this false */
870 /*------------------------------*/
871 /* MySQL has a transaction coordinator to coordinate two phase
872 commit between multiple storage engines and the binary log. When
873 an engine participates in a transaction, it's responsible for
874 registering itself using the trans_register_ha() API. */
875 bool is_registered; /* This flag is set to true after the
876 transaction has been registered with
877 the coordinator using the XA API, and
878 is set to false after commit or
879 rollback. */
880 /*------------------------------*/
882 /*!< normally true, but if the user
883 wants to speed up inserts by
884 suppressing unique key checks
885 for secondary indexes when we decide
886 if we can use the insert buffer for
887 them, we set this false */
888 bool flush_log_later; /* In 2PC, we hold the
889 prepare_commit mutex across
890 both phases. In that case, we
891 defer flush of the logs to disk
892 until after we release the
893 mutex. */
894 bool must_flush_log_later; /*!< this flag is set to true in
895 trx_commit() if flush_log_later was
896 true, and there were modifications by
897 the transaction; in that case we must
898 flush the log in
899 trx_commit_complete_for_mysql() */
901 /*!< true if this trx has latched the
902 search system latch in S-mode.
903 This now can only be true in
904 row_search_mvcc, the btr search latch
905 must has been released before exiting,
906 and this flag would be set to false */
907 trx_dict_op_t dict_operation; /**< @see enum trx_dict_op_t */
908
909 bool ddl_operation; /*!< True if this trx involves dd table
910 change */
911 bool ddl_must_flush; /*!< True if this trx involves dd table
912 change, and must flush */
913 bool in_truncate; /* This trx is doing truncation */
914
915 /* Fields protected by the srv_conc_mutex. */
917 /*!< this is true if we have declared
918 this transaction in
919 srv_conc_enter_innodb to be inside the
920 InnoDB engine */
922 /*!< this can be > 0 only when
923 declared_to_... is true; when we come
924 to srv_conc_innodb_enter, if the value
925 here is > 0, we decrement this by 1 */
927 /*!< 0, RW_S_LATCH, or RW_X_LATCH:
928 the latch mode trx currently holds
929 on dict_operation_lock. Protected
930 by dict_operation_lock. */
931
932 /** Time the state last time became TRX_STATE_ACTIVE. */
933 std::atomic<std::chrono::system_clock::time_point> start_time{
934 std::chrono::system_clock::time_point{}};
935 static_assert(decltype(start_time)::is_always_lock_free);
936
937 lsn_t commit_lsn; /*!< lsn at the time of the commit */
938
939 /*------------------------------*/
940 THD *mysql_thd; /*!< MySQL thread handle corresponding
941 to this trx, or NULL */
942
944 /*!< if MySQL binlog is used, this field
945 contains a pointer to the latest file
946 name; this is NULL if binlog is not
947 used */
949 /*!< if MySQL binlog is used, this
950 field contains the end offset of the
951 binlog entry */
952 /*------------------------------*/
953 uint32_t n_mysql_tables_in_use; /*!< number of Innobase tables
954 used in the processing of the current
955 SQL statement in MySQL */
957 /*!< how many tables the current SQL
958 statement uses, except those
959 in consistent read */
960 /*------------------------------*/
961#ifdef UNIV_DEBUG
962 /** True iff in trx_sys->rw_trx_list */
964
965#endif /* UNIV_DEBUG */
967 mysql_trx_list; /*!< list of transactions created for
968 MySQL; protected by trx_sys->mutex */
969#ifdef UNIV_DEBUG
971 /*!< true if in
972 trx_sys->mysql_trx_list */
973#endif /* UNIV_DEBUG */
974 /*------------------------------*/
975
976 /** DB_SUCCESS if no error, otherwise error number.
977 Accessed without any mutex only by the thread doing the transaction or, if it
978 is suspended (waiting for a lock), by the thread holding this->mutex which
979 has changed trx->lock.wait_lock to nullptr and will wake up the transaction.*/
981
982 const dict_index_t *error_index; /*!< if the error number indicates a
983 duplicate key error, a pointer to
984 the problematic index is stored here */
985 ulint error_key_num; /*!< if the index creation fails to a
986 duplicate key error, a mysql key
987 number of that index is stored here */
988 sess_t *sess; /*!< session of the trx, NULL if none */
989 que_t *graph; /*!< query currently run in the session,
990 or NULL if none; NOTE that the query
991 belongs to the session, and it can
992 survive over a transaction commit, if
993 it is a stored procedure with a COMMIT
994 WORK statement, for instance */
995 /*------------------------------*/
997 trx_savepoints{}; /*!< savepoints set with SAVEPOINT ..., oldest first */
998 /*------------------------------*/
999 UndoMutex undo_mutex; /*!< mutex protecting the fields in this
1000 section (down to undo_no_arr), EXCEPT
1001 last_sql_stat_start, which can be
1002 accessed only when we know that there
1003 cannot be any activity in the undo
1004 logs! */
1005 undo_no_t undo_no; /*!< next undo log record number to
1006 assign; since the undo log is
1007 private for a transaction, this
1008 is a simple ascending sequence
1009 with no gaps; thus it represents
1010 the number of modified/inserted
1011 rows in a transaction */
1013 /*!< space id where last undo record
1014 was written */
1016 /*!< undo_no when the last sql statement
1017 was started: in case of an error, trx
1018 is rolled back down to this undo
1019 number; see note at undo_mutex! */
1020 trx_rsegs_t rsegs; /* rollback segments for undo logging */
1021 undo_no_t roll_limit; /*!< least undo number to undo during
1022 a partial rollback; 0 otherwise */
1023#ifdef UNIV_DEBUG
1024 bool in_rollback; /*!< true when the transaction is
1025 executing a partial or full rollback */
1026#endif /* UNIV_DEBUG */
1027 ulint pages_undone; /*!< number of undo log pages undone
1028 since the last undo log truncation */
1029 /*------------------------------*/
1030 ulint n_autoinc_rows; /*!< no. of AUTO-INC rows required for
1031 an SQL statement. This is useful for
1032 multi-row INSERTs */
1033 /*------------------------------*/
1034 bool read_only; /*!< true if transaction is flagged
1035 as a READ-ONLY transaction.
1036 if auto_commit && will_lock == 0
1037 then it will be handled as a
1038 AC-NL-RO-SELECT (Auto Commit Non-Locking
1039 Read Only Select). A read only
1040 transaction will not be assigned an
1041 UNDO log. */
1042 bool auto_commit; /*!< true if it is an autocommit */
1043 uint32_t will_lock; /*!< Will acquire some locks. Increment
1044 each time we determine that a lock will
1045 be acquired by the MySQL layer. */
1046#ifndef UNIV_HOTBACKUP
1047 /*------------------------------*/
1048 fts_trx_t *fts_trx; /*!< FTS information, or NULL if
1049 transaction hasn't modified tables
1050 with FTS indexes (yet). */
1051 doc_id_t fts_next_doc_id; /* The document id used for updates */
1052 /*------------------------------*/
1053 uint32_t flush_tables; /*!< if "covering" the FLUSH TABLES",
1054 count of tables being flushed. */
1055
1056 /*------------------------------*/
1057 bool internal; /*!< true if it is a system/internal
1058 transaction background task. Such
1059 transactions are always treated as
1060 read-write. */
1061 /*------------------------------*/
1062 /** Transaction persists GTID. */
1064
1065#ifdef UNIV_DEBUG
1066 ulint start_line; /*!< Track where it was started from */
1067 const char *start_file; /*!< Filename where it was started */
1068#endif /* UNIV_DEBUG */
1069
1070 lint n_ref; /*!< Count of references, protected
1071 by trx_t::mutex. We can't release the
1072 locks nor commit the transaction until
1073 this reference is 0. We can change
1074 the state to COMMITTED_IN_MEMORY to
1075 signify that it is no longer
1076 "active". */
1077
1078 /** Version of this instance. It is incremented each time the
1079 instance is re-used in trx_start_low(). It is used to track
1080 whether a transaction has been restarted since it was tagged
1081 for asynchronous rollback. */
1082 std::atomic_uint64_t version;
1083
1084 XID *xid; /*!< X/Open XA transaction
1085 identification to identify a
1086 transaction branch */
1087 trx_mod_tables_t mod_tables; /*!< List of tables that were modified
1088 by this transaction */
1089#endif /* !UNIV_HOTBACKUP */
1090 /*------------------------------*/
1091 bool api_trx; /*!< trx started by InnoDB API */
1092 bool api_auto_commit; /*!< automatic commit */
1093 bool read_write; /*!< if read and write operation */
1094
1095 /** This flag is set for trx_t objects used by the purge sys. We use the flag
1096 when validating mysql_trx_list in trx_sys_before_pre_dd_shutdown_validate.
1097 Purge threads can have allocated trx_t objects visible in the mysql_trx_list
1098 at this point during shutdown, this is acceptable so we need a way to signal
1099 this fact. */
1101 /*------------------------------*/
1102 char *detailed_error; /*!< detailed error message for last
1103 error, or empty. */
1104 Flush_observer *flush_observer; /*!< flush observer */
1105
1106#ifdef UNIV_DEBUG
1107 bool is_dd_trx; /*!< True if the transaction is used for
1108 doing Non-locking Read-only Read
1109 Committed on DD tables */
1110#endif /* UNIV_DEBUG */
1112
1113 bool is_read_uncommitted() const {
1115 }
1116
1119 }
1120
1121 bool skip_gap_locks() const {
1122 switch (isolation_level) {
1123 case READ_UNCOMMITTED:
1124 case READ_COMMITTED:
1125 return (true);
1126 case REPEATABLE_READ:
1127 case SERIALIZABLE:
1128 return (false);
1129 }
1130 ut_d(ut_error);
1131 ut_o(return (false));
1132 }
1133
1134 bool allow_semi_consistent() const { return (skip_gap_locks()); }
1135 /** Checks if this transaction releases locks on non matching records due to
1136 low isolation level.
1137 @return true iff in this transaction's isolation level locks on records which
1138 do not match the WHERE clause are released */
1140};
1141
1142#ifndef UNIV_HOTBACKUP
1143/**
1144Transactions that aren't started by the MySQL server don't set
1145the trx_t::mysql_thd field. For such transactions we set the lock
1146wait timeout to 0 instead of the user configured value that comes
1147from innodb_lock_wait_timeout via trx_t::mysql_thd.
1148@param t transaction
1149@return lock wait timeout in seconds */
1152}
1153
1154/**
1155Determine if the transaction is a non-locking autocommit select
1156(implied read-only).
1157@param t transaction
1158@return true if non-locking autocommit select transaction. */
1159static inline bool trx_is_autocommit_non_locking(const trx_t *t) {
1160 return t->auto_commit && t->will_lock == 0;
1161}
1162
1163/** Check transaction state */
1164static inline void check_trx_state(const trx_t *t) {
1166 switch (t->state) {
1167 case TRX_STATE_PREPARED:
1168 /* fall through */
1169 case TRX_STATE_ACTIVE:
1171 return;
1174 break;
1175 }
1176 ut_error;
1177}
1178
1179/**
1180Assert that the transaction is in the trx_sys_t::rw_trx_list */
1181static inline void assert_trx_in_rw_list(const trx_t *t) {
1182 ut_ad(!t->read_only);
1183 ut_ad(t->in_rw_trx_list == !(t->read_only || !t->rsegs.m_redo.rseg));
1184 check_trx_state(t);
1185}
1186
1187/** Check if transaction is free so that it can be re-initialized.
1188@param t transaction handle */
1189static inline void assert_trx_is_free(const trx_t *t) {
1194 ut_ad((t)->lock.wait_thr == nullptr);
1195 ut_ad(UT_LIST_GET_LEN((t)->lock.trx_locks) == 0);
1196 ut_ad((t)->dict_operation == TRX_DICT_OP_NONE);
1197}
1198
1199/** Check if transaction is in-active so that it can be freed and put back to
1200transaction pool.
1201@param t transaction handle */
1202static inline void assert_trx_is_inactive(const trx_t *t) {
1205}
1206
1207#ifdef UNIV_DEBUG
1208/** Assert that an autocommit non-locking select cannot be in the
1209 rw_trx_list and that it is a read-only transaction.
1210 The transaction must be in the mysql_trx_list. */
1211static inline void assert_trx_nonlocking_or_in_list(const trx_t *t) {
1213 trx_state_t t_state = t->state;
1214 ut_ad(t->read_only);
1215 ut_ad(!t->is_recovered);
1216 ut_ad(!t->in_rw_trx_list);
1218 ut_ad(t_state == TRX_STATE_NOT_STARTED ||
1219 t_state == TRX_STATE_FORCED_ROLLBACK || t_state == TRX_STATE_ACTIVE);
1220 } else {
1221 check_trx_state(t);
1222 }
1223}
1224#else /* UNIV_DEBUG */
1225/** Assert that an autocommit non-locking select cannot be in the
1226 rw_trx_list and that it is a read-only transaction.
1227 The transaction must be in the mysql_trx_list. */
1228#define assert_trx_nonlocking_or_in_list(trx) ((void)0)
1229#endif /* UNIV_DEBUG */
1230
1231/**
1232Determine if the transaction is a non-locking autocommit select
1233with an explicit check for the read-only status.
1234@param t transaction
1235@return true if non-locking autocommit read-only transaction. */
1236static inline bool trx_is_ac_nl_ro(const trx_t *t) {
1238}
1239
1240/**
1241Increase the reference count. If the transaction is in state
1242TRX_STATE_COMMITTED_IN_MEMORY then the transaction is considered
1243committed and the reference count is not incremented.
1244@param trx Transaction that is being referenced */
1245static inline void trx_reference(trx_t *trx);
1246
1247/**
1248Release the transaction. Decrease the reference count.
1249@param trx Transaction that is being released */
1250static inline void trx_release_reference(trx_t *trx);
1251
1252/**
1253Check if the transaction is being referenced. */
1254static inline bool trx_is_referenced(const trx_t *t) { return t->n_ref > 0; }
1255
1256/** Calculates the "weight" of a transaction. The weight of one transaction
1257 is estimated as the number of altered rows + the number of locked rows.
1258 @param t transaction
1259 @return transaction weight */
1260static inline uint64_t TRX_WEIGHT(const trx_t *t) {
1261 return t->undo_no + UT_LIST_GET_LEN(t->lock.trx_locks);
1262}
1263
1264#ifdef UNIV_DEBUG
1265static inline void trx_start_if_not_started_xa(trx_t *t, bool rw,
1266 ut::Location loc) {
1267 t->start_line = loc.line;
1268 t->start_file = loc.filename;
1270}
1271
1272static inline void trx_start_if_not_started(trx_t *t, bool rw, ut::Location l) {
1273 t->start_line = l.line;
1274 t->start_file = l.filename;
1276}
1277
1278static inline void trx_start_internal(trx_t *t, ut::Location loc) {
1279 t->start_line = loc.line;
1280 t->start_file = loc.filename;
1282}
1283
1285 t->start_line = loc.line;
1286 t->start_file = loc.filename;
1288}
1289#else
1290static inline void trx_start_if_not_started_xa(trx_t *t, bool rw,
1291 ut::Location loc) {
1293}
1294
1295static inline void trx_start_internal(trx_t *t, ut::Location loc) {
1297}
1298
1299static inline void trx_start_internal_read_only(trx_t *t, ut::Location loc) {
1301}
1302
1303static inline void trx_start_if_not_started(trx_t *t, bool rw, ut::Location l) {
1305}
1306#endif /* UNIV_DEBUG */
1307
1308/* Transaction isolation levels (trx->isolation_level) */
1309#define TRX_ISO_READ_UNCOMMITTED trx_t::READ_UNCOMMITTED
1310#define TRX_ISO_READ_COMMITTED trx_t::READ_COMMITTED
1311#define TRX_ISO_REPEATABLE_READ trx_t::REPEATABLE_READ
1312#define TRX_ISO_SERIALIZABLE trx_t::SERIALIZABLE
1313
1314/**
1315Check if transaction was started. Note, that after the check
1316situation might have already been changed (and note that holding
1317the trx_sys->mutex does not prevent state transitions for read-only
1318transactions).
1319@param[in] trx Transaction whose state we need to check
1320@return true if transaction is in state started */
1321inline bool trx_was_started(const trx_t *trx) {
1322 const auto trx_state = trx->state.load(std::memory_order_relaxed);
1323 return trx_state != TRX_STATE_NOT_STARTED &&
1324 trx_state != TRX_STATE_FORCED_ROLLBACK;
1325}
1326
1327/**
1328Check if transaction is started.
1329@param[in] trx Transaction whose state we need to check
1330@return true if transaction is in state started */
1331inline bool trx_is_started(const trx_t *trx) {
1333 return trx_was_started(trx);
1334}
1335
1336/** Commit node states */
1338 COMMIT_NODE_SEND = 1, /*!< about to send a commit signal to
1339 the transaction */
1340 COMMIT_NODE_WAIT /*!< commit signal sent to the transaction,
1341 waiting for completion */
1343
1344/** Commit command node in a query graph */
1346 que_common_t common; /*!< node type: QUE_NODE_COMMIT */
1347 enum commit_node_state state; /*!< node execution state */
1348};
1349
1350#ifdef UNIV_DEBUG
1351
1352/** Test if trx->mutex is owned by the current thread. */
1353bool inline trx_mutex_own(const trx_t *trx) { return mutex_own(&trx->mutex); }
1354
1355/**
1356Verifies the invariants and records debug state related to latching rules.
1357Called during trx_mutex_enter before the actual mutex acquisition.
1358@param[in] trx The transaction for which trx_mutex_enter(trx) is
1359 called
1360@param[in] allow_another If false, then no further calls to trx_mutex_enter
1361 are allowed, until trx_mutex_exit().
1362 If true, then this must be the first trx acquisition
1363 and we will allow one more.
1364*/
1365void trx_before_mutex_enter(const trx_t *trx, bool allow_another);
1366
1367/**
1368Verifies the invariants and records debug state related to latching rules.
1369Called during trx_mutex_exit before the actual mutex release.
1370@param[in] trx The transaction for which trx_mutex_exit(trx) is called
1371*/
1372void trx_before_mutex_exit(const trx_t *trx);
1373#endif
1374
1375/**
1376Please do not use this low-level macro.
1377Use trx_mutex_enter(t) instead.
1378In rare cases where you need to take two trx->mutex-es, take the first one
1379using trx_mutex_enter_first_of_two(t1), and the second one with
1380trx_mutex(2)
1381*/
1382#define trx_mutex_enter_low(t, first_of_two) \
1383 do { \
1384 ut_ad(!trx_mutex_own(t)); \
1385 ut_d(trx_before_mutex_enter(t, first_of_two)); \
1386 mutex_enter(&t->mutex); \
1387 } while (0)
1388
1389/** Acquire the trx->mutex (and promise not to request any more). */
1390#define trx_mutex_enter(t) trx_mutex_enter_low(t, false)
1391
1392/** Acquire the trx->mutex (and indicate we might request one more). */
1393#define trx_mutex_enter_first_of_two(t) trx_mutex_enter_low(t, true)
1394
1395/** Release the trx->mutex. */
1396#define trx_mutex_exit(t) \
1397 do { \
1398 ut_ad(trx_mutex_own(t)); \
1399 ut_d(trx_before_mutex_exit(t)); \
1400 mutex_exit(&t->mutex); \
1401 } while (0)
1402
1403/** Track if a transaction is executing inside InnoDB code. It acts
1404like a gate between the Server and InnoDB. */
1406 public:
1407 /**
1408 @param[in,out] trx Transaction entering InnoDB via the handler
1409 @param[in] disable true if called from COMMIT/ROLLBACK method */
1410 TrxInInnoDB(trx_t *trx, bool disable = false) : m_trx(trx) {
1411 enter(trx, disable);
1412 }
1413
1414 /**
1415 Destructor */
1417
1418 /**
1419 @return true if the transaction has been marked for asynchronous
1420 rollback */
1421 bool is_aborted() const { return (is_aborted(m_trx)); }
1422
1423 /**
1424 @return true if the transaction can't be rolled back asynchronously */
1426 return ((m_trx->in_innodb & TRX_FORCE_ROLLBACK_DISABLE) > 0);
1427 }
1428
1429 /**
1430 @return true if the transaction has been marked for asynchronous
1431 rollback */
1432 static bool is_aborted(const trx_t *trx) {
1434
1435 const auto trx_state = trx->state.load(std::memory_order_relaxed);
1436
1437 if (trx_state == TRX_STATE_NOT_STARTED) {
1438 return (false);
1439 }
1440
1441 ut_ad(srv_read_only_mode || trx->in_depth > 0);
1442 ut_ad(srv_read_only_mode || trx->in_innodb > 0);
1443
1444 return (trx->abort || trx_state == TRX_STATE_FORCED_ROLLBACK);
1445 }
1446
1447 /**
1448 Start statement requested for transaction.
1449 @param[in, out] trx Transaction at the start of a SQL statement */
1450 static void begin_stmt(trx_t *trx) { enter(trx, false); }
1451
1452 /**
1453 Note an end statement for transaction
1454 @param[in, out] trx Transaction at end of a SQL statement */
1455 static void end_stmt(trx_t *trx) { exit(trx); }
1456
1457 /**
1458 @return true if the rollback is being initiated by the thread that
1459 marked the transaction for asynchronous rollback */
1460 static bool is_async_rollback(const trx_t *trx) {
1461 return trx->killed_by == std::this_thread::get_id();
1462 }
1463
1464 private:
1465 /** Note that we have crossed into InnoDB code.
1466 @param[in] trx transaction
1467 @param[in] disable true if called from COMMIT/ROLLBACK method */
1468 static void enter(trx_t *trx, bool disable) {
1469 if (srv_read_only_mode) {
1470 return;
1471 }
1472
1473 ut_ad(!is_async_rollback(trx));
1475
1476 /* If it hasn't already been marked for async rollback.
1477 and it will be committed/rolled back. */
1478 if (disable) {
1479 trx_mutex_enter(trx);
1480 if (!is_forced_rollback(trx) && is_started(trx) &&
1482 ut_ad(trx->killed_by == std::thread::id{});
1483
1484 /* This transaction has crossed the point of
1485 no return and cannot be rolled back
1486 asynchronously now. It must commit or rollback
1487 synchronously. */
1488
1490 }
1491 trx_mutex_exit(trx);
1492 }
1493
1494 /* Avoid excessive mutex acquire/release */
1495 ++trx->in_depth;
1496
1497 /* If trx->in_depth is greater than 1 then
1498 transaction is already in InnoDB. */
1499 if (trx->in_depth > 1) {
1500 return;
1501 }
1502
1503 trx_mutex_enter(trx);
1504
1505 wait(trx);
1506
1508
1509 ++trx->in_innodb;
1510
1511 trx_mutex_exit(trx);
1512 }
1513
1514 /**
1515 Note that we are exiting InnoDB code */
1516 static void exit(trx_t *trx) {
1517 if (srv_read_only_mode) {
1518 return;
1519 }
1520
1521 /* Avoid excessive mutex acquire/release */
1522
1523 ut_ad(trx->in_depth > 0);
1524
1525 --trx->in_depth;
1526
1527 if (trx->in_depth > 0) {
1528 return;
1529 }
1530
1531 trx_mutex_enter(trx);
1532
1534
1535 --trx->in_innodb;
1536
1537 trx_mutex_exit(trx);
1538 }
1539
1540 /*
1541 @return true if it is a forced rollback, asynchronously */
1542 static bool is_forced_rollback(const trx_t *trx) {
1543 ut_ad(trx_mutex_own(trx));
1544
1545 return ((trx->in_innodb & TRX_FORCE_ROLLBACK)) > 0;
1546 }
1547
1548 /**
1549 Wait for the asynchronous rollback to complete, if it is in progress */
1550 static void wait(const trx_t *trx) {
1551 ut_ad(trx_mutex_own(trx));
1552
1553 ulint loop_count = 0;
1554 /* start with optimistic sleep time - 20 micro seconds. */
1555 ulint sleep_time = 20;
1556
1557 while (is_forced_rollback(trx)) {
1558 /* Wait for the async rollback to complete */
1559
1560 trx_mutex_exit(trx);
1561
1562 loop_count++;
1563 /* If the wait is long, don't hog the cpu. */
1564 if (loop_count < 100) {
1565 /* 20 microseconds */
1566 sleep_time = 20;
1567 } else if (loop_count < 1000) {
1568 /* 1 millisecond */
1569 sleep_time = 1000;
1570 } else {
1571 /* 100 milliseconds */
1572 sleep_time = 100000;
1573 }
1574
1575 std::this_thread::sleep_for(std::chrono::microseconds(sleep_time));
1576
1577 trx_mutex_enter(trx);
1578 }
1579 }
1580
1581 private:
1582 /**
1583 @return true if transaction is started */
1584 static bool is_started(const trx_t *trx) {
1585 ut_ad(trx_mutex_own(trx));
1586
1587 return trx_is_started(trx);
1588 }
1589
1590 /**
1591 Transaction instance crossing the handler boundary from the Server. */
1593};
1594
1595/** Check if transaction is internal XA transaction
1596@param[in] trx transaction
1597@return true, iff internal XA transaction. */
1598bool trx_is_mysql_xa(const trx_t *trx);
1599
1600/** Update transaction binlog file name and position from session THD.
1601@param[in,out] trx current transaction. */
1603
1604/** Checks whether or not the transaction has been marked as prepared in TC.
1605@param[in] trx the transaction
1606@return true if the transaction is marked as prepared in TC, false otherwise. */
1607bool trx_is_prepared_in_tc(trx_t const *trx);
1608
1609/** Does the 2nd phase of an XA transaction prepare for MySQL.
1610@param[in,out] trx Transaction instance to finish prepare
1611@return DB_SUCCESS or error number */
1613
1614#include "trx0trx.ic"
1615#endif /* !UNIV_HOTBACKUP */
1616
1617#endif
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:46
We use Flush_observer to track flushing of non-redo logged pages in bulk create index(btr0load....
Definition: buf0flu.h:269
static bool is_view_active(ReadView *view)
Definition: read0read.h:79
Read view lists the trx ids of those transactions for which a consistent read should not see the modi...
Definition: read0types.h:47
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_lexer_thd.h:35
Track if a transaction is executing inside InnoDB code.
Definition: trx0trx.h:1405
static void begin_stmt(trx_t *trx)
Start statement requested for transaction.
Definition: trx0trx.h:1450
static void end_stmt(trx_t *trx)
Note an end statement for transaction.
Definition: trx0trx.h:1455
static void enter(trx_t *trx, bool disable)
Note that we have crossed into InnoDB code.
Definition: trx0trx.h:1468
static void wait(const trx_t *trx)
Wait for the asynchronous rollback to complete, if it is in progress.
Definition: trx0trx.h:1550
static bool is_aborted(const trx_t *trx)
Definition: trx0trx.h:1432
~TrxInInnoDB()
Destructor.
Definition: trx0trx.h:1416
static bool is_forced_rollback(const trx_t *trx)
Definition: trx0trx.h:1542
static bool is_async_rollback(const trx_t *trx)
Definition: trx0trx.h:1460
bool is_aborted() const
Definition: trx0trx.h:1421
static bool is_started(const trx_t *trx)
Definition: trx0trx.h:1584
static void exit(trx_t *trx)
Note that we are exiting InnoDB code.
Definition: trx0trx.h:1516
bool is_rollback_disabled() const
Definition: trx0trx.h:1425
trx_t * m_trx
Transaction instance crossing the handler boundary from the Server.
Definition: trx0trx.h:1592
TrxInInnoDB(trx_t *trx, bool disable=false)
Definition: trx0trx.h:1410
Class to maintain list of externally coordinated transactions and their current state at recovery.
Definition: handler.h:1258
Allocator that allows std::* containers to manage their memory through ut::malloc* and ut::free libra...
Definition: ut0new.h:2180
static MEM_ROOT mem_root
Definition: client_plugin.cc:113
dberr_t
Definition: db0err.h:38
Data dictionary global types.
Full text search header file.
uint64_t doc_id_t
Document id type.
Definition: fts0fts.h:78
std::chrono::seconds thd_lock_wait_timeout(THD *thd)
Returns the lock wait timeout for the current connection.
Definition: ha_innodb.cc:1989
Prototypes for global functions in ha_innodb.cc that are called by InnoDB C code.
The transaction lock system global types.
uint64_t lsn_t
Type used for all log sequence number storage and arithmetic.
Definition: log0types.h:62
The memory management.
const std::string FILE("FILE")
Definition: os0file.h:88
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:78
Definition: varlen_sort.h:174
pid_type get_id()
Definition: process.h:47
Query graph global types.
Cursor read.
The server main program.
bool srv_read_only_mode
Set if InnoDB must operate in read-only mode.
Definition: srv0srv.cc:197
The MEM_ROOT is a simple arena, where allocations are carved out of larger blocks.
Definition: my_alloc.h:82
Commit command node in a query graph.
Definition: trx0trx.h:1345
enum commit_node_state state
node execution state
Definition: trx0trx.h:1347
que_common_t common
node type: QUE_NODE_COMMIT
Definition: trx0trx.h:1346
Data structure for an index.
Definition: dict0mem.h:1045
Information about changes in a single transaction affecting the FTS system.
Definition: fts0fts.h:228
Definition: ut0vec.h:212
The info structure stored at the beginning of a heap block.
Definition: mem0mem.h:301
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:176
Definition: que0types.h:50
Definition: que0que.h:300
Definition: que0que.h:241
Definition: usr0sess.h:53
Plain structure to store information about XA transaction id and a list of table names involved into ...
Definition: xa.h:289
Latching protocol for trx_lock_t::que_state.
Definition: trx0trx.h:409
std::atomic< bool > inherit_all
Used to indicate that every lock of this transaction placed on a record which is being purged should ...
Definition: trx0trx.h:566
trx_lock_t()=default
Default constructor.
std::atomic< ulint > n_rec_locks
Number of rec locks in this trx.
Definition: trx0trx.h:557
mem_heap_t * lock_heap
Memory heap for trx_locks.
Definition: trx0trx.h:532
bool start_stmt
The transaction called ha_innobase::start_stmt() to lock a table.
Definition: trx0trx.h:585
std::atomic< trx_t * > blocking_trx
If this transaction is waiting for a lock, then blocking_trx points to a transaction which holds a co...
Definition: trx0trx.h:447
trx_lock_list_t trx_locks
Locks requested by the transaction.
Definition: trx0trx.h:546
std::atomic< lock_t * > wait_lock
The lock request of this transaction is waiting for.
Definition: trx0trx.h:468
std::chrono::system_clock::time_point wait_started
Lock wait started at this time.
Definition: trx0trx.h:509
uint64_t trx_locks_version
Incremented each time a lock is added or removed from the trx->lock.trx_locks, so that the thread whi...
Definition: trx0trx.h:423
trx_que_t que_state
valid when trx->state == TRX_STATE_ACTIVE: TRX_QUE_RUNNING, TRX_QUE_LOCK_WAIT, ...
Definition: trx0trx.h:415
bool in_rollback
When a transaction is forced to rollback due to a deadlock check or by another high priority transact...
Definition: trx0trx.h:580
lock_pool_t table_pool
Pre-allocated table locks.
Definition: trx0trx.h:523
ulint rec_cached
Next free record lock in pool.
Definition: trx0trx.h:526
ulint n_active_thrs
number of active query threads
Definition: trx0trx.h:413
std::atomic< trx_schedule_weight_t > schedule_weight
Weight of the waiting transaction used for scheduling.
Definition: trx0trx.h:574
bool was_chosen_as_deadlock_victim
when the transaction decides to wait for a lock, it sets this to false; if another transaction choose...
Definition: trx0trx.h:498
ib_vector_t * autoinc_locks
AUTOINC locks held by this transaction.
Definition: trx0trx.h:552
uint32_t wait_lock_type
Stores the type of the most recent lock for which this trx had to wait.
Definition: trx0trx.h:496
lock_pool_t rec_pool
Pre-allocated record locks.
Definition: trx0trx.h:520
ulint table_cached
Next free table lock in pool.
Definition: trx0trx.h:529
que_thr_t * wait_thr
query thread belonging to this trx that is in QUE_THR_LOCK_WAIT state.
Definition: trx0trx.h:517
A savepoint set with SQL's "SAVEPOINT savepoint_id" command.
Definition: trx0roll.h:167
The rollback segment memory object.
Definition: trx0types.h:176
Rollback segments assigned to a transaction for undo logging.
Definition: trx0trx.h:665
trx_undo_ptr_t m_noredo
undo log ptr holding reference to a rollback segment that resides in temp tablespace used for undo lo...
Definition: trx0trx.h:674
trx_undo_ptr_t m_redo
undo log ptr holding reference to a rollback segment that resides in system/undo tablespace used for ...
Definition: trx0trx.h:669
Transaction savepoint.
Definition: trx0types.h:147
Definition: trx0trx.h:683
const char * op_info
English text describing the current operation, or an empty string.
Definition: trx0trx.h:859
bool releases_gap_locks_at_prepare() const
Definition: trx0trx.h:1117
space_id_t undo_rseg_space
space id where last undo record was written
Definition: trx0trx.h:1012
bool is_recovered
false: a normal transaction true: a recovered transaction
Definition: trx0trx.h:843
uint32_t dict_operation_lock_mode
0, RW_S_LATCH, or RW_X_LATCH: the latch mode trx currently holds on dict_operation_lock.
Definition: trx0trx.h:926
uint32_t n_mysql_tables_in_use
number of Innobase tables used in the processing of the current SQL statement in MySQL
Definition: trx0trx.h:953
char * detailed_error
detailed error message for last error, or empty.
Definition: trx0trx.h:1102
bool allow_semi_consistent() const
Definition: trx0trx.h:1134
ulint magic_n
Definition: trx0trx.h:1111
ulint n_autoinc_rows
no.
Definition: trx0trx.h:1030
bool must_flush_log_later
this flag is set to true in trx_commit() if flush_log_later was true, and there were modifications by...
Definition: trx0trx.h:894
bool flush_log_later
Definition: trx0trx.h:888
no_list
Required during view creation to check for the view limit for transactions that are committing.
Definition: trx0trx.h:824
trx_dict_op_t dict_operation
Definition: trx0trx.h:907
THD * mysql_thd
MySQL thread handle corresponding to this trx, or NULL.
Definition: trx0trx.h:940
XID * xid
X/Open XA transaction identification to identify a transaction branch.
Definition: trx0trx.h:1084
fts_trx_t * fts_trx
FTS information, or NULL if transaction hasn't modified tables with FTS indexes (yet).
Definition: trx0trx.h:1048
undo_no_t undo_no
next undo log record number to assign; since the undo log is private for a transaction,...
Definition: trx0trx.h:1005
bool releases_non_matching_rows() const
Checks if this transaction releases locks on non matching records due to low isolation level.
Definition: trx0trx.h:1139
uint32_t will_lock
Will acquire some locks.
Definition: trx0trx.h:1043
ulint start_line
Track where it was started from.
Definition: trx0trx.h:1066
que_t * graph
query currently run in the session, or NULL if none; NOTE that the query belongs to the session,...
Definition: trx0trx.h:989
std::atomic< std::chrono::system_clock::time_point > start_time
Time the state last time became TRX_STATE_ACTIVE.
Definition: trx0trx.h:933
Flush_observer * flush_observer
flush observer
Definition: trx0trx.h:1104
TrxMutex mutex
Mutex protecting the fields state and lock (except some fields of lock, which are protected by lock_s...
Definition: trx0trx.h:714
doc_id_t fts_next_doc_id
Definition: trx0trx.h:1051
const char * mysql_log_file_name
if MySQL binlog is used, this field contains a pointer to the latest file name; this is NULL if binlo...
Definition: trx0trx.h:943
lint n_ref
Count of references, protected by trx_t::mutex.
Definition: trx0trx.h:1070
uint32_t in_innodb
if the thread is executing in the InnoDB context count > 0.
Definition: trx0trx.h:728
std::atomic_uint64_t version
Version of this instance.
Definition: trx0trx.h:1082
bool auto_commit
true if it is an autocommit
Definition: trx0trx.h:1042
bool is_dd_trx
True if the transaction is used for doing Non-locking Read-only Read Committed on DD tables.
Definition: trx0trx.h:1107
uint32_t flush_tables
if "covering" the FLUSH TABLES", count of tables being flushed.
Definition: trx0trx.h:1053
std::atomic< trx_state_t > state
State of the trx from the point of view of concurrency control and the valid state transitions.
Definition: trx0trx.h:808
isolation_level_t isolation_level
Current isolation level.
Definition: trx0trx.h:864
bool in_mysql_trx_list
true if in trx_sys->mysql_trx_list
Definition: trx0trx.h:970
bool api_auto_commit
automatic commit
Definition: trx0trx.h:1092
uint32_t in_depth
Track nested TrxInInnoDB count.
Definition: trx0trx.h:725
uint32_t n_tickets_to_enter_innodb
this can be > 0 only when declared_to_... is true; when we come to srv_conc_innodb_enter,...
Definition: trx0trx.h:921
bool skip_lock_inheritance
Definition: trx0trx.h:815
ulint pages_undone
number of undo log pages undone since the last undo log truncation
Definition: trx0trx.h:1027
bool ddl_must_flush
True if this trx involves dd table change, and must flush.
Definition: trx0trx.h:911
undo_no_t roll_limit
least undo number to undo during a partial rollback; 0 otherwise
Definition: trx0trx.h:1021
trx_rsegs_t rsegs
Definition: trx0trx.h:1020
bool is_registered
Definition: trx0trx.h:875
trx_t()=default
Default constructor.
uint64_t mysql_log_offset
if MySQL binlog is used, this field contains the end offset of the binlog entry
Definition: trx0trx.h:948
const char * start_file
Filename where it was started.
Definition: trx0trx.h:1067
lsn_t commit_lsn
lsn at the time of the commit
Definition: trx0trx.h:935
bool check_unique_secondary
normally true, but if the user wants to speed up inserts by suppressing unique key checks for seconda...
Definition: trx0trx.h:881
isolation_level_t
Definition: trx0trx.h:684
@ REPEATABLE_READ
this is the default; all consistent reads in the same trx read the same snapshot; full next-key locki...
Definition: trx0trx.h:702
@ READ_COMMITTED
somewhat Oracle-like isolation, except that in range UPDATE and DELETE we must block phantom rows wit...
Definition: trx0trx.h:697
@ SERIALIZABLE
all plain SELECTs are converted to LOCK IN SHARE MODE reads
Definition: trx0trx.h:706
@ READ_UNCOMMITTED
dirty read: non-locking SELECTs are performed so that we do not look at a possible earlier version of...
Definition: trx0trx.h:690
const dict_index_t * error_index
if the error number indicates a duplicate key error, a pointer to the problematic index is stored her...
Definition: trx0trx.h:982
trx_savept_t last_sql_stat_start
undo_no when the last sql statement was started: in case of an error, trx is rolled back down to this...
Definition: trx0trx.h:1015
bool is_read_uncommitted() const
Definition: trx0trx.h:1113
bool purge_sys_trx
This flag is set for trx_t objects used by the purge sys.
Definition: trx0trx.h:1100
trx_id_t id
transaction id
Definition: trx0trx.h:735
bool read_only
true if transaction is flagged as a READ-ONLY transaction.
Definition: trx0trx.h:1034
trx_savepoints
savepoints set with SAVEPOINT ..., oldest first
Definition: trx0trx.h:997
bool in_rw_trx_list
True iff in trx_sys->rw_trx_list.
Definition: trx0trx.h:963
bool api_trx
trx started by InnoDB API
Definition: trx0trx.h:1091
bool skip_gap_locks() const
Definition: trx0trx.h:1121
bool abort
if this flag is set then this transaction must abort when it can
Definition: trx0trx.h:731
bool in_truncate
Definition: trx0trx.h:913
bool declared_to_be_inside_innodb
this is true if we have declared this transaction in srv_conc_enter_innodb to be inside the InnoDB en...
Definition: trx0trx.h:916
std::atomic< std::thread::id > killed_by
The thread ID that wants to kill this transaction asynchronously.
Definition: trx0trx.h:845
bool check_foreigns
normally true, but if the user wants to suppress foreign key checks, (in table imports,...
Definition: trx0trx.h:866
bool persists_gtid
Transaction persists GTID.
Definition: trx0trx.h:1063
dberr_t error_state
DB_SUCCESS if no error, otherwise error number.
Definition: trx0trx.h:980
trx_list
list of transactions; protected by trx_sys->mutex.
Definition: trx0trx.h:821
trx_id_t no
transaction serialization number: max trx id shortly before the transaction is moved to COMMITTED_IN_...
Definition: trx0trx.h:737
ReadView * read_view
consistent read view used in the transaction, or NULL if not yet set
Definition: trx0trx.h:817
sess_t * sess
session of the trx, NULL if none
Definition: trx0trx.h:988
bool in_rollback
true when the transaction is executing a partial or full rollback
Definition: trx0trx.h:1024
bool read_write
if read and write operation
Definition: trx0trx.h:1093
UndoMutex undo_mutex
mutex protecting the fields in this section (down to undo_no_arr), EXCEPT last_sql_stat_start,...
Definition: trx0trx.h:999
bool has_search_latch
true if this trx has latched the search system latch in S-mode.
Definition: trx0trx.h:900
trx_lock_t lock
Information about the transaction locks and state.
Definition: trx0trx.h:830
trx_mod_tables_t mod_tables
List of tables that were modified by this transaction.
Definition: trx0trx.h:1087
bool ddl_operation
True if this trx involves dd table change.
Definition: trx0trx.h:909
ulint error_key_num
if the index creation fails to a duplicate key error, a mysql key number of that index is stored here
Definition: trx0trx.h:985
uint32_t mysql_n_tables_locked
how many tables the current SQL statement uses, except those in consistent read
Definition: trx0trx.h:956
mysql_trx_list
list of transactions created for MySQL; protected by trx_sys->mutex
Definition: trx0trx.h:967
The transaction handle.
Definition: trx0trx.h:643
bool is_update()
Definition: trx0trx.h:653
bool is_insert_only()
Definition: trx0trx.h:648
trx_undo_t * insert_undo
pointer to the insert undo log, or NULL if no inserts performed yet
Definition: trx0trx.h:658
trx_undo_t * update_undo
pointer to the update undo log, or NULL if no update performed yet
Definition: trx0trx.h:660
trx_rseg_t * rseg
rollback segment assigned to the transaction, or NULL if not assigned yet
Definition: trx0trx.h:655
bool is_empty()
Definition: trx0trx.h:645
Transaction undo log memory object; this is protected by the undo_mutex in the corresponding transact...
Definition: trx0undo.h:338
Definition: ut0core.h:35
const char * filename
Definition: ut0core.h:36
size_t line
Definition: ut0core.h:37
struct xid_t is binary compatible with the XID structure as in the X/Open CAE Specification,...
Definition: xa.h:82
double seconds()
Definition: task.cc:309
static uint64_t trx_immutable_id(const trx_t *trx)
Provides an id of the transaction which does not change over time.
Definition: trx0trx.h:375
void trx_start_if_not_started_low(trx_t *trx, bool read_write)
Starts the transaction if it is not yet started.
Definition: trx0trx.cc:3373
bool trx_assert_started(const trx_t *trx)
Asserts that a transaction has been started.
Definition: trx0trx.cc:2709
static ReadView * trx_get_read_view(trx_t *trx)
void trx_set_flush_observer(trx_t *trx, Flush_observer *observer)
Set flush observer for the transaction.
Definition: trx0trx.cc:131
sess_t * trx_dummy_sess
Dummy session used currently in MySQL interface.
Definition: trx0trx.cc:93
bool trx_is_interrupted(const trx_t *trx)
Determines if the currently running transaction has been interrupted.
Definition: ha_innodb.cc:3157
static void assert_trx_is_inactive(const trx_t *t)
Check if transaction is in-active so that it can be freed and put back to transaction pool.
Definition: trx0trx.h:1202
bool trx_is_started(const trx_t *trx)
Check if transaction is started.
Definition: trx0trx.h:1331
static void trx_start_internal(trx_t *t, ut::Location loc)
Definition: trx0trx.h:1278
bool trx_was_started(const trx_t *trx)
Check if transaction was started.
Definition: trx0trx.h:1321
void trx_free_prepared_or_active_recovered(trx_t *trx)
At shutdown, frees a transaction object that represents either:
Definition: trx0trx.cc:592
void trx_free_for_background(trx_t *trx)
Free a transaction that was allocated by background or user threads.
Definition: trx0trx.cc:586
trx_t * trx_allocate_for_background(void)
Creates a transaction object for background operations by the master thread.
Definition: trx0trx.cc:515
que_thr_t * trx_commit_step(que_thr_t *thr)
Performs an execution step for a commit type node in a query graph.
Definition: trx0trx.cc:2388
static bool trx_is_high_priority(const trx_t *trx)
void trx_before_mutex_exit(const trx_t *trx)
Verifies the invariants and records debug state related to latching rules.
Definition: trx0trx.cc:2892
std::set< dict_table_t *, std::less< dict_table_t * >, ut::allocator< dict_table_t * > > trx_mod_tables_t
Type used to store the list of tables that are modified by a given transaction.
Definition: trx0trx.h:594
void trx_pool_init()
Create the trx_t pool.
Definition: trx0trx.cc:424
void trx_free_for_mysql(trx_t *trx)
Free a transaction object for MySQL.
Definition: trx0trx.cc:678
static bool trx_is_ac_nl_ro(const trx_t *t)
Determine if the transaction is a non-locking autocommit select with an explicit check for the read-o...
Definition: trx0trx.h:1236
void trx_kill_blocking(trx_t *trx)
If this is a high priority transaction, kill all transactions that are blocking this transaction from...
Definition: trx0trx.cc:3472
static void trx_start_if_not_started_xa(trx_t *t, bool rw, ut::Location loc)
Definition: trx0trx.h:1265
void trx_disconnect_plain(trx_t *trx)
Disconnect a transaction from MySQL.
Definition: trx0trx.cc:666
bool trx_weight_ge(const trx_t *a, const trx_t *b)
Compares the "weight" (or size) of two transactions.
Definition: trx0trx.cc:2906
static enum trx_dict_op_t trx_get_dict_operation(const trx_t *trx)
Determine if a transaction is a dictionary operation.
void trx_resurrect_locks(bool all)
Resurrect table locks for resurrected transactions.
Definition: trx0trx.cc:765
void trx_free_resurrected(trx_t *trx)
Free and initialize a transaction object instantiated during recovery.
Definition: trx0trx.cc:576
void trx_clear_resurrected_table_ids()
Clear all resurrected table IDs.
Definition: trx0trx.cc:821
void trx_print_latched(FILE *f, const trx_t *trx, ulint max_query_len)
Prints info about a transaction.
Definition: trx0trx.cc:2669
void trx_sys_update_binlog_position(trx_t *trx)
Update transaction binlog file name and position from session THD.
Definition: trx0trx.cc:3631
static void check_trx_state(const trx_t *t)
Check transaction state.
Definition: trx0trx.h:1164
int trx_recover_tc_for_mysql(Xa_state_list &xa_list)
Find prepared transactions that are marked as prepared in TC, for recovery purposes.
Definition: trx0trx.cc:3259
static void trx_start_if_not_started(trx_t *t, bool rw, ut::Location l)
Definition: trx0trx.h:1272
void trx_mark_sql_stat_end(trx_t *trx)
Marks the latest SQL statement ended.
Definition: trx0trx.cc:2507
void trx_commit(trx_t *trx)
Commits a transaction.
Definition: trx0trx.cc:2248
std::vector< std::pair< trx_id_t, table_id_t > > to_rollback_trx_tables
Definition: trx0trx.cc:90
void trx_before_mutex_enter(const trx_t *trx, bool allow_another)
Verifies the invariants and records debug state related to latching rules.
Definition: trx0trx.cc:2865
static uint64_t TRX_WEIGHT(const trx_t *t)
Calculates the "weight" of a transaction.
Definition: trx0trx.h:1260
void trx_set_rw_mode(trx_t *trx)
Set the transaction as a read-write transaction if it is not already tagged as such.
Definition: trx0trx.cc:3429
std::vector< ib_lock_t *, ut::allocator< ib_lock_t * > > lock_pool_t
Definition: trx0trx.h:385
static void trx_reference(trx_t *trx)
Increase the reference count.
static bool trx_is_referenced(const trx_t *t)
Check if the transaction is being referenced.
Definition: trx0trx.h:1254
bool trx_can_be_handled_by_current_thread_or_is_hp_victim(const trx_t *trx)
Determines if trx can be handled by current thread, which is when trx->mysql_thd is nullptr (a "backg...
Definition: trx0trx.cc:2701
ReadView * trx_assign_read_view(trx_t *trx)
Assigns a read view for a consistent read query.
Definition: trx0trx.cc:2310
void trx_assign_rseg_temp(trx_t *trx)
Assign a temp-tablespace bound rollback-segment to a transaction.
Definition: trx0trx.cc:1274
void trx_set_detailed_error_from_file(trx_t *trx, FILE *file)
Set detailed error message for the transaction from a file.
Definition: trx0trx.cc:144
commit_node_t * trx_commit_node_create(mem_heap_t *heap)
Creates a commit command node struct.
Definition: trx0trx.cc:2374
bool trx_can_be_handled_by_current_thread(const trx_t *trx)
Determines if trx can be handled by current thread, which is when trx->mysql_thd is nullptr (a "backg...
Definition: trx0trx.cc:2689
static const char * trx_get_que_state_str(const trx_t *trx)
Retrieves transaction's que state in a human readable string.
bool trx_is_prepared_in_tc(trx_t const *trx)
Checks whether or not the transaction has been marked as prepared in TC.
Definition: trx0trx.cc:3645
static bool trx_state_eq(const trx_t *trx, trx_state_t state)
Determines if a transaction is in the given state.
#define trx_mutex_exit(t)
Release the trx->mutex.
Definition: trx0trx.h:1396
void trx_start_internal_read_only_low(trx_t *trx)
Starts a read-only transaction for internal processing.
Definition: trx0trx.cc:3412
static trx_id_t trx_get_id_for_print(const trx_t *trx)
Retreieves the transaction ID.
constexpr uint32_t TRX_QUE_STATE_STR_MAX_LEN
Definition: trx0trx.h:317
static void trx_set_dict_operation(trx_t *trx, enum trx_dict_op_t op)
Flag a transaction a dictionary operation.
void trx_commit_low(trx_t *trx, mtr_t *mtr)
Commits a transaction and a mini-transaction.
Definition: trx0trx.cc:2156
static void trx_release_reference(trx_t *trx)
Release the transaction.
bool trx_is_mysql_xa(const trx_t *trx)
Check if transaction is internal XA transaction.
Definition: trx0trx.cc:2989
static bool trx_is_rseg_updated(const trx_t *trx)
Check if redo/noredo rseg is modified for insert/update.
static const dict_index_t * trx_get_error_index(const trx_t *trx)
Retrieves the error_info field from a trx.
int trx_recover_for_mysql(XA_recover_txn *txn_list, ulint len, MEM_ROOT *mem_root)
This function is used to find number of prepared transactions and their transaction objects for a rec...
Definition: trx0trx.cc:3203
trx_t * trx_get_trx_by_xid(const XID *xid)
This function is used to find one X/Open XA distributed transaction which is in the prepared state.
Definition: trx0trx.cc:3320
#define trx_mutex_enter(t)
Acquire the trx->mutex (and promise not to request any more).
Definition: trx0trx.h:1390
static bool trx_is_autocommit_non_locking(const trx_t *t)
Determine if the transaction is a non-locking autocommit select (implied read-only).
Definition: trx0trx.h:1159
void trx_pool_close()
Destroy the trx_t pool.
Definition: trx0trx.cc:432
static const trx_t * trx_arbitrate(const trx_t *requestor, const trx_t *holder)
bool trx_is_strict(trx_t *trx)
Determines if the currently running transaction is in strict mode.
Definition: ha_innodb.cc:3164
void trx_print(FILE *f, const trx_t *trx, ulint max_query_len)
Prints info about a transaction.
Definition: trx0trx.cc:2680
static void assert_trx_in_rw_list(const trx_t *t)
Assert that the transaction is in the trx_sys_t::rw_trx_list.
Definition: trx0trx.h:1181
void trx_start_internal_low(trx_t *trx)
Starts a transaction for internal processing.
Definition: trx0trx.cc:3398
dberr_t trx_set_prepared_in_tc_for_mysql(trx_t *trx)
Does the 2nd phase of an XA transaction prepare for MySQL.
Definition: trx0trx.cc:3660
trx_t * trx_allocate_for_mysql(void)
Creates a transaction object for MySQL.
Definition: trx0trx.cc:527
void trx_lists_init_at_db_start(void)
Creates trx objects for transactions and initializes the trx list of trx_sys at database start.
Definition: trx0trx.cc:1076
void trx_commit_complete_for_mysql(trx_t *trx)
If required, flushes the log to disk if we called trx_commit_for_mysql() with trx->flush_log_later ==...
Definition: trx0trx.cc:2489
trx_rseg_type_t
Definition: trx0trx.h:677
@ TRX_RSEG_TYPE_NONE
void rollback segment type.
Definition: trx0trx.h:678
@ TRX_RSEG_TYPE_NOREDO
non-redo rollback segment.
Definition: trx0trx.h:680
@ TRX_RSEG_TYPE_REDO
redo rollback segment.
Definition: trx0trx.h:679
void trx_disconnect_prepared(trx_t *trx)
Disconnect a prepared transaction from MySQL.
Definition: trx0trx.cc:672
static void assert_trx_nonlocking_or_in_list(const trx_t *t)
Assert that an autocommit non-locking select cannot be in the rw_trx_list and that it is a read-only ...
Definition: trx0trx.h:1211
static void assert_trx_is_free(const trx_t *t)
Check if transaction is free so that it can be re-initialized.
Definition: trx0trx.h:1189
commit_node_state
Commit node states.
Definition: trx0trx.h:1337
@ COMMIT_NODE_SEND
about to send a commit signal to the transaction
Definition: trx0trx.h:1338
@ COMMIT_NODE_WAIT
commit signal sent to the transaction, waiting for completion
Definition: trx0trx.h:1340
void trx_commit_or_rollback_prepare(trx_t *trx)
Prepares a transaction for commit/rollback.
Definition: trx0trx.cc:2327
static void trx_start_internal_read_only(trx_t *t, ut::Location loc)
Definition: trx0trx.h:1284
static std::chrono::seconds trx_lock_wait_timeout_get(const trx_t *t)
Transactions that aren't started by the MySQL server don't set the trx_t::mysql_thd field.
Definition: trx0trx.h:1150
void trx_set_detailed_error(trx_t *trx, const char *msg)
Set detailed error message for the transaction.
Definition: trx0trx.cc:138
void trx_cleanup_at_db_startup(trx_t *trx)
Cleans up a transaction at database startup.
Definition: trx0trx.cc:2273
dberr_t trx_commit_for_mysql(trx_t *trx)
Does the transaction commit for MySQL.
Definition: trx0trx.cc:2434
dberr_t trx_prepare_for_mysql(trx_t *trx)
Does the transaction prepare for MySQL.
Definition: trx0trx.cc:3125
void trx_print_low(FILE *f, const trx_t *trx, ulint max_query_len, ulint n_rec_locks, ulint n_trx_locks, ulint heap_size)
Prints info about a transaction.
Definition: trx0trx.cc:2539
bool trx_mutex_own(const trx_t *trx)
Test if trx->mutex is owned by the current thread.
Definition: trx0trx.h:1353
void trx_start_if_not_started_xa_low(trx_t *trx, bool read_write)
Starts the transaction if it is not yet started.
Definition: trx0trx.cc:3341
The transaction.
Transaction system global type definitions.
static const uint32_t TRX_FORCE_ROLLBACK_MASK
For masking out the above four flags.
Definition: trx0types.h:67
ib_mutex_t TrxMutex
Definition: trx0types.h:170
trx_state_t
Transaction states (trx_t::state)
Definition: trx0types.h:79
@ TRX_STATE_FORCED_ROLLBACK
Same as not started but with additional semantics that it was rolled back asynchronously the last tim...
Definition: trx0types.h:85
@ TRX_STATE_ACTIVE
Definition: trx0types.h:87
@ TRX_STATE_COMMITTED_IN_MEMORY
Definition: trx0types.h:92
@ TRX_STATE_NOT_STARTED
Definition: trx0types.h:81
@ TRX_STATE_PREPARED
Support for 2PC/XA.
Definition: trx0types.h:90
trx_que_t
Transaction execution states when trx->state == TRX_STATE_ACTIVE.
Definition: trx0types.h:70
ib_id_t undo_no_t
Undo number.
Definition: trx0types.h:141
static const uint32_t TRX_FORCE_ROLLBACK
Mark the transaction for forced rollback.
Definition: trx0types.h:64
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:137
static const uint32_t TRX_FORCE_ROLLBACK_DISABLE
If this flag is set then the transaction cannot be rolled back asynchronously.
Definition: trx0types.h:61
ib_mutex_t UndoMutex
Definition: trx0types.h:171
trx_dict_op_t
Type of data dictionary operation.
Definition: trx0types.h:96
@ TRX_DICT_OP_NONE
The transaction is not modifying the data dictionary.
Definition: trx0types.h:98
unsigned long int ulint
Definition: univ.i:405
long int lint
Definition: univ.i:406
Users and sessions global types.
#define ut_error
Abort execution.
Definition: ut0dbg.h:100
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:104
#define ut_o(EXPR)
Opposite of ut_d().
Definition: ut0dbg.h:108
#define ut_d(EXPR)
Debug statement.
Definition: ut0dbg.h:106
#define UT_LIST_GET_LEN(BASE)
Alternative macro to get the number of nodes in a two-way list, i.e., its length.
Definition: ut0lst.h:440
#define UT_LIST_BASE_NODE_T_EXTERN(t, m)
A variant of UT_LIST_BASE_NODE_T to be used in rare cases where the full definition of t is not yet i...
Definition: ut0lst.h:278
#define UT_LIST_NODE_T(t)
Macro used for legacy reasons.
Definition: ut0lst.h:63
#define mutex_own(M)
Checks that the current thread owns the mutex.
Definition: ut0mutex.h:164
Dynamic memory allocation routines and custom allocators specifically crafted to support memory instr...
A vector of pointers to data items.
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:509
static int all(site_def const *s, node_no node)
Definition: xcom_transport.cc:881