Skip to content

Commit 244fdc4

Browse files
committed
MDEV-29438 Recovery or backup of instant ALTER TABLE is incorrect
This bug was found in MariaDB Server 10.6 thanks to the OPT_PAGE_CHECKSUM record that was implemented in commit 4179f93 for catching this type of recovery failures. page_cur_insert_rec_low(): If the previous record is the page infimum, correctly limit the end of the record. We do not want to copy data from the header of the page supremum. This omission caused the incorrect recovery of DB_TRX_ID in an instant ALTER TABLE metadata record, because part of the DB_TRX_ID was incorrectly copied from the n_owned of the page supremum, which in recovery would be updated after the copying, but in normal operation would already have been updated at the time the common prefix was being determined. log_phys_t::apply(): If a data page is found to be corrupted, do not flag the log corrupted but instead return a new status APPLIED_CORRUPTED so that the caller may discard all log for this page. We do not want the recovery of unrelated pages to fail in recv_recover_page(). No test case is included, because the known test case would only work in 10.6, and even after this fix, it would trigger another bug in instant ALTER TABLE crash recovery.
1 parent 5cbc5db commit 244fdc4

File tree

2 files changed

+8
-5
lines changed

2 files changed

+8
-5
lines changed

storage/innobase/log/log0recv.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,9 @@ struct log_phys_t : public log_rec_t
187187
/** The page was modified, affecting the encryption parameters */
188188
APPLIED_TO_ENCRYPTION,
189189
/** The page was modified, affecting the tablespace header */
190-
APPLIED_TO_FSP_HEADER
190+
APPLIED_TO_FSP_HEADER,
191+
/** The page was found to be corrupted */
192+
APPLIED_CORRUPTED,
191193
};
192194

193195
/** Apply log to a page frame.
@@ -308,8 +310,7 @@ struct log_phys_t : public log_rec_t
308310
{
309311
page_corrupted:
310312
ib::error() << "Set innodb_force_recovery=1 to ignore corruption.";
311-
recv_sys.found_corrupt_log= true;
312-
return applied;
313+
return APPLIED_CORRUPTED;
313314
}
314315
break;
315316
case INSERT_HEAP_REDUNDANT:
@@ -2338,6 +2339,7 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
23382339
start_lsn = 0;
23392340
continue;
23402341
case log_phys_t::APPLIED_YES:
2342+
case log_phys_t::APPLIED_CORRUPTED:
23412343
goto set_start_lsn;
23422344
case log_phys_t::APPLIED_TO_FSP_HEADER:
23432345
case log_phys_t::APPLIED_TO_ENCRYPTION:
@@ -2391,7 +2393,8 @@ static void recv_recover_page(buf_block_t* block, mtr_t& mtr,
23912393
}
23922394

23932395
set_start_lsn:
2394-
if (recv_sys.found_corrupt_log && !srv_force_recovery) {
2396+
if ((a == log_phys_t::APPLIED_CORRUPTED
2397+
|| recv_sys.found_corrupt_log) && !srv_force_recovery) {
23952398
break;
23962399
}
23972400

storage/innobase/page/page0cur.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1573,7 +1573,7 @@ page_cur_insert_rec_low(
15731573
{
15741574
const byte *r= rec;
15751575
const byte *c= cur->rec;
1576-
const byte *c_end= cur->rec + data_size;
1576+
const byte *c_end= c + (page_rec_is_infimum(c) ? 8 : data_size);
15771577
static_assert(REC_N_OLD_EXTRA_BYTES == REC_N_NEW_EXTRA_BYTES + 1, "");
15781578
if (c <= insert_buf && c_end > insert_buf)
15791579
c_end= insert_buf;

0 commit comments

Comments
 (0)