闪回查询
闪回查询可以查询过去某个时间点表的某个snapshot数据,这一特性可用于查看和逻辑重建意外删除或更改的受损数据。
方案一:基于TIMECAPSULE语法的闪回查询
功能描述
通过TIMECAPSULE语法进行闪回查询,可以获取指定时间戳或CSN的旧版本数据。
注意事项
使用闪回查询功能需要配置GUC参数undo_retention_time,用于设置undo旧版本的保留时间。
该参数属于SIGHUP类型参数,请参考重设参数表1中对应设置方法进行设置。
此功能暂不支持ASTORE引擎。因此需要在建表时指定存储方式为USTORE,或者设置GUC参数enable_default_ustore_table为on,此时创建的所有表默认使用USTORE存储引擎。
不支持闪回表的对象类型:系统表、列存表、内存表、DFS表、全局临时表、本地临时表、UNLOGGED表、序列表、hashbucket表。
闪回点和当前点之间,执行过修改表结构或影响物理存储的语句(DDL、DCL、VACUUM FULL),闪回失败。
语法格式
{[ ONLY ] table_name [ * ] [ partition_clause ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
[ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ]
[TIMECAPSULE { TIMESTAMP | CSN } expression ]
|( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
|with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
|function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]
|function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
|from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]}
闪回查询的用法例如:
指定闪回查询的时间戳:
SELECT * FROM table1 TIMECAPSULE TIMESTAMP to_timestamp ('2020-02-11 10:13:22.724718', 'YYYY-MM-DD HH24:MI:SS.FF');
指定闪回查询的CSN号。
SELECT * FROM table1 TIMECAPSULE CSN 9617;
指定闪回查询的时间戳,并给表起一个临时表别名:
SELECT * FROM table1 AS t TIMECAPSULE TIMESTAMP to_timestamp ('2020-02-11 10:13:22.724718', 'YYYY-MM-DD HH24:MI:SS.FF');
指定闪回查询的CSN号,并给表起一个临时表别名:
SELECT * FROM table1 AS t TIMECAPSULE CSN 9617;
参数说明
TIMESTAMP
指要查询某个表在TIMESTAMP这个时间点上的数据,TIMESTAMP指一个具体的历史时间。
CSN
指要查询整个数据库逻辑提交序下某个CSN点的数据,CSN指一个具体逻辑提交时间点,数据库中的CSN为写一致性点,每个CSN代表整个数据库的一个一致性点,查询某个CSN下的数据代表SQL查询数据库在该一致性点的相关数据。
[AS] alias
给表或复杂的表引用起一个临时的表别名,以便被其余的查询引用。别名用于缩写或者在自连接中消除歧义。如果提供了别名,它就会完全隐藏表的实际名。
以上参数为闪回查询时的常用参数说明,其余未解释的参数说明请参考SELECT语法。
示例
1、设置undo_retention_time为600秒。
alter system set undo_retention_time to 600;
2、查看修改是否生效。
show undo_retention_time;
如下返回结果表示设置生效:
undo_retention_time
---------------------
600s
(1 row)
3、创建USTORE测试表并插入两条数据。
create table table2(name int) with(STORAGE_TYPE=USTORE);
insert into table2 values(1);
insert into table2 values(2);
4、记录当前时间戳。
select current_timestamp;
返回结果为:
pg_systimestamp
-------------------------------
2023-04-04 16:33:41.183125+08
(1 row)
5、再次插入一条数据。
insert into table2 values(3);
6、查看当前测试表的数据:
select * from table2;
返回结果如下,共有3条数据:
name
------
1
2
3
(3 rows)
7、根据步骤4查看到的时间戳进行闪回查询,查看当时的旧版本数据库信息。
SELECT * FROM table2 TIMECAPSULE TIMESTAMP to_timestamp ('2023-04-19 18:02:17.754955', 'YYYY-MM-DD HH24:MI:SS.FF');
返回结果如下,表示查询结果为步骤5的插入数据之前的表信息。
name
------
1
2
(2 rows)
方案二:基于flashback函数的闪回查询
功能描述
通过FLASHBACK函数进行闪回查询,可以看到修改表数据前或者删除数据前的数据装填,支持闪回查询到不超过max_flashback_time时长以内的表数据。
注意事项
不支持带where条件的闪回查询。
使用闪回查询功能时建议关闭autovacuum功能,确保闪回时间点的数据没有被autovacuum清理。
此方案下数据表truncate后无法闪回。
语法格式
SELECT select_list FROM table_name FLASHBACK(n);
参数说明
select_list
在 select 语句中所要包含的列。
table_name
指定需要进行闪回查询的表名。
n
闪回查询的时长,单位为s(秒)。
例如FLASHBACK(15)表示闪回查询15秒之前的表数据。
示例
1、设置max_flashback_time为180秒。
alter system set max_flashback_time to 180;
2、查看修改是否生效:
show max_flashback_time;
如下返回结果表示设置成功:
max_flashback_time
--------------------
180
(1 row)
3、检查是否开启了事务自动提交。
\echo :AUTOCOMMIT
返回结果为on,表示启用了自动提交,此为默认值。若未启用自动提交,可使用\set AUTOCOMMIT on
命令开启。
4、创建测试表并插入一条数据。
create table table_2 (col1 int, col2 char(20),col3 char(20));
insert into table_2 values(1,'aa','a1');
5、休眠等待10秒。
select pg_sleep(10);
6、为表格插入第二条数据,随后闪回查询插入这条数据之前的情况。
执行以下两条SQL时需要注意连贯性,避免因间隔时间过长导致闪回查询的结果与示例不符。
insert into table_2 values(2,'bb','b1');
select * from table_2 FLASHBACK(8);
返回结果如下,表示闪回查询到了表table_2未插入第二条数据之前的旧版本。
col1 | col2 | col3
------+----------------------+----------------------
1 | aa | a1
(1 row)