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.
This commit is contained in:
Marko Mäkelä 2018-01-03 14:30:58 +02:00
parent c2c2173727
commit 9eb3fcc9fb

View File

@ -1866,8 +1866,9 @@ ulint
trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
buf_block_t* block, mtr_t* mtr)
{
ulint first_free = mach_read_from_2(block->frame + TRX_UNDO_PAGE_HDR
+ TRX_UNDO_PAGE_FREE);
byte* ptr_first_free = TRX_UNDO_PAGE_HDR + 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 <= UNIV_PAGE_SIZE);
byte* start = block->frame + first_free;
@ -1895,11 +1896,10 @@ trx_undo_page_report_rename(trx_t* trx, const dict_table_t* table,
ptr += 2;
ulint offset = page_offset(ptr);
mach_write_to_2(start, offset);
mach_write_to_2(block->frame + TRX_UNDO_PAGE_HDR
+ TRX_UNDO_PAGE_FREE, offset);
mach_write_to_2(ptr_first_free, offset);
trx_undof_page_add_undo_rec_log(block->frame, first_free, offset, mtr);
return offset;
return first_free;
}
/** Report a RENAME TABLE operation.