Bug #120647 Contribution: InnoDB: make_page_dirty debug command logs MLOG_2BYTES on com ...
Submitted: 9 Jun 17:40
Reporter: OCA Admin (OCA) Email Updates:
Status: Open Impact on me:
None 
Category:MySQL Server: InnoDB storage engine Severity:S3 (Non-critical)
Version: OS:Any
Assigned to: CPU Architecture:Any

To submit contributions, please log in.

[9 Jun 17:40] OCA Admin
Contribution submitted via Github - InnoDB: make_page_dirty debug command logs MLOG_2BYTES on compressed index pages 
(*) Contribution by Przemysław Skibiński (Github inikep, https://github.com/mysql/mysql-server/pull/666): ### Summary

The debug `innodb_interpreter` `make_page_dirty` command (`storage/innobase/ut/ut0test.cc`) dirties a page by rewriting `FIL_PAGE_TYPE` with a generic `MLOG_2BYTES` redo record via `mlog_write_ulint()`. When the target page is a compressed (`ROW_FORMAT=COMPRESSED`) index page, crash recovery later replays that generic `MLOG_nBYTES` record with both `page` and `page_zip` set, which violates the redo parser invariant

```
ut_a(!page || !page_zip || !fil_page_index_page_check(page));
```

checked in `mlog_parse_nbytes()` (`storage/innobase/mtr/mtr0log.cc`), asserting and crashing during recovery.

### How to reproduce

Observed as a flaky failure in `innodb.dblwr_encrypt_rowcomp` during crash recovery (debug build). The crash stack is:

```
Assertion failure: mtr0log.cc:178:!page || !page_zip || !fil_page_index_page_check(page)
  mlog_parse_nbytes() at storage/innobase/mtr/mtr0log.cc:178
```

This is a debug-only issue, since `make_page_dirty` is a debug-only interpreter command.

### Fix

For compressed index pages, header modifications must be logged with `MLOG_ZIP_WRITE_HEADER` so the compressed page image stays consistent on replay. Write the header value with `mach_write_to_2()` and log it through `page_zip_write_header()` for compressed index pages, matching how normal compressed-page header updates are logged. The existing `MLOG_2BYTES` path is retained for uncompressed and non-index pages.

### Test

A new test, `innodb.make_page_dirty_rowcomp`, reproduces the crash deterministically: it saves the clean (pre-`make_page_dirty`) image of the compressed index root page, runs `make_page_dirty`, kills the server, and restores the saved older image on disk before restart, so recovery is forced to replay the `make_page_dirty` redo record on top of an older page copy.

* Without the fix, the test crashes recovery with the assertion above.
* With the fix, the test passes (verified across repeated runs).

### Verification

```
./mysql-test-run.pl --suite=innodb make_page_dirty_rowcomp 
    --debug-server --retry=0 --force --parallel=1
```

---

I confirm the code being submitted is offered under the terms of the OCA, and that I am authorized to contribute it.

Attachment: git_patch_3831686119.txt (text/plain), 10.01 KiB.