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