Skip to content

Commit f8f5ed2

Browse files
committed
Revert: MDEV-22351 InnoDB may recover wrong information after RESET MASTER
This commit can cause the wrong (old) binlog position to be recovered by mariabackup --prepare. It implements that the value of the FIL_PAGE_LSN is compared to determine which binlog position is the last one and should be recoved. However, it is not guaranteed that the FIL_PAGE_LSN order matches the commit order, as is assumed by the code. This is because the page LSN could be modified by an unrelated update of the page after the commit. In one example, the recovery first encountered this in trx_rseg_mem_restore(): lsn=27282754 binlog position (./master-bin.000001, 472908) and then later: lsn=27282699 binlog position (./master-bin.000001, 477164) The last one 477164 is the correct position. However, because the LSN encountered for the first one is higher, that position is recovered instead. This results in too old binlog position, and a newly provisioned slave will start replicating too early and get duplicate key error or similar. Signed-off-by: Kristian Nielsen <knielsen@knielsen-hq.org>
1 parent e6bd476 commit f8f5ed2

File tree

2 files changed

+26
-21
lines changed

2 files changed

+26
-21
lines changed

storage/innobase/include/trx0sys.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -867,8 +867,6 @@ class trx_sys_t
867867
uint64_t recovered_binlog_offset;
868868
/** Latest recovered binlog file name */
869869
char recovered_binlog_filename[TRX_SYS_MYSQL_LOG_NAME_LEN];
870-
/** FIL_PAGE_LSN of the page with the latest recovered binlog metadata */
871-
lsn_t recovered_binlog_lsn;
872870

873871

874872
/**

storage/innobase/trx/trx0rseg.cc

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -451,13 +451,8 @@ static dberr_t trx_undo_lists_init(trx_rseg_t *rseg, trx_id_t &max_trx_id,
451451
static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id,
452452
mtr_t *mtr)
453453
{
454-
/* This is based on trx_rsegf_get_new().
455-
We need to access buf_block_t. */
456-
buf_block_t *block = buf_page_get(
457-
page_id_t(rseg->space->id, rseg->page_no), 0, RW_S_LATCH, mtr);
458-
buf_block_dbg_add_level(block, SYNC_RSEG_HEADER_NEW);
459-
460-
const trx_rsegf_t* rseg_header = TRX_RSEG + block->frame;
454+
trx_rsegf_t* rseg_header = trx_rsegf_get_new(
455+
rseg->space->id, rseg->page_no, mtr);
461456

462457
if (mach_read_from_4(rseg_header + TRX_RSEG_FORMAT) == 0) {
463458
trx_id_t id = mach_read_from_8(rseg_header
@@ -468,20 +463,32 @@ static dberr_t trx_rseg_mem_restore(trx_rseg_t *rseg, trx_id_t &max_trx_id,
468463
}
469464

470465
if (rseg_header[TRX_RSEG_BINLOG_NAME]) {
471-
lsn_t lsn = std::max(block->page.newest_modification,
472-
mach_read_from_8(FIL_PAGE_LSN
473-
+ block->frame));
466+
const char* binlog_name = reinterpret_cast<const char*>
467+
(rseg_header) + TRX_RSEG_BINLOG_NAME;
474468
compile_time_assert(TRX_RSEG_BINLOG_NAME_LEN == sizeof
475469
trx_sys.recovered_binlog_filename);
476-
if (lsn > trx_sys.recovered_binlog_lsn) {
477-
trx_sys.recovered_binlog_lsn = lsn;
478-
trx_sys.recovered_binlog_offset
479-
= mach_read_from_8(
480-
rseg_header
481-
+ TRX_RSEG_BINLOG_OFFSET);
482-
memcpy(trx_sys.recovered_binlog_filename,
483-
rseg_header + TRX_RSEG_BINLOG_NAME,
484-
TRX_RSEG_BINLOG_NAME_LEN);
470+
471+
int cmp = *trx_sys.recovered_binlog_filename
472+
? strncmp(binlog_name,
473+
trx_sys.recovered_binlog_filename,
474+
TRX_RSEG_BINLOG_NAME_LEN)
475+
: 1;
476+
477+
if (cmp >= 0) {
478+
uint64_t binlog_offset = mach_read_from_8(
479+
rseg_header + TRX_RSEG_BINLOG_OFFSET);
480+
if (cmp) {
481+
memcpy(trx_sys.
482+
recovered_binlog_filename,
483+
binlog_name,
484+
TRX_RSEG_BINLOG_NAME_LEN);
485+
trx_sys.recovered_binlog_offset
486+
= binlog_offset;
487+
} else if (binlog_offset >
488+
trx_sys.recovered_binlog_offset) {
489+
trx_sys.recovered_binlog_offset
490+
= binlog_offset;
491+
}
485492
}
486493

487494
#ifdef WITH_WSREP

0 commit comments

Comments
 (0)