Fix setting next multixid's offset at offset wraparound

In commit 789d65364c, we started updating the next multixid's offset
too when recording a multixid, so that it can always be used to
calculate the number of members. I got it wrong at offset wraparound:
we need to skip over offset 0. Fix that.

Discussion: https://www.postgresql.org/message-id/d9996478-389a-4340-8735-bfad456b313c@iki.fi
Backpatch-through: 14
pull/256/head
Heikki Linnakangas 2 weeks ago
parent 31d3847a37
commit 4d936c3fff
  1. 9
      src/backend/access/transam/multixact.c

@ -909,6 +909,7 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset,
int64 next_pageno; int64 next_pageno;
int next_entryno; int next_entryno;
MultiXactOffset *next_offptr; MultiXactOffset *next_offptr;
MultiXactOffset next_offset;
LWLock *lock; LWLock *lock;
LWLock *prevlock = NULL; LWLock *prevlock = NULL;
@ -976,11 +977,15 @@ RecordNewMultiXact(MultiXactId multi, MultiXactOffset offset,
next_offptr += next_entryno; next_offptr += next_entryno;
} }
if (*next_offptr != offset + nmembers) /* Like in GetNewMultiXactId(), skip over offset 0 */
next_offset = offset + nmembers;
if (next_offset == 0)
next_offset = 1;
if (*next_offptr != next_offset)
{ {
/* should already be set to the correct value, or not at all */ /* should already be set to the correct value, or not at all */
Assert(*next_offptr == 0); Assert(*next_offptr == 0);
*next_offptr = offset + nmembers; *next_offptr = next_offset;
MultiXactOffsetCtl->shared->page_dirty[slotno] = true; MultiXactOffsetCtl->shared->page_dirty[slotno] = true;
} }

Loading…
Cancel
Save