Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add tests, refactor the code changes
Add a python test case that fails without the code fix. In a debug build, it triggers a rust panic in the pageserver, because integer wraparound is checked in debug builds. In a release build, the nextMulti wraparound happens to works, even though it performs a non-wraparound-aware comparison: "xlrec.mid >= self.checkpoint.nextMulti". That comparison is wrong, but as long as we see the the multixd creation records for every multi-xid, the record with `xlrec.mid == 0xffffffff`, it will cause nextMulti to wrap around to 0, and from there on the comparison works again. Fiddly and incorrect, but happens to work... nextMulti is not so lucky, however, because it won't visit every integer, so it won't usually be called with the exact value of 0xffffffff. Move the code to perform the comparisons to a separate function, update_next_multixid(), similar to the update_next_xid() function for regular XIDs. Add unit tests for it. This made it easier to convince myself that it's actually doing the right thing. One notable code change: we no longer skip multixid 0. I confirmed that vanilla Postgres also sets nextMulti to 0 at wraparound, it's just skipped in GetNewMultiXactId(): postgres=# update tt set i = i; checkpoint; select next_multixact_id, next_multi_offset, next_xid from pg_control_checkpoint (); UPDATE 1 CHECKPOINT next_multixact_id | next_multi_offset | next_xid -------------------+-------------------+---------- 4294967294 | 4294967048 | 0:1012 (1 row) postgres=# update tt set i = i; checkpoint; select next_multixact_id, next_multi_offset, next_xid from pg_control_checkpoint (); UPDATE 1 CHECKPOINT next_multixact_id | next_multi_offset | next_xid -------------------+-------------------+---------- 4294967295 | 4294967050 | 0:1013 (1 row) postgres=# update tt set i = i; checkpoint; select next_multixact_id, next_multi_offset, next_xid from pg_control_checkpoint (); UPDATE 1 CHECKPOINT next_multixact_id | next_multi_offset | next_xid -------------------+-------------------+---------- 0 | 4294967052 | 0:1014 (1 row) postgres=# update tt set i = i; checkpoint; select next_multixact_id, next_multi_offset, next_xid from pg_control_checkpoint (); UPDATE 1 CHECKPOINT next_multixact_id | next_multi_offset | next_xid -------------------+-------------------+---------- 2 | 4294967054 | 0:1015 (1 row)
- Loading branch information