暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

乘数科技生态 | PG闪回插件,快速找回历史数据

中启乘数 2024-02-26
570

PG闪回插件是中启乘数科技自研的PG数据库插件,通过利用PG底层的一些机制,可以帮助您在出现数据库错误操作后,立刻回滚数据库数据到指定的时间点,快速找回正确的业务数据。

闪回插件介绍

如下图所示,假设有一个SQL在9:58时,因为WHERE条件写错了导致错误的修改了部分业务数据,DBA在10:08分的时候发现了这个问题,这时可以使用闪回插件,将数据库临时闪回到9:58分,找回正确的业务数据。

快速使用

安装插件

CREATE EXTENSION csupg_flashback;

本插件可以不用重启数据库,就可以启动快照的功能,但是此功能需要手工启动后台的工作进程,方法如下:

SELECT csufb_start(12300);

上面的命令会启动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


文章转载自中启乘数,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论