Re: All-zero page in GIN index causes assertion failure - Mailing list pgsql-hackers

From Alvaro Herrera
Subject Re: All-zero page in GIN index causes assertion failure
Date
Msg-id 20150807182054.GX2441@postgresql.org
Whole thread Raw
In response to Re: All-zero page in GIN index causes assertion failure  (Heikki Linnakangas <hlinnaka@iki.fi>)
Responses Re: All-zero page in GIN index causes assertion failure  (Alvaro Herrera <alvherre@2ndquadrant.com>)
Re: All-zero page in GIN index causes assertion failure  (Alvaro Herrera <alvherre@2ndquadrant.com>)
List pgsql-hackers
Heikki Linnakangas wrote:

> BRIN update is not quite right, however. brin_getinsertbuffer() can
> initialize a page, but the caller might bail out without using the page and
> WAL-logging the change. If that happens, the next update that uses the same
> page will WAL-log the change but it will not use the XLOG_BRIN_INIT_PAGE
> option, and redo will not initialize the page. Redo will fail.

Here's a fix for BRIN: when brin_getinsertbuffer extends the relation
and doesn't return the page, it initializes and logs the page as an
empty regular page before returning, and also records it into the FSM.
That way, some future process that gets a page from FSM will use it,
preventing this type of problem from bloating the index forever.  Also,
this function no longer initializes the page when it returns it to the
caller: instead the caller (brin_doinsert or brin_doupdate) must do
that.  (Previously, the code was initializing the page outside the
critical section that WAL-logs this action).

> BTW, shouldn't there be a step in BRIN vacuum that scans all the BRIN pages?
> If an empty page is missing from the FSM for any reason, there's nothing to
> add it there.

Probably.  I didn't change this part yet.  There are two things to fix:
1. since we use log_newpage_buffer(), we log the initialization but not
the recording into FSM, so the page would be forgotten about.  This can
be tested with PageIsEmpty().  An alternative to the vacuum scan is to
use our own WAL record that not only logs the initialization itself but
also the FSM update.  Not sure this is worth the trouble.

2. additionally, if brin_getinsertbuffer extends the relation but we
crash before the caller initializes it, the page would be detected by
PageIsNew instead and would also need initialization.

-- 
Álvaro Herrera                http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services



pgsql-hackers by date:

Previous
From: Jesper Pedersen
Date:
Subject: Re: Reduce ProcArrayLock contention
Next
From: Alvaro Herrera
Date:
Subject: Re: All-zero page in GIN index causes assertion failure