Alvaro Herrera wrote:
> Serge Negodyuck wrote:
>
> > 2014-06-02 08:20:55 EEST 172.18.10.4 db PANIC: could not access status of
> > transaction 2080547
> > 2014-06-02 08:20:55 EEST 172.18.10.4 db DETAIL: Could not open file
> > "pg_multixact/members/14078": No such file or directory.
> > 2014-06-02 08:20:55 EEST 172.18.10.4 db CONTEXT: SQL statement " UPDATE
> > ....."
>
> So as it turns out, this was caused because the arithmetic to handle the
> wraparound case neglected to handle multixacts with more members than
> the number that fit in the last page(s) of the last segment, leading to
> a number of pages in the 14078 segment (or whatever the last segment is
> for a given BLCKSZ) to fail to be initialized. This patch is a rework
> of that arithmetic, although it seems little bit too obscure.
After some simplification I think it should be clearer. Thanks Andres
for commenting offlist.
There is a different way to compute the "difference" proposed by Andres,
without using if/else; the idea is to cast the values to int64 and then
clamp. It would be something like
uint64 diff64;
diff64 = Min((uint64) offset + nmembers,
(uint64) offset + MULTIXACT_MEMBERS_PER_PAGE);
difference = (uint32) Min(diff64, MaxMultiXactOffset);
(There are other ways to formulate this, of course, but this seems to me
to be the most readable one). I am undecided between this and the one I
propose in the patch, so I've stuck with the patch.
--
Álvaro Herrera http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services