summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2021-01-22 16:44:17 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2021-01-22 16:44:17 +0200
commit0e10d7ea14cf795ada8aee7fe1afc590ef6de32c (patch)
treee5b6de8f684471d81b8ba908dd76606e1a043f6e
parent4e503aec7feaeb2297035f565ca92c98d4557577 (diff)
downloadmariadb-git-0e10d7ea14cf795ada8aee7fe1afc590ef6de32c.tar.gz
MDEV-22351 InnoDB may recover wrong information after RESET MASTERbb-10.3-MDEV-22351
Ever since commit 947efe17ed8188ca4feef6deb0c2831a246b5c8f InnoDB no longer writes binlog position in one place. It will not at all be written to the TRX_SYS page, and instead it will be written to the undo log header page that changes the transaction state. trx_rseg_mem_restore(): Recover the information from the latest written page.
-rw-r--r--storage/innobase/include/trx0sys.h6
-rw-r--r--storage/innobase/trx/trx0rseg.cc48
2 files changed, 25 insertions, 29 deletions
diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h
index b8ccb2726b2..30ee5f5833d 100644
--- a/storage/innobase/include/trx0sys.h
+++ b/storage/innobase/include/trx0sys.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -857,8 +857,10 @@ public:
#endif
/** Latest recovered binlog offset */
uint64_t recovered_binlog_offset;
- /** Latest recovred binlog file name */
+ /** Latest recovered binlog file name */
char recovered_binlog_filename[TRX_SYS_MYSQL_LOG_NAME_LEN];
+ /** FIL_PAGE_LSN of the page with the latest recovered binlog metadata */
+ lsn_t recovered_binlog_lsn;
/**
diff --git a/storage/innobase/trx/trx0rseg.cc b/storage/innobase/trx/trx0rseg.cc
index dfc8e5cbcca..d6720979716 100644
--- a/storage/innobase/trx/trx0rseg.cc
+++ b/storage/innobase/trx/trx0rseg.cc
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2020, MariaDB Corporation.
+Copyright (c) 2017, 2021, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -439,8 +439,14 @@ static
void
trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
{
- trx_rsegf_t* rseg_header = trx_rsegf_get_new(
- rseg->space->id, rseg->page_no, mtr);
+ /* This is based on trx_rsegf_get_new().
+ We need to access buf_block_t. */
+ buf_block_t *block = buf_page_get(
+ page_id_t(rseg->space->id, rseg->page_no),
+ univ_page_size, RW_S_LATCH, mtr);
+ buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW);
+
+ const trx_rsegf_t* rseg_header = TRX_RSEG + block->frame;
if (mach_read_from_4(rseg_header + TRX_RSEG_FORMAT) == 0) {
trx_id_t id = mach_read_from_8(rseg_header
@@ -451,32 +457,20 @@ trx_rseg_mem_restore(trx_rseg_t* rseg, trx_id_t& max_trx_id, mtr_t* mtr)
}
if (rseg_header[TRX_RSEG_BINLOG_NAME]) {
- const char* binlog_name = reinterpret_cast<const char*>
- (rseg_header) + TRX_RSEG_BINLOG_NAME;
+ lsn_t lsn = std::max(block->page.newest_modification,
+ mach_read_from_8(FIL_PAGE_LSN
+ + block->frame));
compile_time_assert(TRX_RSEG_BINLOG_NAME_LEN == sizeof
trx_sys.recovered_binlog_filename);
-
- int cmp = *trx_sys.recovered_binlog_filename
- ? strncmp(binlog_name,
- trx_sys.recovered_binlog_filename,
- TRX_RSEG_BINLOG_NAME_LEN)
- : 1;
-
- if (cmp >= 0) {
- uint64_t binlog_offset = mach_read_from_8(
- rseg_header + TRX_RSEG_BINLOG_OFFSET);
- if (cmp) {
- memcpy(trx_sys.
- recovered_binlog_filename,
- binlog_name,
- TRX_RSEG_BINLOG_NAME_LEN);
- trx_sys.recovered_binlog_offset
- = binlog_offset;
- } else if (binlog_offset >
- trx_sys.recovered_binlog_offset) {
- trx_sys.recovered_binlog_offset
- = binlog_offset;
- }
+ if (lsn > trx_sys.recovered_binlog_lsn) {
+ trx_sys.recovered_binlog_lsn = lsn;
+ trx_sys.recovered_binlog_offset
+ = mach_read_from_8(
+ rseg_header
+ + TRX_RSEG_BINLOG_OFFSET);
+ memcpy(trx_sys.recovered_binlog_filename,
+ rseg_header + TRX_RSEG_BINLOG_NAME,
+ TRX_RSEG_BINLOG_NAME_LEN);
}
#ifdef WITH_WSREP