Skip to content

Commit

Permalink
Follow-up fix to MDEV-15132 Avoid accessing the TRX_SYS page
Browse files Browse the repository at this point in the history
trx_undo_mem_create_at_db_start(): Do not read TRX_UNDO_TRX_NO
unless the field is known to be valid, that is, the transaction
has been serialized and trx_purge_add_undo_to_history() has been
invoked.

Normally InnoDB pages would be zero-initialized on allocation
(since MySQL 5.5 or so), but the undo log pages skip that
mechanism. So, reused undo log pages can contain garbage.
Undo log headers can start at any offset (there can be
multiple undo log headers in the same undo log page).
Therefore, because the TRX_UNDO_TRX_NO is never explicitly
initialized on undo log header creation, its contents may
be garbage.
  • Loading branch information
dr-m committed Jan 31, 2018
1 parent 7eb084f commit dcc09af
Showing 1 changed file with 10 additions and 6 deletions.
16 changes: 10 additions & 6 deletions storage/innobase/trx/trx0undo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1113,12 +1113,7 @@ trx_undo_mem_create_at_db_start(trx_rseg_t* rseg, ulint id, ulint page_no,
xid.null();
}

trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_NO);
if (trx_id > max_trx_id) {
max_trx_id = trx_id;
}

trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID);
trx_id_t trx_id = mach_read_from_8(undo_header + TRX_UNDO_TRX_ID);
if (trx_id > max_trx_id) {
max_trx_id = trx_id;
}
Expand All @@ -1139,6 +1134,15 @@ trx_undo_mem_create_at_db_start(trx_rseg_t* rseg, ulint id, ulint page_no,
ut_ad(type == TRX_UNDO_INSERT);
state = TRX_UNDO_TO_PURGE;
} else {
if (state == TRX_UNDO_TO_PURGE
|| state == TRX_UNDO_CACHED) {
trx_id_t id = mach_read_from_8(TRX_UNDO_TRX_NO
+ undo_header);
if (id > max_trx_id) {
max_trx_id = id;
}
}

fil_addr_t last_addr = flst_get_last(
TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + undo_page,
&mtr);
Expand Down

0 comments on commit dcc09af

Please sign in to comment.