Прежде всего, не делайте этого в вашей производственной базе данных.
Правильный способ (тм) - использовать транзакции для того, что они стоят. В postgres вы можете даже вкладывать их, используя точки сохранения (к которым вы можете выполнить откат).
test=# create table foo (foo_id serial primary key, bar varchar);
NOTICE: CREATE TABLE will create implicit sequence "foo_foo_id_seq" for serial column "foo.foo_id"
NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "foo_pkey" for table "foo"
CREATE TABLE
test=# begin; insert into foo (bar) values ('test');
BEGIN
INSERT 0 1
test=# savepoint sp1;
SAVEPOINT
test=# insert into foo (foo_id, bar) values (1, 'test');
ERROR: duplicate key value violates unique constraint "foo_pkey"
test=# rollback to sp1;
ROLLBACK
test=# select * from foo;
foo_id | bar
--------+------
1 | test
test=# -- note that you're still in a transaction
Если это не подходит (из-за ограничений программного обеспечения или по другим причинам), вы всегда можете хранить несколько дампов вашей базы данных в файлах, которые вы можете легко восстановить; и / или иметь скрипт, который автоматически выгружает вашу производственную базу данных в локальную тестовую базу данных.
Кроме того, всегда не забывайте сохранять изменения схемы в управлении версиями (или как минимум некоторые файлы .sql); облегчает обновление вашей производственной базы данных после того, как вы разработали что-то новое, используя свою тестовую базу данных.
PITR в первую очередь предназначен для горячего резервирования / резервного копирования.