MDEV-27800: Avoid garbage TRX_UNDO_TRX_NO on TRX_UNDO_CACHED pages
In commit c7d04487 (MDEV-15132) MariaDB Server 10.3 stopped writing the latest transaction identifier to the TRX_SYS page. Instead, the transaction identifier will be recovered from undo log pages. Unfortunately, before commit 3926673c and mysql/mysql-server@dc29792ff2996aefbb6e64bb2f0bc3aa8fc879e9 (MySQL 5.1.48 or MariaDB 5.1.48) InnoDB did not always initialize all data fields, but some garbage could be left behind in unused parts of data pages. In undo log pages that are essentially free, but added to a list for reuse (TRX_UNDO_CACHED) the TRX_UNDO_TRX_NO fields could contain garbage, instead of 0. As long as such undo pages are being reused and never marked completely free, the garbage contents may remain forever. In fact, the function trx_undo_header_create() and the record MLOG_UNDO_HDR_CREATE will only initialize TRX_UNDO_TRX_ID, but leave TRX_UNDO_TRX_NO uninitialized. trx_undo_mem_create_at_db_start(): Only read the TRX_UNDO_TRX_NO fields of TRX_UNDO_CACHED pages if the TRX_UNDO_PAGE_TYPE is 0, that is, the page was updated by MariaDB Server 10.3. Earlier versions would always write the TRX_UNDO_PAGE_TYPE as 1 or 2. trx_undo_header_create(): Zero out the TRX_UNDO_TRX_NO field. Strictly speaking, this will change the semantics of the MLOG_UNDO_HDR_CREATE record, but it should not do any harm to overwrite a potentially garbage field with zeroes. Note: This fix will only help future upgrades straight from MariaDB Server 10.2 or MySQL 5.6 or earlier. If such an upgrade has already been made, then an earlier server startup could have fast-forwarded the transaction ID sequence to a large value. If this large value cannot be represented in 48 bits (the size of the DB_TRX_ID column in clustered index records), then various strange things can happen.
Showing
Please register or sign in to comment