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