Commit 9eb3fcc9 authored by Marko Mäkelä's avatar Marko Mäkelä

Follow-up fix of MDEV-14717 RENAME TABLE in InnoDB is not crash-safe

trx_undo_page_report_rename(): Return a pointer to the start of the
undo log record, not to the start of the (not yet written) next free
record. The wrong return value would sometimes cause ROLLBACK to crash
in an assertion failure (trying to parse garbage from the free area at
the end of the insert_undo log page) if the TRX_UNDO_RENAME_TABLE record
was the very last thing that was written to the insert_undo log. This
would occasionally happen when an ALTER TABLE operation is rolled
back due to invalid FOREIGN KEY constraints in the innodb.innodb test.
In these tests, the error ER_ERROR_ON_RENAME (1025) would be returned
at the end of the ALGORITHM=COPY operation of ALTER TABLE.
parent c2c21737
...@@ -1866,8 +1866,9 @@ ulint ...@@ -1866,8 +1866,9 @@ ulint
trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table, trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
buf_block_t* block, mtr_t* mtr) buf_block_t* block, mtr_t* mtr)
{ {
ulint first_free = mach_read_from_2(block->frame + TRX_UNDO_PAGE_HDR byte* ptr_first_free = TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_FREE
+ TRX_UNDO_PAGE_FREE); + block->frame;
ulint first_free = mach_read_from_2(ptr_first_free);
ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE); ut_ad(first_free >= TRX_UNDO_PAGE_HDR + TRX_UNDO_PAGE_HDR_SIZE);
ut_ad(first_free <= UNIV_PAGE_SIZE); ut_ad(first_free <= UNIV_PAGE_SIZE);
byte* start = block->frame + first_free; byte* start = block->frame + first_free;
...@@ -1895,11 +1896,10 @@ trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table, ...@@ -1895,11 +1896,10 @@ trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
ptr += 2; ptr += 2;
ulint offset = page_offset(ptr); ulint offset = page_offset(ptr);
mach_write_to_2(start, offset); mach_write_to_2(start, offset);
mach_write_to_2(block->frame + TRX_UNDO_PAGE_HDR mach_write_to_2(ptr_first_free, offset);
+ TRX_UNDO_PAGE_FREE, offset);
trx_undof_page_add_undo_rec_log(block->frame, first_free, offset, mtr); trx_undof_page_add_undo_rec_log(block->frame, first_free, offset, mtr);
return offset; return first_free;
} }
/** Report a RENAME TABLE operation. /** Report a RENAME TABLE operation.
......
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