Fix calculation of maximal multixact in ingest_multixact_create_record (#6502)

## Problem

See https://neondb.slack.com/archives/C06F5UJH601/p1706373716661439

## Summary of changes

Use None instead of 0 as initial accumulator value for calculating
maximal multixact XID.

## Checklist before requesting a review

- [ ] I have performed a self-review of my code.
- [ ] If it is a core feature, I have added thorough tests.
- [ ] Do we need to implement analytics? if so did you add the relevant
metrics to the dashboard?
- [ ] If this PR requires public announcement, mark it with
/release-notes label and add several sentences in this section.

## Checklist before merging

- [ ] Do not forget to reformat commit message to not include the above
checklist

---------

Co-authored-by: Konstantin Knizhnik <knizhnik@neon.tech>
Co-authored-by: Heikki Linnakangas <heikki@neon.tech>
This commit is contained in:
Konstantin Knizhnik
2024-01-29 07:39:16 +02:00
committed by GitHub
parent 8253cf1931
commit c1148dc9ac
2 changed files with 23 additions and 7 deletions

View File

@@ -1363,16 +1363,22 @@ impl WalIngest {
self.checkpoint.nextMultiOffset = xlrec.moff + xlrec.nmembers;
self.checkpoint_modified = true;
}
let max_mbr_xid = xlrec.members.iter().fold(0u32, |acc, mbr| {
if mbr.xid.wrapping_sub(acc) as i32 > 0 {
mbr.xid
let max_mbr_xid = xlrec.members.iter().fold(None, |acc, mbr| {
if let Some(max_xid) = acc {
if mbr.xid.wrapping_sub(max_xid) as i32 > 0 {
Some(mbr.xid)
} else {
acc
}
} else {
acc
Some(mbr.xid)
}
});
if self.checkpoint.update_next_xid(max_mbr_xid) {
self.checkpoint_modified = true;
if let Some(max_xid) = max_mbr_xid {
if self.checkpoint.update_next_xid(max_xid) {
self.checkpoint_modified = true;
}
}
Ok(())
}

View File

@@ -203,6 +203,16 @@ def test_import_at_2bil(
$$;
"""
)
# Also create a multi-XID with members past the 2 billion mark
conn2 = endpoint.connect()
cur2 = conn2.cursor()
cur.execute("INSERT INTO t VALUES ('x')")
cur.execute("BEGIN; select * from t WHERE t = 'x' FOR SHARE;")
cur2.execute("BEGIN; select * from t WHERE t = 'x' FOR SHARE;")
cur.execute("COMMIT")
cur2.execute("COMMIT")
# A checkpoint writes a WAL record with xl_xid=0. Many other WAL
# records would have the same effect.
cur.execute("checkpoint")
@@ -217,4 +227,4 @@ def test_import_at_2bil(
conn = endpoint.connect()
cur = conn.cursor()
cur.execute("SELECT count(*) from t")
assert cur.fetchone() == (10000 + 1,)
assert cur.fetchone() == (10000 + 1 + 1,)