Commit ea6ca013 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-32757: rollback crash on corruption

trx_undo_free_page(): Detect a case of corrupted TRX_UNDO_PAGE_LIST.

trx_undo_truncate_end(): Stop attempts to truncate a corrupted log.

trx_t::commit_empty(): Add an error message of a corrupted log.

Reviewed by: Thirunarayanan Balathandayuthapani
parent 5dbe7a8c
...@@ -976,7 +976,13 @@ void trx_t::commit_empty(mtr_t *mtr) ...@@ -976,7 +976,13 @@ void trx_t::commit_empty(mtr_t *mtr)
trx_undo_t *&undo= rsegs.m_redo.undo; trx_undo_t *&undo= rsegs.m_redo.undo;
ut_ad(undo->state == TRX_UNDO_ACTIVE || undo->state == TRX_UNDO_PREPARED); ut_ad(undo->state == TRX_UNDO_ACTIVE || undo->state == TRX_UNDO_PREPARED);
ut_ad(undo->size == 1);
if (UNIV_UNLIKELY(undo->size != 1))
{
sql_print_error("InnoDB: Undo log for transaction " TRX_ID_FMT
" is corrupted (" UINT32PF "!=1)", id, undo->size);
ut_ad("corrupted undo log" == 0);
}
if (buf_block_t *u= if (buf_block_t *u=
buf_page_get(page_id_t(rseg->space->id, undo->hdr_page_no), 0, buf_page_get(page_id_t(rseg->space->id, undo->hdr_page_no), 0,
......
...@@ -740,6 +740,14 @@ trx_undo_free_page( ...@@ -740,6 +740,14 @@ trx_undo_free_page(
return FIL_NULL; return FIL_NULL;
} }
const fil_addr_t last_addr = flst_get_last(
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST
+ header_block->page.frame);
if (UNIV_UNLIKELY(last_addr.page == page_no)) {
*err = DB_CORRUPTION;
return FIL_NULL;
}
*err = fseg_free_page(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER *err = fseg_free_page(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER
+ header_block->page.frame, + header_block->page.frame,
rseg->space, page_no, mtr); rseg->space, page_no, mtr);
...@@ -748,9 +756,6 @@ trx_undo_free_page( ...@@ -748,9 +756,6 @@ trx_undo_free_page(
} }
buf_page_free(rseg->space, page_no, mtr); buf_page_free(rseg->space, page_no, mtr);
const fil_addr_t last_addr = flst_get_last(
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST
+ header_block->page.frame);
rseg->curr_size--; rseg->curr_size--;
if (!in_history) { if (!in_history) {
...@@ -794,6 +799,9 @@ static dberr_t trx_undo_truncate_end(trx_undo_t &undo, undo_no_t limit, ...@@ -794,6 +799,9 @@ static dberr_t trx_undo_truncate_end(trx_undo_t &undo, undo_no_t limit,
{ {
ut_ad(is_temp == !undo.rseg->is_persistent()); ut_ad(is_temp == !undo.rseg->is_persistent());
if (UNIV_UNLIKELY(undo.last_page_no == FIL_NULL))
return DB_CORRUPTION;
for (mtr_t mtr;;) for (mtr_t mtr;;)
{ {
mtr.start(); mtr.start();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment