diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2023-03-03 11:38:43 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2023-03-03 11:38:43 +0200 |
commit | 077425a65989e62149df1a23a73e50d0c793fb0f (patch) | |
tree | b7442445f1431dece57b200fb50bc0be7b285573 /storage | |
parent | 95d51369c9b1d5b759be630003ab12e9615ea0cc (diff) | |
download | mariadb-git-077425a65989e62149df1a23a73e50d0c793fb0f.tar.gz |
MDEV-30311 system-wide max transaction id corrupted after changing the undo tablespaces
This fixes a regression due to MDEV-19229. InnoDB would fail to maintain
the maximum transaction ID when it changes and reinitializes the number
of undo tablespaces. InnoDB should maintain the maximum transaction ID
in TRX_RSEG_MAX_TRX_ID of system rollback segment header.
srv_undo_tablespaces_reinit(): Preserve the system-wide maximum
transaction identifier in the TRX_RSEG_MAX_TRX_ID field of
the first rollback segment. If needed, upgrade the page to the
MariaDB 10.3 format first. All this must be done in the same
atomic mini-transaction that will reinitialize the TRX_SYS page.
Before MariaDB Server 10.3, InnoDB persisted the maximum transaction
identifier only in the TRX_SYS page. MariaDB 10.3 started to treat that
page as a read-only directory of rollback segments, and the maximum
transaction identifier will be recovered from TRX_RSEG_MAX_TRX_ID or
from undo logs. Since a change of innodb_undo_tablespaces is only
allowed when no undo log records exist, the only place to store the
persistent maximum transaction identifier is in TRX_RSEG_MAX_TRX_ID
of one of the rollback segment header pages.
The bug was observed when the database was upgraded directly from MySQL 5.7
or earlier, or from MariaDB Server 10.2 or earlier, to multiple
innodb_undo_tablespaces. On a restart of MariaDB after the upgrade,
the transaction identifier would be reported to be smaller than during
the upgrade:
2023-03-03 10:43:57 0 [Note] InnoDB: log sequence number 2762352; transaction id 1794
2023-03-03 10:44:17 0 [Note] InnoDB: log sequence number 2786076; transaction id 770
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 83571939d1b..9a795126326 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -398,7 +398,7 @@ static dberr_t srv_undo_delete_old_tablespaces() } /** Recreate the undo log tablespaces */ -static dberr_t srv_undo_tablespaces_reinit() +ATTRIBUTE_COLD static dberr_t srv_undo_tablespaces_reinit() { mtr_t mtr; dberr_t err; @@ -431,6 +431,15 @@ static dberr_t srv_undo_tablespaces_reinit() if (!first_rseg_hdr) goto func_exit; + if (UNIV_UNLIKELY(mach_read_from_4(TRX_RSEG + TRX_RSEG_FORMAT + + first_rseg_hdr->page.frame))) + trx_rseg_format_upgrade(first_rseg_hdr, &mtr); + + mtr.write<8,mtr_t::MAYBE_NOP>(*first_rseg_hdr, + TRX_RSEG + TRX_RSEG_MAX_TRX_ID + + first_rseg_hdr->page.frame, + trx_sys.get_max_trx_id() - 1); + /* Reset TRX_SYS page */ err= trx_sys.reset_page(&mtr); |