mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Wrap multixact/members correctly during extension
In the 9.2 code for extending multixact/members, the logic was very
simple because the number of entries in a members page was a proper
divisor of 2^32, and thus at 2^32 wraparound the logic for page switch
was identical than at any other page boundary. In commit 0ac5ad5134
I
failed to realize this and introduced code that was not able to go over
the 2^32 boundary. Fix that by ensuring that when we reach the last
page of the last segment we correctly zero the initial page of the
initial segment, using correct uint32-wraparound-safe arithmetic.
Noticed while investigating bug #8673 reported by Serge Negodyuck, as
diagnosed by Andres Freund.
This commit is contained in:
parent
722acf51a0
commit
a50d976254
@ -2259,7 +2259,6 @@ ExtendMultiXactMember(MultiXactOffset offset, int nmembers)
|
||||
{
|
||||
int flagsoff;
|
||||
int flagsbit;
|
||||
int difference;
|
||||
|
||||
/*
|
||||
* Only zero when at first entry of a page.
|
||||
@ -2280,10 +2279,25 @@ ExtendMultiXactMember(MultiXactOffset offset, int nmembers)
|
||||
LWLockRelease(MultiXactMemberControlLock);
|
||||
}
|
||||
|
||||
/* Advance to next page (OK if nmembers goes negative) */
|
||||
/*
|
||||
* Advance to next page, taking care to properly handle the wraparound
|
||||
* case. OK if nmembers goes negative.
|
||||
*/
|
||||
if ((unsigned int) (offset + nmembers) < offset)
|
||||
{
|
||||
uint32 difference = offset + MULTIXACT_MEMBERS_PER_PAGE;
|
||||
|
||||
nmembers -= (unsigned int) (MULTIXACT_MEMBERS_PER_PAGE - difference);
|
||||
offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
int difference;
|
||||
|
||||
difference = MULTIXACT_MEMBERS_PER_PAGE - offset % MULTIXACT_MEMBERS_PER_PAGE;
|
||||
offset += difference;
|
||||
nmembers -= difference;
|
||||
offset += difference;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user