Primeiro de tudo, não faça isso em seu banco de dados de produção.
O caminho certo (tm) é usar transações para o que eles valem. Em postgres você pode até mesmo ninho los usando pontos de salvamento (que você pode fazer um rollback a).
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 IGNORE 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
Se isso não atender (devido a limitações de software ou outros motivos), você pode sempre manter vários depósitos de seu banco de dados em arquivos que você pode facilmente restaurar; e / ou ter um script que despeja automaticamente seu banco de dados de produção em um banco de dados de teste local.
Além disso, lembre-se sempre para manter as alterações de esquema no controle de versão (ou um mínimo de alguns arquivos .sql); faz com que seja fácil de atualizar seu banco de dados de produção depois de ter desenvolvido algo novo usando seu banco de dados de teste.
PITR é destinado principalmente para fins de espera / de backup quentes.