clog_redo causing very long recovery time

From: Joseph Conway <mail(at)joeconway(dot)com>
To: PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: clog_redo causing very long recovery time
Date: 2011-05-02 06:26:05
Message-ID: 4DBE4E7D.80501@joeconway.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

I'm working with a client that uses Postgres on what amounts to an
appliance.

The database is therefore subject to occasional torture such as, in this
particular case, running out of disk space while performing a million
plus queries (of mixed varieties, many using plpgsql with exception
handling -- more on that later), and eventually being power-cycled. Upon
restart, clog_redo was called approx 885000 times (CLOG_ZEROPAGE) during
recovery, which took almost 2 hours on their hardware. I should note
that this is on Postgres 8.3.x.

After studying the source, I can only see one possible way that this
could have occurred:

In varsup.c:GetNewTracsactionId(), ExtendCLOG() needs to succeed on a
freshly zeroed clog page, and ExtendSUBTRANS() has to fail. Both of
these calls can lead to a page being pushed out of shared buffers and to
disk, so given a lack of disk space, sufficient clog buffers, but lack
of subtrans buffers, this could happen. At that point the transaction id
does not get advanced, so clog zeros the same page, extendSUBTRANS()
fails again, rinse and repeat.

I believe in the case above, subtrans buffers were exhausted due to the
extensive use of plpgsql with exception handling.

I can simulate this failure with the attached debug-clog patch which
makes use of two pre-existing debug GUCs to selectively interject an
ERROR in between calls to ExtendCLOG() and ExtendSUBTRANS(). If you want
to test this yourself, apply this patch and use the function in
test_clog.sql to generate a million or so transactions. After the first
32K or before (based on when clog gets its first opportunity to zero a
new page) you should start seeing messages about injected ERRORs. Let a
few hundred thousand ERRORs go by, then kill postgres. Recovery will
take ages, because clog_redo is calling fsync hundreds of thousands of
times in order to zero the same page over and over.

The attached fix-clogredo diff is my proposal for a fix for this.

Thoughts/alternatives, etc appreciated.

Thanks,

Joe

--
Joe Conway
credativ LLC: http://www.credativ.us
Linux, PostgreSQL, and general Open Source
Training, Service, Consulting, & 24x7 Support

Attachment Content-Type Size
debug-clog-r02.diff text/plain 1.3 KB
fix-clogredo-pg-r03.diff text/plain 883 bytes
test_clog.sql text/plain 999 bytes

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Greg Stark 2011-05-02 06:44:39 Re: Proposed patch: Smooth replication during VACUUM FULL
Previous Message Pavan Deolasee 2011-05-02 06:01:47 Re: branching for 9.2devel