一、闪回介绍
闪回恢复功能是数据库恢复技术的一环,可以有选择性的撤销一个已提交事务的影响,将数据从人为不正确的操作中进行恢复。在采用闪回技术之前,只能通过备份恢复、PITR 等手段找回已提交的数据库修改,恢复时长需要数分钟甚至数小时。采用闪回技术后,恢复已提交的数据库修改前的数据,只需要秒级,而且恢复时间和数据库大小无关。
闪回恢复适用场景:
1、误删除表的场景
2、需要将表中的数据恢复到指定时间点或者 CSN(commit sequence number)。
闪回支持两种恢复模式:
1、基于 MVCC 多版本的数据恢复
适用于误删除、误更新、误插入数据的查询和恢复。用户可以通过配置旧版本保留时间,并执行相关命令,进行闪回表操作,或者进行闪回查询。
2、基于回收站的恢复
适用于误 DROP、误 TRUNCATE 的表的恢复。用户通过配置回收站开关,并执行相应的恢复命令,可以将误 DROP、误 TRUNCATE的表找回。
二、闪回类型
主要包括闪回表、闪回查询、闪回drop/truncate
(一)闪回表
闪回表基于 MVCC 多版本机制,通过删除指定时间点和该时间点之后的增量数据,
并找回指定时间点和当前时间点删除的数据,实现表级数据还原。
(1)基于timecapsule语法的闪回表
注意事项:
1、需要配置 GUC 参数 undo_retention_time,用于设置 undo旧版本的保留时间。该参数属于 SIGHUP 类型参数。
2、此功能暂不支持 ASTORE 引擎。因此需要在建表时指定存储方式为 USTORE,或者设置 GUC 参数 enable_default_ustore_table 为 on,此时创建的所有表默认使用 USTORE 存储引擎。
3、不支持闪回表的对象类型:系统表、列存表、内存表、DFS 表、全局临时表、本地临时表、unlogged 表、序列表、cmhbucket 表。
4、闪回点和当前点之间,如果执行过修改表结构或影响物理存储的语句(DDL、DCL、VACUUM FULL),将导致闪回失败。
语法格式
闪回表至指定的时间戳:
TIMECAPSULE TABLE table1 TO TIMESTAMP to_timestamp (‘2024-02-22 14:34:33’,‘YYYY-MM-DD HH24:MI:SS’) ;
闪回表至指定的csn:
TIMECAPSULE TABLE table1 TO CSN <CSN号>;
举例说明
下面通过指定时间戳进行闪回表:
1、数据库设置undo_retention_time参数
postgres=# show undo_retention_time;
undo_retention_time
---------------------
0
(1 row)
[panweidb@node1 ~]$gs_guc reload -N all -I all -c “undo_retention_time=1800”
postgres=# show undo_retention_time;
undo_retention_time
---------------------
30min
(1 row)
2、创建表并插入数据
postgres=# create table test(id int,name varchar(20)) with (storage_type=ustore);
CREATE TABLE
postgres=# \d+ test
Table “public.test”
Column | Type | Modifiers | Storage | Stats target | Description | Attalias
--------±------------±----------±---------±-------------±------------±---------
id | integer | | plain | | | id
name | varchar(20) | | extended | | | name
Has OIDs: no
Options: orientation=row, storage_type=ustore, fillfactor=80, compression=no
postgres=#
postgres=# insert into test values(1,‘zhang’),(2,‘li’),(3,‘wang’),(4,‘zhao’),(5,‘hu’);
INSERT 0 5
3、记录当时的时间
postgres=# select current_timestamp;
pg_systimestamp
-------------------------------
2024-02-22 22:56:35.799047+08
(1 row)
4、删除数据
postgres=# delete from test where id=3 ;
DELETE 1
postgres=# select * from test;
id | name
----±------
1 | zhang
2 | li
4 | zhao
5 | hu
(4 rows)
5、通过timestamp闪回表
postgres=# TIMECAPSULE TABLE test TO TIMESTAMP to_timestamp (‘2024-02-22 22:56:35.799047’,‘YYYY-MM-DD HH24:MI:SS.FF’) ;
TimeCapsule Table
postgres=# select * from test;
id | name
----±------
1 | zhang
2 | li
4 | zhao
5 | hu
3 | wang
(5 rows)
(2)基于pg_flashback函数的闪回表
使用基于 pg_flashback 函数的闪回表,可以将表闪回到不超过
max_flashback_time 时长以内的旧版本。
注意事项:
1、设置max_flashback_time参数,用于控制闪回功能支持的最大时长,该参数属于 SIGHUP 类型参数,单位为秒(s)。
2、不支持连续闪回。
3、 使用闪回查询功能时建议关闭 autovacuum 功能,确保闪回时间点的数据没
有被 autovacuum 清理。
4、此方案下数据表 truncate 后无法闪回。
语法格式
将表闪回至n秒之前的状态。
SELECT PG_FLASHBACK(‘table_name’,n);
n是闪回表的时长,单位为 s(秒)。
举例说明
下面通过pg_flashback函数进行闪回查询:
1、数据库设置max_flashback_time参数
postgres=# show max_flashback_time;
max_flashback_time
--------------------
0
(1 row)
[panweidb@node1 ~]$gs_guc reload -N all -I all -c “max_flashback_time=3600”
postgres=# show max_flashback_time;
max_flashback_time
--------------------
3600
(1 row)
2、创建表并插入数据
postgres=# create table test6(id int,name varchar(20));
CREATE TABLE
postgres=# \d+ test6
Table “public.test6”
Column | Type | Modifiers | Storage | Stats target | Description | Attalias
--------±------------±----------±---------±-------------±------------±---------
id | integer | | plain | | | id
name | varchar(20) | | extended | | | name
Has OIDs: no
Options: orientation=row, compression=no, fillfactor=80
postgres=# insert into test6 values(1,‘zhang’);
INSERT 0 1
3、休眠20s
postgres=# select pg_sleep(20);
4、再次插入数据
postgres=# insert into test6 values(2,‘li’);
INSERT 0 1
5、将表闪回到15s前
postgres=# SELECT PG_FLASHBACK(‘test6’,15);
pg_flashback
--------------
(1 row)
6、查看闪回表结果
postgres=# select * from test6;
id | name
----±------
1 | zhang
(1 row)
(二)闪回查询
闪回查询基于MVCC多版本机制,通过检索查询旧版本,获取指定老版本数据。闪回查询可以查询过去某个时间点表的某个snapshot数据,这一特性用于查看意外删除或更改的受损数据。
注意:数据库表存储引擎类型,修改后不支持修改。
存储引擎类型取值范围:
USTORE,表示表支持Inplace-Update存储引擎。
ASTORE,表示表支持Append-only存储引擎。
不指定时,默认是Append-only存储。
(1)基于timecapsule语法的闪回查询(只支持ustore表)
注意事项:
1、需要配置 GUC 参数 undo_retention_time,用于设置 undo旧版本的保留时间。
2、此功能暂不支持 ASTORE 引擎。因此需要在建表时指定存储方式为 USTORE,或者设置 GUC 参数 enable_default_ustore_table 为 on,此时创建的所有表默认使用 USTORE 存储引擎。
3、不支持闪回表的对象类型:系统表、列存表、内存表、DFS 表、全局临时表、本地临时表、unlogged 表、序列表、cmhbucket 表。
4、闪回点和当前点之间,如果执行过修改表结构或影响物理存储的语句(DDL、DCL、VACUUM FULL),将导致闪回失败。
语法格式
指定闪回查询的时间戳
SELECT * FROM table1 timecapsule timestamp to_timestamp(‘2024-02-22 14:34:33’,‘YYYY-MM-DD HH24:MI:SS’) ;
指定闪回查询的 CSN 号
SELECT * FROM table1 TIMECAPSULE CSN <CSN号>;
指定闪回查询的时间戳,并给表起一个临时表别名
SELECT * FROM table1 as t timecapsule timestamp to_timestamp(‘2024-02-22 14:34:33’,‘YYYY-MM-DD HH24:MI:SS’) ;
指定闪回查询的 CSN 号,并给表起一个临时表别名
SELECT * FROM table1 TIMECAPSULE CSN <CSN号>;
举例说明
下面通过指定闪时间戳进行闪回查询:
1、数据库设置undo_retention_time参数
postgres=# show undo_retention_time;
undo_retention_time
---------------------
0
(1 row)
[panweidb@node1 ~]$gs_guc reload -N all -I all -c “undo_retention_time=1800”
postgres=# show undo_retention_time;
undo_retention_time
---------------------
30min
(1 row)
2、创建表并插入数据
postgres=# create table test(id int,name varchar(20)) with (storage_type=ustore);
CREATE TABLE
postgres=# \d+ test
Table “public.test”
Column | Type | Modifiers | Storage | Stats target | Description | Attalias
--------±------------±----------±---------±-------------±------------±---------
id | integer | | plain | | | id
name | varchar(20) | | extended | | | name
Has OIDs: no
Options: orientation=row, storage_type=ustore, fillfactor=80, compression=no
postgres=#
postgres=# insert into test values(1,‘zhang’),(2,‘li’),(3,‘wang’),(4,‘zhao’),(5,‘hu’);
INSERT 0 5
3、记录当时的时间
postgres=# select now();
now
-------------------------------
2024-02-22 14:34:33.729139+08
(1 row)
4、删除数据
postgres=# delete from test where id=3 ;
DELETE 1
postgres=# select * from test;
id | name
----±------
1 | zhang
2 | li
4 | zhao
5 | hu
(4 rows)
5、通过timestamp查询误删数据
postgres=# select * from test timecapsule timestamp to_timestamp(‘2024-02-22 14:34:33’,‘YYYY-MM-DD HH24:MI:SS’) ;
id | name
----±------
1 | zhang
2 | li
3 | wang
4 | zhao
5 | hu
(5 rows)
也支持通过csn可以查看删除数据
select * from t1 timecapsule csn 10248;
(2)基于flashback函数的闪回查询(支持astore表)
注意事项:
1、不支持带 where 条件的闪回查询。
2、使用闪回查询功能时建议关闭 autovacuum 功能,确保闪回时间点的数据没有被 autovacuum 清理。
3、设置max_flashback_time参数,控制闪回功能支持的最大时长,单位为秒
4、此方案下数据表 truncate 后无法闪回。
语法格式
SELECT select_list FROM table_name FLASHBACK(n);
举例说明
下面通过flashback函数进行闪回查询:
1、数据库设置max_flashback_time参数
postgres=# show max_flashback_time;
max_flashback_time
--------------------
0
(1 row)
[panweidb@node1 ~]$gs_guc reload -N all -I all -c “max_flashback_time=3600”
postgres=# show max_flashback_time;
max_flashback_time
--------------------
3600
(1 row)
2、创建表并插入数据
postgres=# create table test2(id int,name varchar(20));
CREATE TABLE
postgres=# \d+ test2
Table “public.test2”
Column | Type | Modifiers | Storage | Stats target | Description | Attalias
--------±------------±----------±---------±-------------±------------±---------
id | integer | | plain | | | id
name | varchar(20) | | extended | | | name
Has OIDs: no
Options: orientation=row, compression=no, fillfactor=80
postgres=# insert into test2 values(1,‘zhang’);
INSERT 0 1
3、休眠20s
postgres=# select pg_sleep(20);
4、再次插入数据
postgres=# insert into test2 values(2,‘li’);
INSERT 0 1
5、通过flashback函数查询15s以前的数据
postgres=# select * from test2 FLASHBACK(15);
id | name
----±------
1 | zhang
(1 row)
(三)闪回drop/truncate
(1)闪回drop
可以恢复意外删除的表,从回收站(recyclebin)中恢复被删除的表及其附属结构如索引、表约束等。闪回drop是基于回收站机制,通过还原回收站中记录的表的物理文件,实现已drop的表的恢复。
(2)闪回truncate
可以恢复误操作或意外被truncate的表,从回收站中恢复被truncate的表及索引的物理数据。闪回truncate基于回收站机制,通过还原回收站中记录的表的物理文件,实现已trunacate表的恢复。
注意事项
1、闪回 drop/truncate 暂不支持 USTORE。
2、GUC 参数 enable_recyclebin 需设置为 on,表示启用回收站。
3、GUC 参数 recyclebin_retention_time 用于设置回收站对象保留时间,超过该时间的回收站对象将被自动清理;单位为秒(s)。
语法格式
从回收站中恢复被 DROP 的表
{ TIMECAPSULE | FLASHBACK } TABLE { table_name } TO BEFORE DROP [RENAME TO new_tablename]
从回收站中恢复被 TRUNCATE 的表
{ TIMECAPSULE | FLASHBACK } TABLE { table_name } TO BEFORE TRUNCATE
举例说明
检查并设置数据库参数
postgres=# show enable_recyclebin;
enable_recyclebinoff
(1 row)
postgres=# show recyclebin_retention_time;
recyclebin_retention_time15min
(1 row)
[panweidb@node1 ~]gs_guc reload -N all -I all -c “enable_recyclebin=on”
[panweidb@node1 ~]gs_guc reload -N all -I all -c “recyclebin_retention_time=3600”
postgres=# show enable_recyclebin;
enable_recyclebinon
(1 row)
postgres=# show recyclebin_retention_time;
recyclebin_retention_time1h
(1 row)
闪回drop表:
1. 建表
create table test3(id int ,name varchar);
2.插入数据
insert into test3 values(1,‘a’),(2,‘b’);
3.删除表
drop table test3;
4.通过回收站闪回drop表
timecapsule table test3 to before drop;
5.查询表
select * from test3;
闪回Truncate表数据:
1.建表
create table test4(id int ,name varchar);
2.插入数据
insert into test4 values(1,‘a’),(2,‘b’);
3.truncate表
Truncate table test4;
4.通过回收站闪回truncate表
timecapsule table test4 to before truncate;
5.查询表
select * from test4;




