pg_rewind is not crash safe

From: Heikki Linnakangas <hlinnaka(at)iki(dot)fi>
To: pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: pg_rewind is not crash safe
Date: 2020-08-05 18:13:08
Message-ID: d8dcc760-8780-5084-f066-6d663801d2e2@iki.fi
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

A colleague of mine brought to my attention that pg_rewind is not crash
safe. If it is interrupted for any reason, it leaves behind a data
directory with a mix of data from the source and target images. If
you're "lucky", the server will start up, but it can be in an
inconsistent state. That's obviously not good. It would be nice to:

1. Detect the situation, and refuse to start up.

Or even better:

2. Make pg_rewind crash safe, so that you could safely restart it if
it's interrupted.

Has anyone else run into this? How did you work around it?

It doesn't seem hard to detect this. pg_rewind can somehow "poison" the
data directory just before it starts making irreversible changes. I'm
thinking of updating the 'state' in the control file to a new
PG_IN_REWIND value.

It also doesn't seem too hard to make it restartable. As long as you
point it to the same source server, it is already almost safe to run
pg_rewind again. If we re-order the way it writes the control or backup
files and makes other changes, pg_rewind can verify that you pointed it
at the same or compatible primary as before.

I think there's one corner case with truncated files, if pg_rewind has
extended a file by copying missing "tail" from the source system, but
the system crashes before it's fsynced to disk. But I think we can fix
that too, by paying attention to SMGR_TRUNCATE records when scanning the
source WAL.

- Heikki

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Tom Lane 2020-08-05 18:21:59 Re: FailedAssertion("pd_idx == pinfo->nparts", File: "execPartition.c", Line: 1689)
Previous Message Robert Haas 2020-08-05 17:53:03 Re: FailedAssertion("pd_idx == pinfo->nparts", File: "execPartition.c", Line: 1689)