MySQL 26.7.0
Source Code Documentation
trx0undo_trunc.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2025, 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/trx0undo_trunc.h
29 Undo truncation handling */
30
31/**
32 @page PAGE_INNODB_UNDO_TRUNCATE Innodb UNDO Tablespace Truncate
33 Module to handle UNDO tablespace truncation.
34
35 @section undo_num_space_id Undo number vs undo space id
36
37 @subsection undo_num Undo number
38 There could be maximum of 127 UNDO tablespaces on a MySQL instance. Each undo
39 tablespace is assigned an UNDO number in range from 1-127.
40
41 @subsection undo_space_id Undo space id
42 Undo tablespaces have reserved range of 400,000 (s_undo_space_id_range) space
43 ids with Maximum space id as 0xFFFFFFEF (s_max_undo_space_id). Undo space ids
44 are assigned in reverse from high to low. In other words, first Undo space
45 gets max_id assigned and further Undo spaces get id assigned descending from
46 this max.
47
48 So
49 - FSP_MAX_UNDO_TABLESPACES = 127
50 - s_undo_space_id_range = 400,000
51 - s_max_undo_space_id = 0xFFFFFFEF
52
53 So the assignment of UNDO space id to UNDO num is as follows:
54 <pre>
55 Space ID Space Num Space ID Space Num ... Space ID Space Num
56 0xFFFFFFEF 1 0xFFFFFFEe 2 ... 0xFFFFFF71 127
57 0xFFFFFF70 1 0xFFFFFF6F 2 ... 0xFFFFFEF2 127
58 0xFFFFFEF1 1 0xFFFFFEF0 2 ... 0xFFFFFE73 127
59 </pre>
60*/
61
62#pragma once
63
64#include "dict0dict.h" //dict_sys_t::*
65#include "fsp0fsp.h" //fsp_*
66#include "trx0sys.h" //Space_ids
67
68/* Namespace to hold all the related functions and variables needed
69to truncate an undo tablespace. */
70namespace undo_truncate {
71
72// Forward declaration.
73struct Tablespace;
74
75/** Truncate Log file Prefix. */
76static constexpr char s_log_prefix[] = "undo_";
77
78/** Truncate Log file Extension. */
79static constexpr char s_log_ext[] = "trunc.log";
80
81/** Check if TRUNCATE_DDL_LOG file exist.
82@param[in] space_num undo tablespace number
83@return true if exist else false. */
84[[nodiscard]] bool is_active_truncate_log_present(space_id_t space_num);
85
86/** Remove TRUNCATE_DDL_LOG file if it exists
87@param[in] space_num undo tablespace number */
89
90/** Mutex for serializing undo tablespace related DDL. These have to do with
91creating and dropping undo tablespaces. */
92extern ib_mutex_t ddl_mutex;
93
94/** Build a standard undo tablespace name from a space_id.
95This caller is responsible for freeing the returned value using ut::free
96@param[in] space_id id of the undo tablespace.
97@return tablespace name of the undo tablespace file */
98[[nodiscard]] char *make_space_name(space_id_t space_id);
99
100/** Build a standard undo tablespace file name from a space_id.
101This will create a name like 'undo_001' if the space_id is in the
102reserved range, else it will be like 'undo001'.
103This caller is responsible for freeing the returned value using ut::free
104@param[in] space_id id of the undo tablespace.
105@return file_name of the undo tablespace file */
106[[nodiscard]] char *make_file_name(space_id_t space_id);
107
108/** Check if the space_id is an undo space ID in the reserved range.
109@param[in] space_id undo tablespace ID
110@return true if it is in the reserved undo space ID range. */
111[[nodiscard]] inline bool is_reserved(space_id_t space_id) {
112 return (space_id >= dict_sys_t::s_min_undo_space_id &&
114}
115
116/** Convert an undo space number (from 1 to 127) into the undo space_id,
117given an index indicating which space_id from the pool assigned to that
118undo number.
119@param[in] space_num undo tablespace number
120@param[in] ndx index of the space_id within that undo number
121@return space_id of the undo tablespace */
122[[nodiscard]] space_id_t num2id(space_id_t space_num, size_t ndx);
123
124/** Convert an undo space number (from 1 to 127) into an undo space_id.
125Use the undo_truncate::space_id_bank to return the current space_id assigned to
126that undo number.
127@param[in] space_num undo tablespace number
128@return space_id of the undo tablespace */
129[[nodiscard]] space_id_t num2id(space_id_t space_num);
130
131/** Get the corresponding UNDO space number for a given UNDO space id
132@param[in] space_id undo tablespace ID
133@return space number of the undo tablespace */
134[[nodiscard]] space_id_t id2num(space_id_t space_id);
135
136/* Given a reserved undo space_id, return the next space_id for the associated
137undo space number. */
138[[nodiscard]] space_id_t id2next_id(space_id_t space_id);
139/** Map from undo tablespace number to space id to allow a reserved undo space
140ID to be found quickly. */
142 public:
143 /** Constructor which will create the mapping from UNDO space number to UNDO
144 space id from the given space_id list.
145 @param[in] space_ids list of space ids */
146 Undo_num2id_map(const std::vector<space_id_t> &space_ids) {
147 for (auto &id : space_ids) {
148 if (fsp_is_undo_tablespace(id)) {
149 const auto num = id2num(id);
150 ut_a(m_num2id.count(num) == 0);
151 m_num2id[num] = id;
152 }
153 }
154 }
155
156 /** Find the UNDO space_id for a given UNDO space number from the mapping.
157 @param[in] num Undo space number
158 @return UNDO space_id */
159 [[nodiscard]] space_id_t get(space_id_t num) {
160 ut_a(m_num2id.count(num) != 0);
161
162 return m_num2id[num];
163 }
164
165 /** check if mapping contains an entry for given UNDO space number.
166 @param[in] num UNDO space number
167 @return True if entry is there, false otherwise */
168 [[nodiscard]] bool contains(space_id_t num) {
169 return (m_num2id.count(num) != 0);
170 }
171
172 private:
173 /** Map from undo space_num to undo space_id */
174 std::unordered_map<space_id_t, space_id_t> m_num2id{};
175};
176
177/* A pointer to an instance of Undo_num2id_map. It is initialized after we get
178the space_ids from tablespace directory scan and is released after bootstrap.
179It is used only during bootstrap when UNDO tablespaces are being opened post
180REDO recovery. */
182
183/** An undo_truncate::Tablespace object is used to easily convert between
184undo_space_id and undo_space_num and to create the automatic file_name
185and space name. In addition, it is used in undo_truncate::Tablespaces to track
186the trx_rseg_t objects in an Rsegs vector. So we do not allocate the
187Rsegs vector for each object, only when requested by the constructor. */
189 /** Constructor
190 @param[in] id tablespace id */
192 : m_id(id),
193 m_new(false),
194 m_space_name(),
195 m_file_name(),
197 m_rsegs(),
198 truncate_in_progress(false) {}
199
200 /** Copy Constructor
201 @param[in] other undo tablespace to copy */
203 : m_id(other.id()),
204 m_new(other.is_new()),
205 m_space_name(),
206 m_file_name(),
208 m_rsegs() {
209 ut_ad(m_id == 0 || is_reserved(m_id));
210
211 set_space_name(other.space_name());
212 set_file_name(other.file_name());
213
214 /* When the copy constructor is used, add an Rsegs
215 vector. This constructor is only used in the global
216 undo_truncate::Tablespaces object where rollback segments are
217 tracked. */
218 m_rsegs = ut::new_withkey<Rsegs>(UT_NEW_THIS_FILE_PSI_KEY);
219 }
220
221 /** Destructor */
223 if (m_space_name != nullptr) {
225 m_space_name = nullptr;
226 }
227
228 if (m_file_name != nullptr) {
230 m_file_name = nullptr;
231 }
232
233 if (m_log_file_name != nullptr) {
235 m_log_file_name = nullptr;
236 }
237
238 /* Clear the cached rollback segments. */
239 if (m_rsegs != nullptr) {
241 m_rsegs = nullptr;
242 }
243 }
244
245 /* Determine if this undo space needs to be truncated.
246 @return true if it should be truncated, false if not. */
247 [[nodiscard]] bool needs_truncation();
248
249 /** Change the space_id from its current value.
250 @param[in] space_id The new undo tablespace ID */
251 void set_space_id(space_id_t space_id);
252
253 /** Replace the standard undo space name if it exists with a copy
254 of the undo tablespace name provided.
255 @param[in] new_space_name non-standard undo space name */
256 void set_space_name(const char *new_space_name);
257
258 /** Get the undo tablespace name. Make it if not yet made.
259 NOTE: This is only called from stack objects so there is no
260 race condition. If it is ever called from a shared object
261 like undo_truncate::spaces, then it must be protected by the caller.
262 @return tablespace name created from the space_id */
263 [[nodiscard]] char *space_name() {
264 if (m_space_name == nullptr) {
265#ifndef UNIV_HOTBACKUP
267#endif /* !UNIV_HOTBACKUP */
268 }
269
270 return (m_space_name);
271 }
272
273 /** Replace the standard undo file name if it exists with a copy
274 of the file name provided. This name can come in three forms:
275 absolute path, relative path, and basename. Undo ADD DATAFILE
276 does not accept a relative path. So if that comes in here, it
277 was the scanned name and is relative to the datadir.
278 If this is just a basename, add it to srv_undo_dir.
279 @param[in] file_name explicit undo file name */
280 void set_file_name(const char *file_name);
281
282 /** Get the undo space filename. Make it if not yet made.
283 NOTE: This is only called from stack objects so there is no
284 race condition. If it is ever called from a shared object
285 like undo_truncate::spaces, then it must be protected by the caller.
286 @return tablespace filename created from the space_id */
287 [[nodiscard]] char *file_name() {
288 if (m_file_name == nullptr) {
290 }
291
292 return (m_file_name);
293 }
294
295 /** Build a log file name based on space_id
296 @param[in] space_id id of the undo tablespace.
297 @param[in] location directory location of the file.
298 @return DB_SUCCESS or error code */
299 [[nodiscard]] char *make_log_file_name(space_id_t space_id,
300 const char *location);
301
302 /** Get the undo log filename. Make it if not yet made.
303 NOTE: This is only called from stack objects so there is no
304 race condition. If it is ever called from a shared object
305 like undo_truncate::spaces, then it must be protected by the caller.
306 @return tablespace filename created from the space_id */
307 [[nodiscard]] char *log_file_name() {
308 if (m_log_file_name == nullptr) {
310 }
311
312 return (m_log_file_name);
313 }
314
315 /** Get the undo tablespace ID.
316 @return tablespace ID */
317 [[nodiscard]] space_id_t id() { return (m_id); }
318
319 /** Get the undo tablespace number.
320 This is the same as m_id if m_id is 0.
321 @return undo tablespace number */
322 [[nodiscard]] space_id_t num() {
323 const auto n = id2num(m_id);
325 return n;
326 }
327
328 /** Get a reference to the List of rollback segments within
329 this undo tablespace.
330 @return a reference to the Rsegs vector. */
331 [[nodiscard]] Rsegs *rsegs() { return (m_rsegs); }
332
333 /** Report whether this undo tablespace was explicitly created
334 by an SQL statement.
335 @return true if the tablespace was created explicitly. */
336 [[nodiscard]] bool is_explicit() {
338 }
339
340 /** Report whether this undo tablespace was created at startup.
341 @retval true if created at startup.
342 @retval false if pre-existed at startup. */
343 [[nodiscard]] bool is_new() { return (m_new); }
344
345 /** Note that this undo tablespace is being created. */
346 void set_new() { m_new = true; }
347
348 /** Return whether the undo tablespace is active.
349 @return true if active */
350 [[nodiscard]] bool is_active() {
351 if (m_rsegs == nullptr) {
352 return (false);
353 }
354 m_rsegs->s_lock();
355 bool ret = m_rsegs->is_active();
356 m_rsegs->s_unlock();
357 return (ret);
358 }
359
360 /** Return whether the undo tablespace is active. For optimization purposes,
361 do not take a latch.
362 @return true if active */
363 [[nodiscard]] bool is_active_no_latch() {
364 if (m_rsegs == nullptr) {
365 return (false);
366 }
367 return (m_rsegs->is_active());
368 }
369
370 /** Return the rseg at the requested rseg slot if the undo space is active.
371 @param[in] slot The slot of the rseg. 1 to 127
372 @return Rseg pointer of nullptr if the space is not active. */
373 [[nodiscard]] trx_rseg_t *get_active(ulint slot) {
374 m_rsegs->s_lock();
375 if (!m_rsegs->is_active()) {
376 m_rsegs->s_unlock();
377 return (nullptr);
378 }
379
380 /* Mark the chosen rseg so that it will not be selected
381 for UNDO truncation. */
382 trx_rseg_t *rseg = m_rsegs->at(slot);
383 rseg->trx_ref_count++;
384
385 m_rsegs->s_unlock();
386
387 return (rseg);
388 }
389
390 /** Return whether the undo tablespace is inactive due to
391 implicit selection by the purge thread.
392 @return true if marked for truncation by the purge thread */
393 [[nodiscard]] bool is_inactive_implicit() {
394 if (m_rsegs == nullptr) {
395 return (false);
396 }
397 m_rsegs->s_lock();
398 bool ret = m_rsegs->is_inactive_implicit();
399 m_rsegs->s_unlock();
400 return (ret);
401 }
402
403 /** Return whether the undo tablespace was made inactive by
404 ALTER TABLESPACE.
405 @return true if altered inactive */
406 [[nodiscard]] bool is_inactive_explicit() {
407 if (m_rsegs == nullptr) {
408 return (false);
409 }
410 m_rsegs->s_lock();
411 bool ret = m_rsegs->is_inactive_explicit();
412 m_rsegs->s_unlock();
413 return (ret);
414 }
415
416 /** Return whether the undo tablespace is empty and ready
417 to be dropped.
418 @return true if empty */
419 [[nodiscard]] bool is_empty() {
420 if (m_rsegs == nullptr) {
421 return (true);
422 }
423 m_rsegs->s_lock();
424 bool ret = m_rsegs->is_empty();
425 m_rsegs->s_unlock();
426 return (ret);
427 }
428
429 /** Set the undo tablespace active for use by transactions. */
430 void set_active() {
431 m_rsegs->x_lock();
433 m_rsegs->x_unlock();
434 }
435
436 /** Set the state of the rollback segments in this undo tablespace to
437 inactive_implicit if currently active. If the state is inactive_explicit,
438 leave as is. Then put the space_id into the callers marked_space_id.
439 This is done when marking a space for truncate. It will not be used
440 for new transactions until it becomes active again. */
441 void set_inactive_implicit(space_id_t *marked_space_id) {
442 m_rsegs->x_lock();
443 if (m_rsegs->is_active()) {
445 }
446 *marked_space_id = m_id;
447
448 m_rsegs->x_unlock();
449 }
450
451 /** Make the undo tablespace inactive so that it will not be
452 used for new transactions. The purge thread will clear out
453 all the undo logs, truncate it, and then mark it empty. */
455 m_rsegs->x_lock();
457 m_rsegs->x_unlock();
458 }
459
460 /** Make the undo tablespace active again so that it will
461 be used for new transactions.
462 If current State is ___ then do:
463 empty: Set active.
464 active_implicit: Ignore. It was not altered inactive. When it is done
465 being truncated it will go back to active.
466 active_explicit: Depends if it is marked for truncation.
467 marked: Set to inactive_implicit. the next state will be active.
468 not yet: Set to active so that it does not get truncated. */
469 void alter_active();
470
471 /** Set the state of the undo tablespace to empty so that it
472 can be dropped. */
473 void set_empty() {
474 m_rsegs->x_lock();
476 m_rsegs->x_unlock();
477 }
478
479 private:
480 /** Undo Tablespace ID. */
482
483 /** True if this undo tablespace was implicitly created when
484 this instance started up. False if it pre-existed. */
485 bool m_new;
486
487 /** The tablespace name, auto-generated when needed from
488 the space number. */
490
491 /** The tablespace file name, auto-generated when needed
492 from the space number. */
494
495 /** The truncation log file name, auto-generated when needed
496 from the space number and the srv_undo_dir. */
498
499 /** List of rollback segments within this tablespace.
500 This is not always used. Must call init_rsegs to use it. */
502
503 public:
504 /** True if truncation of this undo tablespace is in progress. */
506};
507
508/** List of undo tablespaces, each containing a list of
509rollback segments. */
512 std::vector<Tablespace *, ut::allocator<Tablespace *>>;
513
514 public:
516
518
519 /** Initialize */
520 void init();
521
522 /** De-initialize */
523 void deinit();
524
525 /** Clear the contents of the list of Tablespace objects.
526 This does not deallocate any memory. */
527 void clear() {
528 for (auto undo_space : m_spaces) {
529 ut::delete_(undo_space);
530 }
531 m_spaces.clear();
532 }
533
534 /** Get the number of tablespaces tracked by this object. */
535 ulint size() { return (m_spaces.size()); }
536
537 /** See if the list of tablespaces is empty. */
538 bool empty() { return (m_spaces.empty()); }
539
540 /** Get the Tablespace tracked at a position. */
541 Tablespace *at(size_t pos) { return (m_spaces.at(pos)); }
542
543 /** Add a new undo_truncate::Tablespace to the back of the vector.
544 The vector has been pre-allocated to 128 so read threads will
545 not lose what is pointed to. If tablespace_name and file_name
546 are standard names, they are optional.
547 @param[in] ref_undo_space undo tablespace */
548 void add(Tablespace &ref_undo_space);
549
550 /** Drop an existing explicit undo_truncate::Tablespace.
551 @param[in] undo_space pointer to undo space */
552 void drop(Tablespace *undo_space);
553
554 /** Drop an existing explicit undo_truncate::Tablespace.
555 @param[in] ref_undo_space reference to undo space */
556 void drop(Tablespace &ref_undo_space);
557
558 /** Check if the given space_id is in the vector.
559 @param[in] num undo tablespace number
560 @return true if space_id is found, else false */
561 bool contains(space_id_t num) { return (find(num) != nullptr); }
562
563 /** Find the given space_num in the vector.
564 @param[in] num undo tablespace number
565 @return pointer to an undo_truncate::Tablespace struct */
567 if (m_spaces.empty()) {
568 return (nullptr);
569 }
570
571 /* The sort method above puts this vector in order by
572 Tablespace::num. If there are no gaps, then we should
573 be able to find it quickly. */
574 space_id_t slot = num - 1;
575 if (slot < m_spaces.size()) {
576 auto undo_space = m_spaces.at(slot);
577 if (undo_space->num() == num) {
578 return (undo_space);
579 }
580 }
581
582 /* If there are gaps in the numbering, do a search. */
583 for (auto undo_space : m_spaces) {
584 if (undo_space->num() == num) {
585 return (undo_space);
586 }
587 }
588
589 return (nullptr);
590 }
591
592 /** Find the first undo space that is marked inactive explicitly.
593 @param[in,out] num_active If there are no inactive_explicit spaces
594 found, this will contain the number of
595 active spaces found.
596 @return pointer to an undo_truncate::Tablespace struct */
598 ut_ad(own_latch());
599
600 if (m_spaces.empty()) {
601 return (nullptr);
602 }
603
604 for (auto undo_space : m_spaces) {
605 if (undo_space->is_inactive_explicit()) {
606 return (undo_space);
607 }
608
609 if (num_active != nullptr && undo_space->is_active()) {
610 (*num_active)++;
611 }
612 }
613
614 return (nullptr);
615 }
616
617#ifdef UNIV_DEBUG
618 /** Determine if this thread owns a lock on m_latch. */
619 bool own_latch() {
621 }
622#endif /* UNIV_DEBUG */
623
624 /** Get a shared lock on m_spaces. */
625 void s_lock(ut::Location location) { rw_lock_s_lock(m_latch, location); }
626
627 /** Release a shared lock on m_spaces. */
629
630 /** Get an exclusive lock on m_spaces. */
631 void x_lock(ut::Location location) { rw_lock_x_lock(m_latch, location); }
632
633 /** Release an exclusive lock on m_spaces. */
635
637
638 private:
639 /** RW lock to protect m_spaces.
640 x for adding elements, s for scanning, size() etc. */
642};
643
644/** A global object that contains a vector of undo_truncate::Tablespace structs.
645 */
646extern Tablespaces *spaces;
647
648/** Set an undo tablespace active. */
649void set_active(space_id_t space_id);
650
651constexpr ulint TRUNCATE_FREQUENCY = 128;
652
653/** Track an UNDO tablespace marked for truncate. */
654class Truncate {
655 public:
656 /** Constructor. */
658
659 /** Destructor. */
660 ~Truncate() = default;
661
662 /** Is tablespace selected for truncate.
663 @return true if undo tablespace is marked for truncate */
664 [[nodiscard]] bool is_marked() const {
666 }
667
668 /** Mark the undo tablespace selected for truncate as empty
669 so that it will be truncated next. */
671
672 /** Is the tablespace selected for truncate empty of undo logs yet?
673 @return true if the marked undo tablespace has no more undo logs */
674 [[nodiscard]] bool is_marked_space_empty() const {
676 }
677
678 /** Mark the tablespace for truncate.
679 @param[in] undo_space undo tablespace to truncate. */
680 void mark(Tablespace *undo_space);
681
682 /** Get the number of the tablespace marked for truncate.
683 @return tablespace number marked for truncate. */
684 [[nodiscard]] space_id_t get_marked_space_num() const {
685 return (id2num(m_space_id_marked));
686 }
687
688 /** Reset for next rseg truncate. */
689 void reset() {
690 reset_timer();
693 }
694
695 /** Get the undo tablespace number to start a scan.
696 Re-adjust in case the spaces::size() went down.
697 @return undo space_num to start scanning. */
698 [[nodiscard]] space_id_t get_scan_space_num() const {
700
701 Tablespace *undo_space = spaces->at(s_scan_pos);
702
703 return (undo_space->num());
704 }
705
706 /** Increment the scanning position in a round-robin fashion.
707 @return undo space_num at incremented scanning position. */
708 [[nodiscard]] space_id_t increment_scan() const {
709 /** Round-robin way of selecting an undo tablespace for the truncate
710 operation. Once we reach the end of the list of known undo tablespace
711 IDs, move back to the first undo tablespace ID. This will scan active
712 as well as inactive undo tablespaces. */
714
715 return (get_scan_space_num());
716 }
717
718 /** Check if the given space id is equal to the space ID that is marked for
719 truncation.
720 @return true if they are equal, false otherwise. */
721 [[nodiscard]] bool is_equal(space_id_t space_id) const {
722 return (m_space_id_marked == space_id);
723 }
724
725 /** @return the number of milliseconds since last reset. */
726 [[nodiscard]] int64_t check_timer() const { return (m_timer.elapsed()); }
727
728 /** Reset the timer. */
730
731 private:
732 /** UNDO space ID that is marked for truncate. */
734
735 /** This is true if the marked space is empty of undo logs and ready
736 to truncate. We leave the rsegs object 'inactive' until after it is
737 truncated and rebuilt. This allow the code to do the check for undo
738 logs only once. */
740
741 /** Elapsed time since last truncate check. */
743
744 /** Start scanning for UNDO tablespace from this vector position. This is
745 to avoid bias selection of one tablespace always. */
746 static size_t s_scan_pos;
747
748}; /* class Truncate */
749
750/* Exposed functions */
751
752/** Note that the undo space number for a space ID is being used.
753Put that space_id into the space_id_bank.
754@param[in] space_id undo tablespace number */
755void use_space_id(space_id_t space_id);
756
757/** Mark that the given undo space number is being used and
758return the next available space_id for that space number.
759@param[in] space_num undo tablespace number
760@return the next tablespace ID to use */
761[[nodiscard]] space_id_t use_next_space_id(space_id_t space_num);
762
763/** Given a valid undo space_id, return the next space_id for that
764space number.
765@param[in] space_id undo tablespace ID
766@return the next tablespace ID to use */
767[[nodiscard]] space_id_t next_space_id(space_id_t space_id);
768
769/** Given a valid undo space_id or SPACE_UNKNOWN, return the next space_id
770for the given space number.
771@param[in] space_id undo tablespace ID
772@param[in] space_num undo tablespace number
773@return the next tablespace ID to use */
774[[nodiscard]] space_id_t next_space_id(space_id_t space_id,
775 space_id_t space_num);
776
777/** Mark an undo number associated with a given space_id as unused and
778available to be reused. This happens when the fil_space_t is closed
779associated with a drop undo tablespace.
780@param[in] space_id Undo Tablespace ID */
781void unuse_space_id(space_id_t space_id);
782
783/** Return the next available undo space ID to be used for a new explicit
784undo tablespaces. The slot will be marked as in-use.
785@return next available undo space number if successful.
786@return SPACE_UNKNOWN if failed */
788
789/** Set the FSP_FLAGS_MASK_UNDO_UNUSABLE flag in the undo tablespace
790header to indicate that the undo file is not usable. This is mainly
791done during the truncate operation of undo tablespace.
792@param[in] space_id undo tablespace id
793@param[in] mtr Mini-transaction */
795
796/** Unset the FSP_FLAGS_MASK_UNDO_UNUSABLE in the undo tablespace
797header to indicate that the undo file is now usable.
798@param[in] space_id undo tablespace id
799@param[in] mtr Mini-transaction */
800void mark_undo_tablespace_usable(space_id_t space_id, mtr_t *mtr);
801
802#ifdef UNIV_DEBUG
803/** Inject a crash if a certain SET GLOBAL DEBUG has been set.
804Before DBUG_SUICIDE(), write an entry about this crash to the error log
805and flush the redo log. */
806void inject_crash(const char *injection_point_name);
807
808/** Inject a failure in the undo truncation debug compiled code at various
809places so that it fails the first time it hits and succeeds after that. */
812 const char *m_inject_name;
813
814 public:
815 explicit Inject_failure_once(const char *inject_name)
816 : m_already_failed{false}, m_inject_name{inject_name} {}
817
818 /** If a certain SET GLOBAL DEBUG has been set and this is the first time
819 this has been called for that injection point, write an entry to the
820 error log and return true so that the caller can cause the failure.
821 @return true iff compiled with debug and the debug point has been set
822 and this it the first call for this debug point. */
823 [[nodiscard]] bool should_fail();
824};
825#endif /* UNIV_DEBUG */
826
827} // namespace undo_truncate
uint32_t space_id_t
Tablespace identifier.
Definition: api0api.h:49
This is a wrapper for a std::vector of trx_rseg_t object pointers.
Definition: trx0types.h:331
void set_empty()
Set the state of the undo tablespace to empty so that it can be dropped.
Definition: trx0types.h:450
void set_inactive_implicit()
Set the state of the rollback segments in this undo tablespace to inactive_implicit.
Definition: trx0types.h:438
void set_active()
Set the state of the rollback segments in this undo tablespace to ACTIVE for use by new transactions.
Definition: trx0types.h:431
void s_lock()
Acquire the shared lock on m_rsegs.
Definition: trx0types.h:395
bool is_empty()
Return whether the undo tablespace is empty and ready to be dropped.
Definition: trx0types.h:423
bool is_inactive_implicit()
Return whether the undo tablespace is inactive due to implicit selection by the purge thread.
Definition: trx0types.h:413
bool is_inactive_explicit()
Return whether the undo tablespace was made inactive by ALTER TABLESPACE.
Definition: trx0types.h:418
void s_unlock()
Release the shared lock on m_rsegs.
Definition: trx0types.h:398
void set_inactive_explicit()
Make the undo tablespace inactive so that it will not be used for new transactions.
Definition: trx0types.h:446
bool is_active()
Return whether the undo tablespace is active.
Definition: trx0types.h:408
void x_unlock()
Release the exclusive lock on m_rsegs.
Definition: trx0types.h:404
void x_lock()
Acquire the exclusive lock on m_rsegs.
Definition: trx0types.h:401
trx_rseg_t * at(ulint slot)
Find the rseg at the given slot in this vector.
Definition: trx0types.h:375
For measuring time elapsed.
Definition: ut0ut.h:303
void reset()
Reset the timer to the current time.
Definition: ut0ut.h:312
int64_t elapsed() const noexcept
Definition: ut0ut.h:316
Inject a failure in the undo truncation debug compiled code at various places so that it fails the fi...
Definition: trx0undo_trunc.h:810
Inject_failure_once(const char *inject_name)
Definition: trx0undo_trunc.h:815
bool m_already_failed
Definition: trx0undo_trunc.h:811
bool should_fail()
If a certain SET GLOBAL DEBUG has been set and this is the first time this has been called for that i...
Definition: trx0undo_trunc.cc:516
const char * m_inject_name
Definition: trx0undo_trunc.h:812
List of undo tablespaces, each containing a list of rollback segments.
Definition: trx0undo_trunc.h:510
bool own_latch()
Determine if this thread owns a lock on m_latch.
Definition: trx0undo_trunc.h:619
void clear()
Clear the contents of the list of Tablespace objects.
Definition: trx0undo_trunc.h:527
bool contains(space_id_t num)
Check if the given space_id is in the vector.
Definition: trx0undo_trunc.h:561
ulint size()
Get the number of tablespaces tracked by this object.
Definition: trx0undo_trunc.h:535
void add(Tablespace &ref_undo_space)
Add a new undo_truncate::Tablespace to the back of the vector.
Definition: trx0purge.cc:2082
rw_lock_t * m_latch
RW lock to protect m_spaces.
Definition: trx0undo_trunc.h:641
Tablespace * find_first_inactive_explicit(size_t *num_active)
Find the first undo space that is marked inactive explicitly.
Definition: trx0undo_trunc.h:597
Tablespaces_Vector m_spaces
Definition: trx0undo_trunc.h:636
Tablespaces()
Definition: trx0undo_trunc.h:515
void s_lock(ut::Location location)
Get a shared lock on m_spaces.
Definition: trx0undo_trunc.h:625
std::vector< Tablespace *, ut::allocator< Tablespace * > > Tablespaces_Vector
Definition: trx0undo_trunc.h:512
void drop(Tablespace *undo_space)
Drop an existing explicit undo_truncate::Tablespace.
Definition: trx0purge.cc:2095
Tablespace * at(size_t pos)
Get the Tablespace tracked at a position.
Definition: trx0undo_trunc.h:541
Tablespace * find(space_id_t num)
Find the given space_num in the vector.
Definition: trx0undo_trunc.h:566
bool empty()
See if the list of tablespaces is empty.
Definition: trx0undo_trunc.h:538
void s_unlock()
Release a shared lock on m_spaces.
Definition: trx0undo_trunc.h:628
void x_lock(ut::Location location)
Get an exclusive lock on m_spaces.
Definition: trx0undo_trunc.h:631
void init()
Initialize.
Definition: trx0purge.cc:2058
void x_unlock()
Release an exclusive lock on m_spaces.
Definition: trx0undo_trunc.h:634
void deinit()
De-initialize.
Definition: trx0purge.cc:2073
~Tablespaces()
Definition: trx0undo_trunc.h:517
Track an UNDO tablespace marked for truncate.
Definition: trx0undo_trunc.h:654
void reset()
Reset for next rseg truncate.
Definition: trx0undo_trunc.h:689
bool m_marked_space_is_empty
This is true if the marked space is empty of undo logs and ready to truncate.
Definition: trx0undo_trunc.h:739
ib::Timer m_timer
Elapsed time since last truncate check.
Definition: trx0undo_trunc.h:742
void set_marked_space_empty()
Mark the undo tablespace selected for truncate as empty so that it will be truncated next.
Definition: trx0undo_trunc.h:670
Truncate()
Constructor.
Definition: trx0undo_trunc.h:657
space_id_t get_marked_space_num() const
Get the number of the tablespace marked for truncate.
Definition: trx0undo_trunc.h:684
~Truncate()=default
Destructor.
int64_t check_timer() const
Definition: trx0undo_trunc.h:726
bool is_marked() const
Is tablespace selected for truncate.
Definition: trx0undo_trunc.h:664
static size_t s_scan_pos
Start scanning for UNDO tablespace from this vector position.
Definition: trx0undo_trunc.h:746
space_id_t increment_scan() const
Increment the scanning position in a round-robin fashion.
Definition: trx0undo_trunc.h:708
void reset_timer()
Reset the timer.
Definition: trx0undo_trunc.h:729
bool is_equal(space_id_t space_id) const
Check if the given space id is equal to the space ID that is marked for truncation.
Definition: trx0undo_trunc.h:721
space_id_t get_scan_space_num() const
Get the undo tablespace number to start a scan.
Definition: trx0undo_trunc.h:698
bool is_marked_space_empty() const
Is the tablespace selected for truncate empty of undo logs yet?
Definition: trx0undo_trunc.h:674
void mark(Tablespace *undo_space)
Mark the tablespace for truncate.
Definition: trx0purge.cc:780
space_id_t m_space_id_marked
UNDO space ID that is marked for truncate.
Definition: trx0undo_trunc.h:733
Map from undo tablespace number to space id to allow a reserved undo space ID to be found quickly.
Definition: trx0undo_trunc.h:141
std::unordered_map< space_id_t, space_id_t > m_num2id
Map from undo space_num to undo space_id.
Definition: trx0undo_trunc.h:174
bool contains(space_id_t num)
check if mapping contains an entry for given UNDO space number.
Definition: trx0undo_trunc.h:168
space_id_t get(space_id_t num)
Find the UNDO space_id for a given UNDO space number from the mapping.
Definition: trx0undo_trunc.h:159
Undo_num2id_map(const std::vector< space_id_t > &space_ids)
Constructor which will create the mapping from UNDO space number to UNDO space id from the given spac...
Definition: trx0undo_trunc.h:146
Data dictionary system.
bool fsp_is_undo_tablespace(space_id_t space_id)
Check whether a space id is an undo tablespace ID Undo tablespaces have space_id's starting 1 less th...
Definition: fsp0fsp.cc:264
File space management.
constexpr size_t FSP_MAX_UNDO_TABLESPACES
The maximum number of non-temporary Undo Tablespaces (implicit + explicit) that can exist at the same...
Definition: fsp0types.h:439
constexpr size_t FSP_IMPLICIT_UNDO_TABLESPACES
There are exactly two implicit Undo Tablespaces present at any moment (undo_001 and undo_002),...
Definition: fsp0types.h:444
size_t size(const char *const c)
Definition: base64.h:46
Definition: srv0start.h:50
void mark_undo_tablespace_usable(space_id_t space_id, mtr_t *mtr)
Unset the FSP_FLAGS_MASK_UNDO_UNUSABLE in the undo tablespace header to indicate that the undo file i...
Definition: trx0undo_trunc.cc:498
space_id_t id2num(space_id_t space_id)
Get the corresponding UNDO space number for a given UNDO space id.
Definition: trx0undo_trunc.cc:462
Tablespaces * spaces
A global object that contains a vector of undo_truncate::Tablespace structs.
Definition: trx0undo_trunc.cc:46
space_id_t num2id(space_id_t space_num, size_t ndx)
Convert an undo space number (from 1 to 127) into the undo space_id, given an index indicating which ...
Definition: trx0undo_trunc.cc:437
char * make_file_name(space_id_t space_id)
Build a standard undo tablespace file name from a space_id.
Definition: trx0undo_trunc.cc:406
void set_active(space_id_t space_id)
Set an undo tablespace active.
Definition: trx0undo_trunc.cc:378
space_id_t next_space_id(space_id_t space_id)
Given a valid undo space_id, return the next space_id for that space number.
Definition: trx0undo_trunc.cc:206
constexpr ulint TRUNCATE_FREQUENCY
Definition: trx0undo_trunc.h:651
space_id_t get_next_available_space_id()
Return the next available undo space ID to be used for a new explicit undo tablespaces.
Definition: trx0undo_trunc.cc:198
void inject_crash(const char *injection_point_name)
Inject a crash if a certain SET GLOBAL DEBUG has been set.
Definition: trx0undo_trunc.cc:509
void unuse_space_id(space_id_t space_id)
Mark an undo number associated with a given space_id as unused and available to be reused.
Definition: trx0undo_trunc.cc:202
space_id_t use_next_space_id(space_id_t space_num)
Mark that the given undo space number is being used and return the next available space_id for that s...
Definition: trx0undo_trunc.cc:210
space_id_t id2next_id(space_id_t space_id)
Definition: trx0undo_trunc.cc:473
static constexpr char s_log_prefix[]
Truncate Log file Prefix.
Definition: trx0undo_trunc.h:76
void mark_undo_tablespace_unusable(space_id_t space_id, mtr_t *mtr)
Set the FSP_FLAGS_MASK_UNDO_UNUSABLE flag in the undo tablespace header to indicate that the undo fil...
Definition: trx0undo_trunc.cc:486
void remove_truncate_log_file(space_id_t space_num)
Remove TRUNCATE_DDL_LOG file if it exists.
Definition: trx0undo_trunc.cc:363
bool is_reserved(space_id_t space_id)
Check if the space_id is an undo space ID in the reserved range.
Definition: trx0undo_trunc.h:111
bool is_active_truncate_log_present(space_id_t space_num)
Check if TRUNCATE_DDL_LOG file exist.
Definition: trx0undo_trunc.cc:356
ut::unique_ptr< Undo_num2id_map > num2id_map
Definition: trx0undo_trunc.cc:44
static constexpr char s_log_ext[]
Truncate Log file Extension.
Definition: trx0undo_trunc.h:79
ib_mutex_t ddl_mutex
Mutex for serializing undo tablespace related DDL.
Definition: trx0undo_trunc.cc:42
void use_space_id(space_id_t space_id)
Note that the undo space number for a space ID is being used.
Definition: trx0undo_trunc.cc:196
char * make_space_name(space_id_t space_id)
Build a standard undo tablespace name from a space_id.
Definition: trx0undo_trunc.cc:391
void delete_(T *ptr) noexcept
Releases storage which has been dynamically allocated through any of the ut::new*() variants.
Definition: ut0new.h:651
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
void free(void *ptr) noexcept
Releases storage which has been dynamically allocated through any of the ut::malloc*(),...
Definition: ut0new.h:559
char * srv_undo_dir
Server undo tablespaces directory, can be absolute path.
Definition: srv0srv.cc:155
static constexpr space_id_t s_max_undo_space_id
The highest undo tablespace ID.
Definition: dict0dict.h:1120
static constexpr space_id_t s_min_undo_space_id
The lowest undo tablespace ID.
Definition: dict0dict.h:1116
Mini-transaction handle and buffer.
Definition: mtr0mtr.h:174
The structure used in the spin lock implementation of a read-write lock.
Definition: sync0rw.h:362
The rollback segment memory object.
Definition: trx0types.h:214
std::atomic< size_t > trx_ref_count
Reference counter to track rseg allocated transactions.
Definition: trx0types.h:313
An undo_truncate::Tablespace object is used to easily convert between undo_space_id and undo_space_nu...
Definition: trx0undo_trunc.h:188
space_id_t id()
Get the undo tablespace ID.
Definition: trx0undo_trunc.h:317
Rsegs * rsegs()
Get a reference to the List of rollback segments within this undo tablespace.
Definition: trx0undo_trunc.h:331
void alter_active()
Make the undo tablespace active again so that it will be used for new transactions.
Definition: trx0undo_trunc.cc:334
char * m_file_name
The tablespace file name, auto-generated when needed from the space number.
Definition: trx0undo_trunc.h:493
bool is_inactive_explicit()
Return whether the undo tablespace was made inactive by ALTER TABLESPACE.
Definition: trx0undo_trunc.h:406
char * space_name()
Get the undo tablespace name.
Definition: trx0undo_trunc.h:263
void set_empty()
Set the state of the undo tablespace to empty so that it can be dropped.
Definition: trx0undo_trunc.h:473
void set_new()
Note that this undo tablespace is being created.
Definition: trx0undo_trunc.h:346
char * file_name()
Get the undo space filename.
Definition: trx0undo_trunc.h:287
space_id_t m_id
Undo Tablespace ID.
Definition: trx0undo_trunc.h:481
char * m_log_file_name
The truncation log file name, auto-generated when needed from the space number and the srv_undo_dir.
Definition: trx0undo_trunc.h:497
~Tablespace()
Destructor.
Definition: trx0undo_trunc.h:222
char * m_space_name
The tablespace name, auto-generated when needed from the space number.
Definition: trx0undo_trunc.h:489
bool is_empty()
Return whether the undo tablespace is empty and ready to be dropped.
Definition: trx0undo_trunc.h:419
bool is_inactive_implicit()
Return whether the undo tablespace is inactive due to implicit selection by the purge thread.
Definition: trx0undo_trunc.h:393
void set_space_name(const char *new_space_name)
Replace the standard undo space name if it exists with a copy of the undo tablespace name provided.
Definition: trx0undo_trunc.cc:262
bool is_active()
Return whether the undo tablespace is active.
Definition: trx0undo_trunc.h:350
void set_file_name(const char *file_name)
Replace the standard undo file name if it exists with a copy of the file name provided.
Definition: trx0undo_trunc.cc:275
void set_inactive_implicit(space_id_t *marked_space_id)
Set the state of the rollback segments in this undo tablespace to inactive_implicit if currently acti...
Definition: trx0undo_trunc.h:441
void set_space_id(space_id_t space_id)
Change the space_id from its current value.
Definition: trx0undo_trunc.cc:257
space_id_t num()
Get the undo tablespace number.
Definition: trx0undo_trunc.h:322
void set_active()
Set the undo tablespace active for use by transactions.
Definition: trx0undo_trunc.h:430
trx_rseg_t * get_active(ulint slot)
Return the rseg at the requested rseg slot if the undo space is active.
Definition: trx0undo_trunc.h:373
char * log_file_name()
Get the undo log filename.
Definition: trx0undo_trunc.h:307
bool needs_truncation()
Definition: trx0undo_trunc.cc:215
Tablespace(Tablespace &other)
Copy Constructor.
Definition: trx0undo_trunc.h:202
Rsegs * m_rsegs
List of rollback segments within this tablespace.
Definition: trx0undo_trunc.h:501
bool truncate_in_progress
True if truncation of this undo tablespace is in progress.
Definition: trx0undo_trunc.h:505
bool is_active_no_latch()
Return whether the undo tablespace is active.
Definition: trx0undo_trunc.h:363
bool m_new
True if this undo tablespace was implicitly created when this instance started up.
Definition: trx0undo_trunc.h:485
char * make_log_file_name(space_id_t space_id, const char *location)
Build a log file name based on space_id.
Definition: trx0undo_trunc.cc:310
void set_inactive_explicit()
Make the undo tablespace inactive so that it will not be used for new transactions.
Definition: trx0undo_trunc.h:454
bool is_explicit()
Report whether this undo tablespace was explicitly created by an SQL statement.
Definition: trx0undo_trunc.h:336
bool is_new()
Report whether this undo tablespace was created at startup.
Definition: trx0undo_trunc.h:343
Tablespace(space_id_t id)
Constructor.
Definition: trx0undo_trunc.h:191
Definition: ut0core.h:36
bool rw_lock_own(const rw_lock_t *lock, ulint lock_type)
Checks if the thread has locked the rw-lock in the specified mode, with the pass value == 0.
Definition: sync0rw.cc:858
static void rw_lock_s_unlock(rw_lock_t *L)
Definition: sync0rw.h:807
static void rw_lock_x_lock(rw_lock_t *M, ut::Location L)
Definition: sync0rw.h:781
static void rw_lock_s_lock(rw_lock_t *M, ut::Location L)
Definition: sync0rw.h:730
static void rw_lock_x_unlock(rw_lock_t *L)
Definition: sync0rw.h:810
@ RW_LOCK_S
Definition: sync0types.h:203
@ RW_LOCK_X
Definition: sync0types.h:204
Transaction system.
unsigned long int ulint
Definition: univ.i:403
constexpr space_id_t SPACE_UNKNOWN
Unknown space id.
Definition: univ.i:452
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:109
#define ut_a(EXPR)
Abort execution if EXPR does not evaluate to nonzero.
Definition: ut0dbg.h:97
#define UT_NEW_THIS_FILE_PSI_KEY
Definition: ut0new.h:408
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:510
int n
Definition: xcom_base.cc:509