MySQL 9.4.0
Source Code Documentation
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
trx0sys.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1996, 2025, 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 designed to work with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation. The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26*****************************************************************************/
27
28/** @file include/trx0sys.h
29 Transaction system
30
31 Created 3/26/1996 Heikki Tuuri
32 *******************************************************/
33
34#ifndef trx0sys_h
35#define trx0sys_h
36
37#include "univ.i"
38
39#include "buf0buf.h"
40#include "fil0fil.h"
41#include "trx0types.h"
42#ifndef UNIV_HOTBACKUP
43#include "mem0mem.h"
44#include "mtr0mtr.h"
45#include "page0types.h"
46#include "ut0byte.h"
47#include "ut0class_life_cycle.h"
48#include "ut0guarded.h"
49#include "ut0lst.h"
50#include "ut0mutex.h"
51#endif /* !UNIV_HOTBACKUP */
52#include <atomic>
53#include <unordered_map>
54#include <vector>
55#include "trx0trx.h"
56
57#ifndef UNIV_HOTBACKUP
58
59// Forward declaration
60class MVCC;
61class ReadView;
62
63/** The transaction system */
64extern trx_sys_t *trx_sys;
65
66/** Checks if a page address is the trx sys header page.
67@param[in] page_id page id
68@return true if trx sys header page */
69static inline bool trx_sys_hdr_page(const page_id_t &page_id);
70
71/** Creates and initializes the central memory structures for the transaction
72system. This is called when the database is started.
73@return min binary heap of rsegs to purge */
75
76/** Creates the trx_sys instance and initializes purge_queue and mutex. */
77void trx_sys_create(void);
78
79/** Creates and initializes the transaction system at the database creation. */
81
82/** Look for a free slot for a rollback segment in the trx system file copy.
83@param[in,out] mtr mtr
84@return slot index or ULINT_UNDEFINED if not found */
86
87/** Gets a pointer to the transaction system file copy and x-locks its page.
88 @return pointer to system file copy, page x-locked */
89static inline trx_sysf_t *trx_sysf_get(mtr_t *mtr); /*!< in: mtr */
90
91/** Gets the page number of the nth rollback segment slot in the trx system
92file copy.
93@param[in] sys_header trx sys file copy
94@param[in] i slot index == rseg id
95@param[in] mtr mtr
96@return page number, FIL_NULL if slot unused */
98 ulint i, mtr_t *mtr);
99
100/** Sets the space id of the nth rollback segment slot in the trx system
101file copy.
102@param[in] sys_header trx sys file copy
103@param[in] i slot index == rseg id
104@param[in] space space id
105@param[in] mtr mtr */
106static inline void trx_sysf_rseg_set_space(trx_sysf_t *sys_header, ulint i,
107 space_id_t space, mtr_t *mtr);
108
109/** Set the page number of the nth rollback segment slot in the trx system
110file copy.
111@param[in] sys_header trx sys file copy
112@param[in] i slot index == rseg id
113@param[in] page_no page number, FIL_NULL if the slot is reset to
114 unused
115@param[in] mtr mtr */
116static inline void trx_sysf_rseg_set_page_no(trx_sysf_t *sys_header, ulint i,
117 page_no_t page_no, mtr_t *mtr);
118
119/** Allocates a new transaction id (for trx->id). Before calling,
120the trx_sys_mutex must be acquired.
121@return new, allocated trx id */
123
124/** Allocates a new transaction number (for trx->no). Before calling,
125the trx_sys_serialisation_mutex must be acquired.
126@return new, allocated trx no */
128
129/** Retrieves a next value that will be allocated if trx_sys_allocate_trx_id()
130or trx_sys_allocate_trx_id_trx_no() was called.
131@return the next trx->id or trx->no that will be allocated */
133
134#ifdef UNIV_DEBUG
135/* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */
136extern uint trx_rseg_n_slots_debug;
137#endif
138#endif /* !UNIV_HOTBACKUP */
139
140/** Writes a trx id to an index page. In case that the id size changes in some
141future version, this function should be used instead of mach_write_...
142@param[in] ptr pointer to memory where written
143@param[in] id id */
144static inline void trx_write_trx_id(byte *ptr, trx_id_t id);
145
146#ifndef UNIV_HOTBACKUP
147/** Reads a trx id from an index page. In case that the id size changes in
148 some future version, this function should be used instead of
149 mach_read_...
150 @return id */
152 const byte *ptr); /*!< in: pointer to memory from where to read */
153
154/** Checks if a rw transaction with the given id is active.
155Please note, that positive result means only that the trx was active
156at some moment during the call, but it might have already become
157TRX_STATE_COMMITTED_IN_MEMORY before the call returns to the caller, as this
158transition is protected by trx->mutex and Trx_shard's mutex, but it is
159impossible for the caller to hold any of these mutexes when calling this
160function as the function itself internally acquires Trx_shard's mutex which
161would cause recurrent mutex acquisition if caller already had the same mutex,
162or latching order violation in case of holding trx->mutex.
163@param[in] trx_id trx id of the transaction
164@param[in] do_ref_count if true then increment the trx_t::n_ref_count
165@return transaction instance if active, or NULL; */
166static inline trx_t *trx_rw_is_active(trx_id_t trx_id, bool do_ref_count);
167
168/** Persist transaction number limit below which all transaction GTIDs
169are persisted to disk table.
170@param[in] gtid_trx_no transaction number */
171void trx_sys_persist_gtid_num(trx_id_t gtid_trx_no);
172
173/** @return oldest transaction number yet to be committed. */
175
176/** Get a list of all binlog prepared transactions.
177@param[out] trx_ids all prepared transaction IDs. */
178void trx_sys_get_binlog_prepared(std::vector<trx_id_t> &trx_ids);
179
180/** Get current binary log positions stored.
181@param[out] file binary log file name
182@param[out] offset binary log file offset */
183void trx_sys_read_binlog_position(char *file, uint64_t &offset);
184
185/** Update binary log position if not already updated. This is called
186by clone to update any stale binary log position if any transaction
187is yet to update the binary log position in SE.
188@param[in] last_file last noted binary log file name
189@param[in] last_offset last noted binary log offset
190@param[in] file current binary log file name
191@param[in] offset current binary log file offset
192@return true, if binary log position is updated with current. */
193bool trx_sys_write_binlog_position(const char *last_file, uint64_t last_offset,
194 const char *file, uint64_t offset);
195
196/** Updates the offset information about the end of the MySQL binlog entry
197which corresponds to the transaction being committed, external XA transaction
198being prepared or rolled back. In a MySQL replication slave updates the latest
199master binlog position up to which replication has proceeded.
200@param[in] trx Current transaction
201@param[in,out] mtr Mini-transaction for update */
203
204/** Shutdown/Close the transaction system. */
205void trx_sys_close(void);
206
207/** Determine if there are incomplete transactions in the system.
208@return whether incomplete transactions need rollback */
209static inline bool trx_sys_need_rollback();
210
211/** Reads number of recovered transactions which have state
212equal to TRX_STATE_ACTIVE (so are not prepared transactions).
213@return number of active recovered transactions */
215
216/** Validates lists of transactions at the very beginning of the
217pre-dd-shutdown phase. */
219
220/** Validates lists of transactions at the very end of the
221pre-dd-shutdown phase. */
223
224/** Validates lists of transactions after all background threads
225of InnoDB exited during shutdown of MySQL. */
227
228/** Add the transaction to the RW transaction set.
229@param trx transaction instance to add */
230static inline void trx_sys_rw_trx_add(trx_t *trx);
231
232#endif /* !UNIV_HOTBACKUP */
233
234#ifdef UNIV_DEBUG
235/** Validate the trx_sys_t::rw_trx_list.
236 @return true if the list is valid */
238#endif /* UNIV_DEBUG */
239
240/** The automatically created system rollback segment has this id */
241constexpr uint32_t TRX_SYS_SYSTEM_RSEG_ID = 0;
242
243/** The offset of the transaction system header on the page */
244constexpr uint32_t TRX_SYS = FSEG_PAGE_DATA;
245
246/** Transaction system header */
247/*------------------------------------------------------------- @{ */
248/** the maximum trx id or trx number modulo TRX_SYS_TRX_ID_UPDATE_MARGIN written
249 to a file page by any transaction; the assignment of transaction ids
250 continues from this number rounded up by TRX_SYS_TRX_ID_UPDATE_MARGIN plus
251 TRX_SYS_TRX_ID_UPDATE_MARGIN when the database is started */
252constexpr uint32_t TRX_SYS_TRX_ID_STORE = 0;
253/** segment header for the tablespace segment the trx system is created into */
254constexpr uint32_t TRX_SYS_FSEG_HEADER = 8;
255/** the start of the array of rollback segment specification slots */
256constexpr uint32_t TRX_SYS_RSEGS = 8 + FSEG_HEADER_SIZE;
257/*------------------------------------------------------------- @} */
258
259/** Maximum length of MySQL binlog file name, in bytes. */
260constexpr uint32_t TRX_SYS_MYSQL_LOG_NAME_LEN = 512;
261/** Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD */
262constexpr uint32_t TRX_SYS_MYSQL_LOG_MAGIC_N = 873422344;
263
264static_assert(UNIV_PAGE_SIZE_MIN >= 4096, "UNIV_PAGE_SIZE_MIN < 4096");
265/** The offset of the MySQL binlog offset info in the trx system header */
266#define TRX_SYS_MYSQL_LOG_INFO (UNIV_PAGE_SIZE - 1000)
267/** magic number which is TRX_SYS_MYSQL_LOG_MAGIC_N if we have valid data in the
268 MySQL binlog info */
269constexpr uint32_t TRX_SYS_MYSQL_LOG_MAGIC_N_FLD = 0;
270/** high 4 bytes of the offset within that file */
271constexpr uint32_t TRX_SYS_MYSQL_LOG_OFFSET_HIGH = 4;
272/** low 4 bytes of the offset within that file */
273constexpr uint32_t TRX_SYS_MYSQL_LOG_OFFSET_LOW = 8;
274/** MySQL log file name */
275constexpr uint32_t TRX_SYS_MYSQL_LOG_NAME = 12;
276
277/** Reserve next 8 bytes for transaction number up to which GTIDs
278are persisted to table */
279#define TRX_SYS_TRX_NUM_GTID \
280 (TRX_SYS_MYSQL_LOG_INFO + TRX_SYS_MYSQL_LOG_NAME + TRX_SYS_MYSQL_LOG_NAME_LEN)
281#define TRX_SYS_TRX_NUM_END (TRX_SYS_TRX_NUM_GTID + 8)
282/** Doublewrite buffer */
283/** @{ */
284/** The offset of the doublewrite buffer header on the trx system header page */
285#define TRX_SYS_DOUBLEWRITE (UNIV_PAGE_SIZE - 200)
286/*-------------------------------------------------------------*/
287/** fseg header of the fseg containing the doublewrite buffer */
288constexpr uint32_t TRX_SYS_DOUBLEWRITE_FSEG = 0;
289/** 4-byte magic number which shows if we already have created the doublewrite
290 buffer */
292/** page number of the first page in the first sequence of 64 (=
293 FSP_EXTENT_SIZE) consecutive pages in the doublewrite buffer */
295/** page number of the first page in the second sequence of 64 consecutive pages
296 in the doublewrite buffer */
298/** we repeat TRX_SYS_DOUBLEWRITE_MAGIC, TRX_SYS_DOUBLEWRITE_BLOCK1,
299 TRX_SYS_DOUBLEWRITE_BLOCK2 so that if the trx sys header is half-written to
300 disk, we still may be able to recover the information */
301constexpr uint32_t TRX_SYS_DOUBLEWRITE_REPEAT = 12;
302/** If this is not yet set to TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N,
303we must reset the doublewrite buffer, because starting from 4.1.x the
304space id of a data page is stored into
305FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID. */
307
308/*-------------------------------------------------------------*/
309/** Contents of TRX_SYS_DOUBLEWRITE_MAGIC */
310constexpr uint32_t TRX_SYS_DOUBLEWRITE_MAGIC_N = 536853855;
311/** Contents of TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED */
312constexpr uint32_t TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N = 1783657386;
313
314/** Size of the doublewrite block in pages */
315#define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE
316/** @} */
317
318/** List of undo tablespace IDs. */
319class Space_Ids : public std::vector<space_id_t, ut::allocator<space_id_t>> {
320 public:
321 void sort() { std::sort(begin(), end()); }
322
324 if (size() == 0) {
325 return (false);
326 }
327
328 iterator it = std::find(begin(), end(), id);
329
330 return (it != end());
331 }
332
333 iterator find(space_id_t id) { return (std::find(begin(), end(), id)); }
334};
335
336/** Number of shards created for transactions. */
337constexpr size_t TRX_SHARDS_N = 256;
338
339/** Computes shard number for a given trx_id.
340@param[in] trx_id trx_id for which shard_no should be computed
341@return the computed shard number (number in range 0..TRX_SHARDS_N-1) */
342inline size_t trx_get_shard_no(trx_id_t trx_id) {
343 ut_ad(trx_id != 0);
344 return trx_id % TRX_SHARDS_N;
345}
346
347#ifndef UNIV_HOTBACKUP
350 size_t operator()(const trx_id_t &key) const {
351 return static_cast<size_t>(key / TRX_SHARDS_N);
352 }
353 };
354
355 using By_id = std::unordered_map<trx_id_t, trx_t *, Trx_track_hash>;
357
358 /** For observers which use Trx_shard::mutex protection: each transaction id
359 in the m_by_id is guaranteed to be at least m_min_id.
360 Writes are protected with Trx_shard::mutex.
361 Reads can be performed without any latch before accessing m_by_id,
362 but care must be taken to interpret the result -
363 @see trx_rw_is_active for details.*/
364 std::atomic<trx_id_t> m_min_id{TRX_ID_MAX};
365
366 /** A "lower bound" is a value which is guaranteed to be smaller or equal than
367 any id in any of the shards of transactions which finished calling insert(id)
368 and have not yet started a call to erase(id).
369 I.e. a shard can already contain an id smaller than this value, if insert(id)
370 has still not finished. This is sufficient guarantee, if you only care about
371 "active" transactions in the sense that insert(id) for them has happened
372 before the call and erase(id) hasn't started. For example, when you want to
373 check if a record you look at could have been modified by any of active
374 transactions, then this is a valid assumption as creating a record happens
375 after insert(id).
376
377 Each of the two values in this array may be used as a lower bound if its
378 highest bit (UPDATING_LOWER_BOUND) is not set. At most one of them has the
379 highest bit set at any given time. If both of them can be used as a lower
380 bound, it follows, that you can use maximum of the two, as the best lower
381 bound estimate. Note that this value may be way lower than actual minimum, as
382 it is only updated from time to time by
383 get_better_lower_bound_for_already_active_id(). The highest bit being set for
384 a given entry means it is currently undergoing the process of updating and its
385 value should not be used until its finished.
386
387 Transactions performing insert(id) should ensure that for each i=0,1:
388 (s_lower_bound[i]&~UPDATING_LOWER_BOUND) <= id
389
390 The property we wish to prove is:
391
392 Claim 1: The value returned by get_cheap_lower_bound_for_already_active_id()
393 is lower or equal to any trx_id for which return from insert(trx->id) has
394 happened-before the call to get_cheap_lower_bound_for_already_active_id()
395 has started and a call to erase(trx->id) (if any at all) will happened-after
396 the return from get_cheap_lower_bound_for_already_active_id().
397
398 Note how weak this property is: it's the burden of the person who wants to
399 use this Claim 1 for anything, to first establish the happens-before relations
400 by other means, and only then the Claim 1 can do any useful work at all. The
401 reason we need only such a weak claim, is because in practice we use
402 get_cheap_lower_bound_for_already_active_id() only when already having in our
403 hands a record which is a proof of activity of some transaction which must
404 have happened after it has already called insert(trx->id) successfully - this
405 establishes the needed happens-before relation: insert(trx->id) happens
406 before a write of the record, which happens-before our read, which happens
407 before the call to get_cheap_lower_bound_for_already_active_id(). As for the
408 quite strong requirement for erase() to happen-after, it is justified, because
409 it is fine for get_cheap_lower_bound_for_already_active_id() to ignore a trx
410 which is "in the middle" of erase(trx->id), as it means the trx is already
411 committing, and the call to erase() happens under shard mutex and after the
412 state was already changed to TRX_STATE_COMMITTED_IN_MEMORY under trx->mutex,
413 so whoever else is interested in the question "is trx active?" and asks it
414 under shard mutex or trx->mutex will arrive at "no", so if we answer "no" as
415 well, there's no discrepancy, and if we answer "yes", then we err on the safe
416 side which is fine as well, as the caller will then double check.
417 Hence we don't care about cases where erase(trx->id) has already started.
418
419 The proof of Claim 1, depends on a simpler claim:
420
421 Claim 2: for any moment which happens-after insert(trx_id) and happens-before
422 erase(trx_id), the value of s_lower_bound[i] (for each i) either has the
423 UPDATING_LOWER_BOUND flag or is lower-or-equal to trx_id.
424
425 Claim 2 implies Claim 1, because get_cheap_lower_bound_for_already_active_id()
426 returns a value which it loaded from s_lower_bound[i] and had no
427 UPDATING_LOWER_BOUND flag.
428
429 In what follows, it is important that all atomic operations (load, store,
430 compare_exchange_weak, fetch_xor) use memory_order::seq_cst ordering, so there
431 is a single order S in which all of them happen, which is consistent with the
432 happens-before relation (established in the Claim's assumptions, and by
433 shard's mutex).
434
435 The proof of Claim 2 is constructive. For each trx shard separately, we use
436 induction over the trx_id-s in the order they are insert()ed to the shard
437 (which happen under shard.active_rw_trxs.mutex, so are ordered by
438 happens-before, too).
439
440 The thread which does insert(trx_id) experiences following events in following
441 order:
442 1. shard.m_min_id.load()
443 Case A) saw shard.m_min_id <= trx_id and did nothing
444 Case B) saw shard.m_min_id > trx_id and did:
445 2. stored shard.m_min_id = trx_id
446 3. saw that s_lower_bound[i] <= trx_id holds already, OR enforced this
447 inequality by itself by modifying s_lower_bound[i] with CAS
448
449 As all operations on shard.m_min_id and s_lower_bound[i] are ordered in S, it
450 is meaningful to look at the sorted list of all the operations from "2.", to
451 the moment get_cheap_lower_bound_for_already_active_id() load()s the value
452 from it. There are only few ways in which s_lower_bound[i] can be modified:
453
454 a) calls to limit_to(s_lower_bound[i], x) from insert(x) or
455 get_better_lower_bound_for_already_active_id(). They can only make the
456 value smaller than it was
457
458 b) s_lower_bound[index_to_update].store(min_seen |UPDATING_LOWER_BOUND)
459 in get_better_lower_bound_for_already_active_id() which can make it
460 (let's say: arbitrarily) larger, but also sets the flag
461
462 c) s_lower_bound[index_to_update].fetch_xor(UPDATING_LOWER_BOUND) which
463 clears the flag, but doesn't change the lower 63 bits
464
465 So, we have a sequence of operations of these three types. Also (b)s which
466 sets the flag and (c)s which clear it, appear in alternating fashion, so
467 that it is meaningful to talk about periods when the flag is present and
468 those where it is not present.
469
470 We will show that no mater which Case, A) or B) occured, Claim 2 will hold.
471
472 Case A) - the m_min_id was already small so we did nothing.
473
474 There are two interesting sub-cases to consider:
475
476 A.I) the "1." falls between (b) and (c), i.e. when the flag was present
477
478 Here, we need to distinguish two sub-sub-cases:
479
480 A.I.1) the "1." happens-before the second for() loop in
481 get_cheap_lower_bound_for_already_active_id() does
482 trx_sys->shards[i].active_rw_trxs.peek().min_id().
483
484 In this case, we are fine, because from moment "1." onwards it holds that
485 m_min_id <= trx_id, and thus it will be noticed, and taken into account
486 before (c) clears the flag. From then on, any later (a) can only make it
487 smaller, and future (b) will also happen after shard.m_min_id was already
488 as we need, so will take it into account.
489
490 A.I.2) the "1." happens-after the second for() loop loaded V from
491 shard.m_min_id.
492
493 If V <= trx_id, everything is fine, as the final value published by (c) will
494 be smaller or equal to trx_id.
495 If V > trx_id, and we've just seen at "1." that it was <= trx_id, it means it
496 somehow decreased between the load() done by the second for() loop, and load()
497 done in "1." in insert(trx_id) by us. The only places which decrease it, are
498 calls to insert(..), so it must be the case that another insert(trx_id') has
499 happened for trx_id'<=trx_id which decreased the m_min_id, and executed the
500 logic for limit_to(s_lower_bound[i],trx_id'), before finishing insert(trx_id')
501 which happened before moment "1.", which in turn happened before (c), which
502 means, that the lower 63 bits of s_lower_bound[i] are <= trx_id' <= trx_id
503 already at moment "1.", and thus the value revealed by (c) will be fine.
504
505 A.II) the "1." falls outside of any (b)--(c) window, i.e. when the flag was
506 missing
507
508 This is easy case, as at "1." we saw m_min_id <= trx_id, which means (thanks
509 to shard's mutex) that insert(m_min_id) has happened-before "1." and
510 erase(m_min_id) has not yet happened, so we can use inductive assumption, to
511 show the s_shard_bound[i] had to be <= m_min_id at moment "1." as the flag
512 was not present, and thus it is also <= trx_id, and will stay like that
513 through all (a) operations, and any future (b) operation will happen after
514 we've already ensured shard's m_min_id <= trx_id, so will be noticed by scan
515 over shards, before doing (c) to clear the flag.
516
517
518 Case B) the m_min_id was too large, so we did "2." and "3."
519
520 There are two interesting sub-cases to consider:
521
522 B.I) the "3." falls between (b) and (c), i.e. when the flag was present
523
524 It means the lower 63 bits are already <= trx_id at moment "3.", and will
525 stay so until (c), which will only clear the flag. Operation (a) also can't
526 make it larger. So, it is only another (b) in future which could make it
527 larger, but that future (b) will happen after "2." which ensured shard's
528 m_min_id is <= trx_id, and any thread doing (b)--(c) end-to-end has to check
529 all the shards, to take them into account.
530
531 B.II) the "3." falls outside of any (b)--(c) window, i.e. when the flag was
532 missing
533
534 Here, similarly, at moment "3." the s_lower_bound[i] is <= trx_id, and
535 subsequent (a)s can't violate it. Also, if (b) sets the flag in future, then
536 it will only be cleared by (c) after scanning all shards, which will happen
537 after moment "2.", so will take the shard's m_min_id into account.
538
539 So, Claim 2 holds in all these cases.
540 */
541 static std::atomic<trx_id_t> s_lower_bound[2];
542 static constexpr trx_id_t UPDATING_LOWER_BOUND = trx_id_t{1} << 63;
543
544 /** This is used during get_better_lower_bound_for_already_active_id() to
545 announce that it is trying to establish new value for s_lower_bound.
546 This value is false if no such process is under way, and changed to true by
547 the only thread chosen to perform it, thus serves the purpose of "mutex".
548 The reason we don't use an std::mutex, is that we don't wish to wait, nor
549 spin, we just want to give up when somebody else already works on it. */
550 static std::atomic<bool> s_updating_lower_bound;
551 /** Performs an equivalent of if(upper_bound < a) a=upper_bound atomically,
552 ignoring, but preserving the UPDATING_LOWER_BOUND flag.
553 @param[in] a The atomic we want to limit to upper_bound
554 @param[in] upper_bound The upper_bound we want to impose on a */
555 static void limit_to(std::atomic<trx_id_t> &a, trx_id_t upper_bound) {
556 trx_id_t v = a.load();
557 while (
558 upper_bound < (v & ~UPDATING_LOWER_BOUND) &&
559 !a.compare_exchange_weak(v, upper_bound | (v & UPDATING_LOWER_BOUND))) {
560 }
561 }
562
563 public:
564 /** Returns a value which is lower or equal to id of any transaction
565 for which insert(id) happened before the call started, and erase(id)
566 has not happened before the start of the call. @see s_lower_bound
567 Note that this value never increases unless someone calls
568 @see get_better_lower_bound_for_already_active_id() */
570 trx_id_t best_bound = 0;
571 bool found = false;
572 /* The while loop handles a rare race condition where we observe
573 both entries as having UPDATING_LOWER_BOUND, because first one
574 was being updated then the later. */
575 while (!found) {
576 for (const auto &lower_bound : s_lower_bound) {
577 const auto val = lower_bound.load();
578 if (!(val & UPDATING_LOWER_BOUND)) {
579 found = true;
580 /* Any s_lower_bound which doesn't have the UPDATING_LOWER_BOUND flag
581 is correct, so we prefer to take the larger one. For an exhaustive
582 proof see s_lower_bound's doxygen. */
583 best_bound = std::max(best_bound, val);
584 }
585 }
586 }
587 return best_bound;
588 }
589 /** @see get_cheap_lower_bound_for_already_active_id() from which this
590 function differs by executing a tighter estimation. If it is indeed
591 better, then as a side effect it will bump the value of s_lower_bound
592 used by get_cheap_lower_bound_for_already_active_id()*/
594
595 By_id const &by_id() const { return m_by_id; }
596 trx_id_t min_id() const { return m_min_id.load(); }
597 trx_t *get(trx_id_t trx_id) const {
598 const auto it = m_by_id.find(trx_id);
599 trx_t *trx = it == m_by_id.end() ? nullptr : it->second;
600 /* We remove trx from active_rw_trxs and change state to
601 TRX_STATE_COMMITTED_IN_MEMORY in a same critical section protected by
602 Trx_shard's mutex, which we happen to hold here, so we expect the state
603 of trx to match its presence in that set */
604 ut_ad(trx == nullptr || !trx_state_eq(trx, TRX_STATE_COMMITTED_IN_MEMORY));
605 return trx;
606 }
607 void insert(trx_t &trx) {
608 const trx_id_t trx_id = trx.id;
609 ut_ad(0 == m_by_id.count(trx_id));
610 m_by_id.emplace(trx_id, &trx);
611 if (trx_id < m_min_id.load(std::memory_order_relaxed)) {
612 /* It matters that our m_min_id.store() is made visible before we load any
613 of the two s_lower_bound[i]!
614 If m_min_id.store() was using just memory_order_release, it could happen,
615 that s_lower_bound[i].load() will appear small, so we will not limit it,
616 but right after that another thread starts updating s_lower_bound[i], and
617 will not see our stored m_min_id, and thus will set s_lower_bound[i], to
618 too large value. */
619 m_min_id.store(trx_id);
620 /* Ensure that both s_lower_bound[i]&~UPDATING_LOWER_BOUND are <= trx_id,
621 preserving the UPDATING_LOWER_BOUND flag if present */
622 for (auto &lower_bound : s_lower_bound) {
623 limit_to(lower_bound, trx_id);
624 }
625 }
626 }
627 void erase(trx_id_t trx_id) {
628 ut_ad(1 == m_by_id.count(trx_id));
629 m_by_id.erase(trx_id);
630 if (m_min_id.load(std::memory_order_relaxed) == trx_id) {
631 if (m_by_id.empty()) {
632 /* Note that this value is not equal to shard id modulo TRX_SHARDS_N,
633 and that changing to TRX_ID_MAX back and forth means the m_min_id is
634 not monotone over time. None of this is really a requirement for the
635 solution to work correctly, and m_min_id was never guaranteed to be
636 monotone really, as ids passed to insert(id) are not monotone. */
637 m_min_id.store(TRX_ID_MAX, std::memory_order_release);
638 } else {
639 /* We want at most 1 release store, so we use a local variable for the
640 loop. The m_by_id isn't ordered, so we find the min value by iterating
641 over all possible values in this shard. We know we will find something
642 eventually, because the shard is not empty, and we start the loop from
643 its old minimum. The number of iterations in total life of the
644 application is in practice roughly equal to the number of transactions,
645 because we visit each candidate value at most once, usually. There's an
646 edge case though: the ids passed to insert(id) are not necessarily
647 monotonically increasing, as ids are assigned independently from
648 inserting them - even though the two operations are close to each other
649 in source, the operations from two threads can get interleaved in a way
650 which makes the new minimum smaller - this is not only rare, but also
651 the range of such disorder is rather short, thus this doesn't impact
652 performance as at most just a few candidate values are rechecked. */
653 trx_id_t new_min = trx_id + TRX_SHARDS_N;
654#ifdef UNIV_DEBUG
655 // These asserts ensure while loop terminates:
656 const trx_id_t some_id = m_by_id.begin()->first;
657 ut_a(new_min <= some_id);
658 ut_a((some_id - new_min) % TRX_SHARDS_N == 0);
659#endif /* UNIV_DEBUG */
660 while (m_by_id.count(new_min) == 0) {
661 new_min += TRX_SHARDS_N;
662 }
663 m_min_id.store(new_min, std::memory_order_release);
664 }
665 }
666 }
667};
668
669/** Shard for subset of transactions. */
670struct Trx_shard {
671 /** Mapping from trx->id to trx of active rw transactions.
672 The peek() interface can only be used safely for the min_id().
673 Use latch_and_execute() interface to access other members. */
676};
677
678/** The transaction system central memory data structure. */
679struct trx_sys_t {
680 /* Members protected by neither trx_sys_t::mutex nor serialisation_mutex. */
682
683 /** @{ */
684
685 /** Multi version concurrency control manager */
686
688
689 /** Vector of pointers to rollback segments within the temp tablespace;
690 This vector is created and destroyed in single-threaded mode so it is not
691 protected by any mutex because it is read-only during multi-threaded
692 operation. */
694
695 /** Length of the TRX_RSEG_HISTORY list (update undo logs for committed
696 transactions). */
697 std::atomic<uint64_t> rseg_history_len;
698
699 /** @} */
700
701 /* Members protected by either trx_sys_t::mutex or serialisation_mutex. */
703
704 /** @{ */
705
706 /** The smallest number not yet assigned as a transaction id
707 or transaction number. This is declared as atomic because it
708 can be accessed without holding any mutex during AC-NL-RO
709 view creation. When it is used for assignment of the trx->id,
710 it is synchronized by the trx_sys_t::mutex. When it is used
711 for assignment of the trx->no, it is synchronized by the
712 trx_sys_t::serialisation_mutex. Note: it might be in parallel
713 used for both trx->id and trx->no assignments (for different
714 trx_t objects). */
715 std::atomic<trx_id_t> next_trx_id_or_no;
716
717 /** @} */
718
719 /* Members protected by serialisation_mutex. */
721
722 /** @{ */
723
724 /** Mutex to protect serialisation_list. */
726
727 /** Tracks minimal transaction id which has received trx->no, but has
728 not yet finished commit for the mtr writing the trx commit. Protected
729 by the serialisation_mutex. Ordered on the trx->no field. */
730 UT_LIST_BASE_NODE_T(trx_t, no_list) serialisation_list;
731
732#ifdef UNIV_DEBUG
733 /** Max trx number of read-write transactions added for purge. */
735#endif /* UNIV_DEBUG */
736
738
739 /* The minimum trx->no inside the serialisation_list. Protected by
740 the serialisation_mutex. Might be read without the mutex. */
741 std::atomic<trx_id_t> serialisation_min_trx_no;
742
743 /** @} */
744
745 /* Members protected by the trx_sys_t::mutex. */
747
748 /** @{ */
749
750 /** Mutex protecting most fields in this structure (the default one). */
752
754
755 /** List of active and committed in memory read-write transactions, sorted
756 on trx id, biggest first. Recovered transactions are always on this list. */
757 UT_LIST_BASE_NODE_T(trx_t, trx_list) rw_trx_list;
758
760
761 /** List of transactions created for MySQL. All user transactions are
762 on mysql_trx_list. The rw_trx_list can contain system transactions and
763 recovered transactions that will not be in the mysql_trx_list.
764 Additionally, mysql_trx_list may contain transactions that have not yet
765 been started in InnoDB. */
766 UT_LIST_BASE_NODE_T(trx_t, mysql_trx_list) mysql_trx_list;
767
768 /** Array of Read write transaction IDs for MVCC snapshot. A ReadView would
769 take a snapshot of these transactions whose changes are not visible to it.
770 We should remove transactions from the list before committing in memory and
771 releasing locks to ensure right order of removal and consistent snapshot. */
773
775
776 /** Mapping from transaction id to transaction instance. */
778
779 /** Number of transactions currently in the XA PREPARED state. */
781
782 /** True if XA PREPARED trxs are found. */
784
785 /** @} */
786
788
790 return trx_sys->shards[trx_get_shard_no(trx_id)];
791 }
792 template <typename F>
794 const ut::Location &loc) {
795 return get_shard_by_trx_id(trx_id).active_rw_trxs.latch_and_execute(
796 [&](Trx_by_id_with_min &trx_by_id_with_min) {
797 return std::forward<F>(f)(trx_by_id_with_min.get(trx_id));
798 },
799 loc);
800 }
801};
802
803#endif /* !UNIV_HOTBACKUP */
804
805#ifndef UNIV_HOTBACKUP
806
807/** When a trx id which is zero modulo this number (which must be a power of
808two) is assigned, the field TRX_SYS_TRX_ID_STORE on the transaction system
809page is updated */
811
812/** Acquire the trx_sys->mutex. */
813static inline void trx_sys_mutex_enter() { mutex_enter(&trx_sys->mutex); }
814
815/** Release the trx_sys->mutex. */
816static inline void trx_sys_mutex_exit() { trx_sys->mutex.exit(); }
817
818#ifdef UNIV_DEBUG
819
820/** Test if trx_sys->mutex is owned. */
821static inline bool trx_sys_mutex_own() { return trx_sys->mutex.is_owned(); }
822
823/** Test if trx_sys->serialisation_mutex is owned. */
825 return trx_sys->serialisation_mutex.is_owned();
826}
827#endif
828
829/** Acquire the trx_sys->serialisation_mutex. */
832}
833
834/** Release the trx_sys->serialisation_mutex. */
837}
838
839#endif /* !UNIV_HOTBACKUP */
840
841#include "trx0sys.ic"
842
843#endif
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:48
uint32_t page_no_t
Page number.
Definition: api0api.h:46
Kerberos Client Authentication nullptr
Definition: auth_kerberos_client_plugin.cc:247
The database buffer pool high-level routines.
The MVCC read view manager.
Definition: read0read.h:44
Read view lists the trx ids of those transactions for which a consistent read should not see the modi...
Definition: read0types.h:48
This is a wrapper for a std::vector of trx_rseg_t object pointers.
Definition: trx0types.h:331
List of undo tablespace IDs.
Definition: trx0sys.h:319
void sort()
Definition: trx0sys.h:321
bool contains(space_id_t id)
Definition: trx0sys.h:323
iterator find(space_id_t id)
Definition: trx0sys.h:333
Definition: trx0sys.h:348
std::atomic< trx_id_t > m_min_id
For observers which use Trx_shard::mutex protection: each transaction id in the m_by_id is guaranteed...
Definition: trx0sys.h:364
trx_t * get(trx_id_t trx_id) const
Definition: trx0sys.h:597
static std::atomic< trx_id_t > s_lower_bound[2]
A "lower bound" is a value which is guaranteed to be smaller or equal than any id in any of the shard...
Definition: trx0sys.h:541
By_id const & by_id() const
Definition: trx0sys.h:595
trx_id_t min_id() const
Definition: trx0sys.h:596
static constexpr trx_id_t UPDATING_LOWER_BOUND
Definition: trx0sys.h:542
static trx_id_t get_better_lower_bound_for_already_active_id()
Definition: trx0sys.cc:65
static std::atomic< bool > s_updating_lower_bound
This is used during get_better_lower_bound_for_already_active_id() to announce that it is trying to e...
Definition: trx0sys.h:550
static trx_id_t get_cheap_lower_bound_for_already_active_id()
Returns a value which is lower or equal to id of any transaction for which insert(id) happened before...
Definition: trx0sys.h:569
void erase(trx_id_t trx_id)
Definition: trx0sys.h:627
static void limit_to(std::atomic< trx_id_t > &a, trx_id_t upper_bound)
Performs an equivalent of if(upper_bound < a) a=upper_bound atomically, ignoring, but preserving the ...
Definition: trx0sys.h:555
void insert(trx_t &trx)
Definition: trx0sys.h:607
std::unordered_map< trx_id_t, trx_t *, Trx_track_hash > By_id
Definition: trx0sys.h:355
By_id m_by_id
Definition: trx0sys.h:356
Page identifier.
Definition: buf0types.h:207
The low-level file system.
constexpr uint32_t FSEG_PAGE_DATA
On a page of any file segment, data may be put starting from this offset.
Definition: fsp0types.h:79
constexpr uint32_t FSEG_HEADER_SIZE
Length of the file system header, in bytes.
Definition: fsp0types.h:94
#define F
Definition: jit_executor_value.cc:374
The memory management.
Mini-transaction buffer.
Definition: os0file.h:89
Container::const_iterator find(const Container &c, Value &&value)
Definition: generic.h:39
ValueType max(X &&first)
Definition: gtid.h:103
const char * begin(const char *const c)
Definition: base64.h:44
size_t size(const char *const c)
Definition: base64.h:46
Cursor end()
A past-the-end Cursor.
Definition: rules_table_service.cc:192
constexpr size_t INNODB_CACHE_LINE_SIZE
CPU cache line size.
Definition: ut0cpu_cache.h:41
std::vector< T, ut::allocator< T > > vector
Specialization of vector which uses allocator.
Definition: ut0new.h:2876
Index page routines.
required string key
Definition: replication_asynchronous_connection_failover.proto:60
Definition: trx0sys.h:349
size_t operator()(const trx_id_t &key) const
Definition: trx0sys.h:350
Shard for subset of transactions.
Definition: trx0sys.h:670
ut::Cacheline_padded< ut::Guarded< Trx_by_id_with_min, LATCH_ID_TRX_SYS_SHARD > > active_rw_trxs
Mapping from trx->id to trx of active rw transactions.
Definition: trx0sys.h:675
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:177
The transaction system central memory data structure.
Definition: trx0sys.h:679
UT_LIST_BASE_NODE_T(trx_t, no_list) serialisation_list
Tracks minimal transaction id which has received trx->no, but has not yet finished commit for the mtr...
TrxSysMutex serialisation_mutex
Mutex to protect serialisation_list.
Definition: trx0sys.h:725
char pad3[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:737
UT_LIST_BASE_NODE_T(trx_t, mysql_trx_list) mysql_trx_list
List of transactions created for MySQL.
UT_LIST_BASE_NODE_T(trx_t, trx_list) rw_trx_list
List of active and committed in memory read-write transactions, sorted on trx id, biggest first.
std::atomic< trx_id_t > next_trx_id_or_no
The smallest number not yet assigned as a transaction id or transaction number.
Definition: trx0sys.h:715
std::atomic< uint64_t > rseg_history_len
Length of the TRX_RSEG_HISTORY list (update undo logs for committed transactions).
Definition: trx0sys.h:697
auto latch_and_execute_with_active_trx(trx_id_t trx_id, F &&f, const ut::Location &loc)
Definition: trx0sys.h:793
std::atomic< trx_id_t > serialisation_min_trx_no
Definition: trx0sys.h:741
char pad7[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:774
char pad2[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:720
trx_id_t rw_max_trx_no
Max trx number of read-write transactions added for purge.
Definition: trx0sys.h:734
Rsegs tmp_rsegs
Vector of pointers to rollback segments within the temp tablespace; This vector is created and destro...
Definition: trx0sys.h:693
char pad4[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:746
char pad1[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:702
bool found_prepared_trx
True if XA PREPARED trxs are found.
Definition: trx0sys.h:783
MVCC * mvcc
Multi version concurrency control manager.
Definition: trx0sys.h:687
Trx_shard & get_shard_by_trx_id(trx_id_t trx_id)
Definition: trx0sys.h:789
Trx_shard shards[TRX_SHARDS_N]
Mapping from transaction id to transaction instance.
Definition: trx0sys.h:777
char pad5[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:753
ulint n_prepared_trx
Number of transactions currently in the XA PREPARED state.
Definition: trx0sys.h:780
TrxSysMutex mutex
Mutex protecting most fields in this structure (the default one).
Definition: trx0sys.h:751
char pad0[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:681
char pad_after[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:787
char pad6[ut::INNODB_CACHE_LINE_SIZE]
Definition: trx0sys.h:759
trx_ids_t rw_trx_ids
Array of Read write transaction IDs for MVCC snapshot.
Definition: trx0sys.h:772
Definition: trx0trx.h:675
trx_id_t id
transaction id
Definition: trx0trx.h:727
A utility wrapper class, which adds padding at the end of the wrapped structure, so that the next obj...
Definition: ut0cpu_cache.h:55
Definition: ut0core.h:36
constexpr size_t TRX_SHARDS_N
Number of shards created for transactions.
Definition: trx0sys.h:337
constexpr trx_id_t TRX_SYS_TRX_ID_WRITE_MARGIN
When a trx id which is zero modulo this number (which must be a power of two) is assigned,...
Definition: trx0sys.h:810
static void trx_sysf_rseg_set_page_no(trx_sysf_t *sys_header, ulint i, page_no_t page_no, mtr_t *mtr)
Set the page number of the nth rollback segment slot in the trx system file copy.
constexpr uint32_t TRX_SYS_MYSQL_LOG_NAME
MySQL log file name.
Definition: trx0sys.h:275
void trx_sys_update_mysql_binlog_offset(trx_t *trx, mtr_t *mtr)
Updates the offset information about the end of the MySQL binlog entry which corresponds to the trans...
Definition: trx0sys.cc:363
constexpr uint32_t TRX_SYS_MYSQL_LOG_OFFSET_HIGH
high 4 bytes of the offset within that file
Definition: trx0sys.h:271
size_t trx_get_shard_no(trx_id_t trx_id)
Computes shard number for a given trx_id.
Definition: trx0sys.h:342
constexpr uint32_t TRX_SYS_DOUBLEWRITE_MAGIC
4-byte magic number which shows if we already have created the doublewrite buffer
Definition: trx0sys.h:291
static bool trx_sys_hdr_page(const page_id_t &page_id)
Checks if a page address is the trx sys header page.
static void trx_sys_mutex_exit()
Release the trx_sys->mutex.
Definition: trx0sys.h:816
static void trx_write_trx_id(byte *ptr, trx_id_t id)
Writes a trx id to an index page.
void trx_sys_get_binlog_prepared(std::vector< trx_id_t > &trx_ids)
Get a list of all binlog prepared transactions.
Definition: trx0sys.cc:211
static void trx_sys_serialisation_mutex_exit()
Release the trx_sys->serialisation_mutex.
Definition: trx0sys.h:835
void trx_sys_after_pre_dd_shutdown_validate()
Validates lists of transactions at the very end of the pre-dd-shutdown phase.
Definition: trx0sys.cc:720
static void trx_sys_serialisation_mutex_enter()
Acquire the trx_sys->serialisation_mutex.
Definition: trx0sys.h:830
constexpr uint32_t TRX_SYS_SYSTEM_RSEG_ID
The automatically created system rollback segment has this id.
Definition: trx0sys.h:241
static trx_t * trx_rw_is_active(trx_id_t trx_id, bool do_ref_count)
Checks if a rw transaction with the given id is active.
static trx_sysf_t * trx_sysf_get(mtr_t *mtr)
Gets a pointer to the transaction system file copy and x-locks its page.
void trx_sys_read_binlog_position(char *file, uint64_t &offset)
Get current binary log positions stored.
Definition: trx0sys.cc:295
constexpr uint32_t TRX_SYS
The offset of the transaction system header on the page.
Definition: trx0sys.h:244
void trx_sys_create(void)
Creates the trx_sys instance and initializes purge_queue and mutex.
Definition: trx0sys.cc:601
trx_id_t trx_sys_oldest_trx_no()
Definition: trx0sys.cc:201
size_t trx_sys_recovered_active_trxs_count()
Reads number of recovered transactions which have state equal to TRX_STATE_ACTIVE (so are not prepare...
Definition: trx0sys.cc:758
constexpr uint32_t TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N
Contents of TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED.
Definition: trx0sys.h:312
void trx_sys_before_pre_dd_shutdown_validate()
Validates lists of transactions at the very beginning of the pre-dd-shutdown phase.
Definition: trx0sys.cc:697
constexpr uint32_t TRX_SYS_MYSQL_LOG_MAGIC_N
Contents of TRX_SYS_MYSQL_LOG_MAGIC_N_FLD.
Definition: trx0sys.h:262
constexpr uint32_t TRX_SYS_DOUBLEWRITE_FSEG
fseg header of the fseg containing the doublewrite buffer
Definition: trx0sys.h:288
purge_pq_t * trx_sys_init_at_db_start(void)
Creates and initializes the central memory structures for the transaction system.
Definition: trx0sys.cc:481
ulint trx_sysf_rseg_find_free(mtr_t *mtr)
Look for a free slot for a rollback segment in the trx system file copy.
Definition: trx0sys.cc:384
void trx_sys_close(void)
Shutdown/Close the transaction system.
Definition: trx0sys.cc:644
constexpr uint32_t TRX_SYS_DOUBLEWRITE_REPEAT
we repeat TRX_SYS_DOUBLEWRITE_MAGIC, TRX_SYS_DOUBLEWRITE_BLOCK1, TRX_SYS_DOUBLEWRITE_BLOCK2 so that i...
Definition: trx0sys.h:301
trx_id_t trx_sys_allocate_trx_no()
Allocates a new transaction number (for trx->no).
Definition: trx0sys.ic:231
static trx_id_t trx_read_trx_id(const byte *ptr)
Reads a trx id from an index page.
static bool trx_sys_need_rollback()
Determine if there are incomplete transactions in the system.
bool trx_sys_validate_trx_list()
Validate the trx_sys_t::rw_trx_list.
Definition: trx0sys.cc:775
static void trx_sysf_rseg_set_space(trx_sysf_t *sys_header, ulint i, space_id_t space, mtr_t *mtr)
Sets the space id of the nth rollback segment slot in the trx system file copy.
static void trx_sys_rw_trx_add(trx_t *trx)
Add the transaction to the RW transaction set.
constexpr uint32_t TRX_SYS_MYSQL_LOG_NAME_LEN
Maximum length of MySQL binlog file name, in bytes.
Definition: trx0sys.h:260
bool trx_sys_write_binlog_position(const char *last_file, uint64_t last_offset, const char *file, uint64_t offset)
Update binary log position if not already updated.
Definition: trx0sys.cc:347
void trx_sys_create_sys_pages(void)
Creates and initializes the transaction system at the database creation.
Definition: trx0sys.cc:632
constexpr uint32_t TRX_SYS_DOUBLEWRITE_BLOCK1
page number of the first page in the first sequence of 64 (= FSP_EXTENT_SIZE) consecutive pages in th...
Definition: trx0sys.h:294
static bool trx_sys_mutex_own()
Test if trx_sys->mutex is owned.
Definition: trx0sys.h:821
constexpr uint32_t TRX_SYS_TRX_ID_STORE
Transaction system header.
Definition: trx0sys.h:252
void trx_sys_after_background_threads_shutdown_validate()
Validates lists of transactions after all background threads of InnoDB exited during shutdown of MySQ...
Definition: trx0sys.cc:752
constexpr uint32_t TRX_SYS_MYSQL_LOG_OFFSET_LOW
low 4 bytes of the offset within that file
Definition: trx0sys.h:273
trx_id_t trx_sys_allocate_trx_id()
Allocates a new transaction id (for trx->id).
Definition: trx0sys.ic:226
void trx_sys_persist_gtid_num(trx_id_t gtid_trx_no)
Persist transaction number limit below which all transaction GTIDs are persisted to disk table.
Definition: trx0sys.cc:190
constexpr uint32_t TRX_SYS_DOUBLEWRITE_MAGIC_N
Contents of TRX_SYS_DOUBLEWRITE_MAGIC.
Definition: trx0sys.h:310
static void trx_sys_mutex_enter()
Acquire the trx_sys->mutex.
Definition: trx0sys.h:813
static page_no_t trx_sysf_rseg_get_page_no(trx_sysf_t *sys_header, ulint i, mtr_t *mtr)
Gets the page number of the nth rollback segment slot in the trx system file copy.
uint trx_rseg_n_slots_debug
Definition: trx0sys.cc:147
constexpr uint32_t TRX_SYS_MYSQL_LOG_MAGIC_N_FLD
magic number which is TRX_SYS_MYSQL_LOG_MAGIC_N if we have valid data in the MySQL binlog info
Definition: trx0sys.h:269
trx_sys_t * trx_sys
The transaction system.
Definition: trx0sys.cc:60
constexpr uint32_t TRX_SYS_DOUBLEWRITE_BLOCK2
page number of the first page in the second sequence of 64 consecutive pages in the doublewrite buffe...
Definition: trx0sys.h:297
constexpr uint32_t TRX_SYS_FSEG_HEADER
segment header for the tablespace segment the trx system is created into
Definition: trx0sys.h:254
constexpr uint32_t TRX_SYS_RSEGS
the start of the array of rollback segment specification slots
Definition: trx0sys.h:256
static bool trx_sys_serialisation_mutex_own()
Test if trx_sys->serialisation_mutex is owned.
Definition: trx0sys.h:824
trx_id_t trx_sys_get_next_trx_id_or_no()
Retrieves a next value that will be allocated if trx_sys_allocate_trx_id() or trx_sys_allocate_trx_id...
Definition: trx0sys.ic:242
constexpr uint32_t TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED
If this is not yet set to TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N, we must reset the doublewrite buffer...
Definition: trx0sys.h:306
Transaction system.
The transaction.
static bool trx_state_eq(const trx_t *trx, trx_state_t state)
Determines if a transaction is in the given state.
Transaction system global type definitions.
@ TRX_STATE_COMMITTED_IN_MEMORY
Definition: trx0types.h:93
constexpr trx_id_t TRX_ID_MAX
Maximum transaction identifier.
Definition: trx0types.h:145
std::priority_queue< TrxUndoRsegs, std::vector< TrxUndoRsegs, ut::allocator< TrxUndoRsegs > >, TrxUndoRsegs > purge_pq_t
Definition: trx0types.h:631
std::vector< trx_id_t, ut::allocator< trx_id_t > > trx_ids_t
Definition: trx0types.h:633
ib_id_t trx_id_t
Transaction identifier (DB_TRX_ID, DATA_TRX_ID)
Definition: trx0types.h:138
byte trx_sysf_t
File objects.
Definition: trx0types.h:155
ib_mutex_t TrxSysMutex
Definition: trx0types.h:174
Version control for database, common definitions, and include files.
constexpr uint32_t UNIV_PAGE_SIZE_MIN
Minimum page size InnoDB currently supports.
Definition: univ.i:321
unsigned long int ulint
Definition: univ.i:406
Utilities for byte operations.
Utilities related to class lifecycle.
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:105
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:93
The ut::Guarded template which protects access to another class with mutex.
List utilities.
Policy based mutexes.
#define mutex_enter(M)
Definition: ut0mutex.h:117