PG闪回插件是中启乘数科技自研的PG数据库插件,通过利用PG底层的一些机制,可以帮助您在出现数据库错误操作后,立刻回滚数据库数据到指定的时间点,快速找回正确的业务数据。
闪回插件介绍
如下图所示,假设有一个SQL在9:58时,因为WHERE条件写错了导致错误的修改了部分业务数据,DBA在10:08分的时候发现了这个问题,这时可以使用闪回插件,将数据库临时闪回到9:58分,找回正确的业务数据。

快速使用
安装插件
CREATE EXTENSION csupg_flashback;
本插件可以不用重启数据库,就可以启动快照的功能,但是此功能需要手工启动后台的工作进程,方法如下:
SELECT csufb_start(12, 300);
上面的命令会启动12个后台工作进程,即12个快照,每个快照间隔300s。
如果我们想数据库启动后自动启动csupg_flashback,则需要把此插件配置到数据库参数shared_preload_libraries中:
max_worker_processes = 256
shared_preload_libraries = 'csupg_flashback'
csupg_flashback.total_workers = 12
csupg_flashback.interval_seconds = 300
注意我们还需要配置max_worker_processes为一个较大的参数,否则可能无法启动csupg_flashback的后台服务进程。 上面还配置了csupg_flashback.total_workers=12,代表启动12个后台服务进程,即12个快照,每个快照的间隔时间由csupg_flashback.interval_seconds指定。
使用快照方式恢复误删除的数据
create table test_fb(id serial primary key, tm timestamptz);
insert into test_fb(tm) values(now());
然后在psql中用\watch 30命令每隔30秒插入一行数据,等上面的插入数据的SQL运行上几分钟,然后结束掉:
postgres=# insert into test_fb(tm) values(now());
INSERT 0 1
postgres=#
postgres=# \watch 30
Wed 10 Jan 2024 02:57:01 PM CST (every 30s)
INSERT 0 1
Wed 10 Jan 2024 02:57:31 PM CST (every 30s)
INSERT 0 1
Wed 10 Jan 2024 02:58:01 PM CST (every 30s)
INSERT 0 1
Wed 10 Jan 2024 02:58:31 PM CST (every 30s)
INSERT 0 1
Wed 10 Jan 2024 02:59:01 PM CST (every 30s)
INSERT 0 1
Wed 10 Jan 2024 02:59:31 PM CST (every 30s)
INSERT 0 1
Wed 10 Jan 2024 03:00:01 PM CST (every 30s)
INSERT 0 1
Wed 10 Jan 2024 03:00:31 PM CST (every 30s)
INSERT 0 1
Wed 10 Jan 2024 03:01:01 PM CST (every 30s)
INSERT 0 1
^C
然后我们模拟误操作,把数据给清理掉:
postgres=# delete from test_fb;
select now();
DELETE 10
now
-------------------------------
2024-01-10 15:01:40.301245+08
(1 row)
postgres=# select * from test_fb;
id | tm
----+----
(0 rows)
用下面的SQL查看快照情况:
postgres=# select * from csufb_show_snapshot;
snap_name | snap_timestamp
---------------------+-------------------------------
00000009-00000007-1 | 2024-01-10 14:56:55.861918+08
00000008-00000007-1 | 2024-01-10 14:57:25.712646+08
00000007-00000007-1 | 2024-01-10 14:57:55.929685+08
00000006-00000007-1 | 2024-01-10 14:58:25.721977+08
00000005-00000007-1 | 2024-01-10 14:58:56.012892+08
00000004-00000007-1 | 2024-01-10 14:59:25.819478+08
00000003-00000007-1 | 2024-01-10 14:59:55.868616+08
00000002-00000007-1 | 2024-01-10 15:00:25.925132+08
0000000E-00000008-1 | 2024-01-10 15:00:55.860658+08
0000000B-00000008-1 | 2024-01-10 15:01:25.876552+08
0000000A-00000008-1 | 2024-01-10 15:01:55.954251+08
0000000D-00000008-1 | 2024-01-10 15:02:26.037894+08
(12 rows)
删除操作是在“2024-01-10 15:01:40.301245+08”做的,这时我们可以回到“0000000B-00000008-1 | 2024-01-10 15:01:25.876552+08”的这个快照:
我们现在切换到删除前的快照点:
postgres=# select * from csufb_gen_snapshot_sql('2024-01-10 15:01:40.301245+08');
csufb_gen_snapshot_sql
----------------------------------------------------
-- flashback to 2024-01-10 15:01:25.876552+08
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT '0000000B-00000008-1';
(3 rows)
把上面SQL在psql钟执行一下:
postgres=# BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SET TRANSACTION SNAPSHOT '0000000B-00000008-1';
BEGIN
SET
执行上面的SQL之后,我们就切换到了删除之前的快照点了,然后再执行查询,可以看到误删除的数据就回来了:
postgres=*# select * from test_fb;
id | tm
----+-------------------------------
75 | 2024-01-10 15:01:01.468669+08
66 | 2024-01-10 14:56:54.754206+08
67 | 2024-01-10 14:57:01.12277+08
68 | 2024-01-10 14:57:31.164265+08
69 | 2024-01-10 14:58:01.207221+08
70 | 2024-01-10 14:58:31.251475+08
71 | 2024-01-10 14:59:01.294713+08
72 | 2024-01-10 14:59:31.336454+08
73 | 2024-01-10 15:00:01.382129+08
74 | 2024-01-10 15:00:31.425634+08
(10 rows)
我们可以把快照点查询的数据恢复到另一张表中:
postgres=*# create table test_fb_2 as select * from test_fb;
SELECT 10




