postgresql Point In Time Recovery

Enable archive setting

1
2
3
4
5
6
#Set WAL to either hot_standby or archive
echo "wal_level= hot_standby" > postgresql.conf
#keep archiving old WAL
echo "archive_mode=on" > postgresql.conf
#specify archive command to backup old WAL
echo "archive_command='test ! -f /opt/archive/%f && cp %p /opt/archive/%f' " > postgresql.conf

Origin data

1
2
3
--This table will be included in base backup.
create table test1(id int4 primary key, name varchar(20));
--CREATE TABLE

Base backup

1
pg_basebackup -U postgres -h 127.0.0.1 --format=tar -xzP  -D backup

Use this command to create a base backup tar file.
Recovery work will start from the last check point of this base backup file.
For more backup methods, please refer to my post.

More data after backup

1
2
3
4
5
6
7
8
9
create table test2(id int4 primary key, name varchar(20));
--CREATE TABLE
insert into test2 values (1, 'Rugal'), (2, 'Bernstein'), (3, 'Tenjin'), (4, 'Descend');
--INSERT 0 4
select pg_switch_xlog(); -- force xlog switch to simulate normal log shift
--test2 table will be included in archived xlog
create table test3(id int4 primary key, name varchar(20));
--CREATE TABLE
--test3 table is in current xlog, so this table will not be recovered if current xlog is not backuped

Emulate server crash

You can use any method to make this happens. Like shutdown your server by power off or kill.

kill postgresql

Backup latest unarchived xlog, if you could.

1
cp -r $PGDATA/pg_xlog $HOME

Emulate data files loss.

1
2
#Delete all data file 
rm -r $PGDATA

Now it is time to restore database.

restore base file

What we need to do is just unzip and move all files into $PGDATA folder.

1
2
tar -zxf base.tar.gz
mv * $PGDATA

Now if you start postgresql, you will find data restore to the point of base backup.
But now we need to recover till to most recent valid archieve state.

Setup recovery file

Create a file recovery.conf under you $PGDATA.

1
echo "restore_command = 'cp /opt/archive/%f %p'" > $PGDATA/recovery.conf

Since you have your archived WAL, if you start postgresql, database will recovering process till the last valid segment that was archived.
But if you want to recover to the last valid moment right before crash, maybe that latest segment has not yet been archived, so you need to copy all pg_xlog files in original $PGDATA folder, that is why I said it is better to backup $PGDATA/pg_xlog even with you enabled archive_mode

1
cp  -r $HOME/pg_xlog $PGDATA

If recovery is finished, the recovery.conf file will be renamed to recovery.done to avoid further recovery.


postgresql Point In Time Recovery
https://rug.al/2015/2015-07-18-postgresql-recovery/
Author
Rugal Bernstein
Posted on
July 18, 2015
Licensed under