单机闪回
单机闪回¶
- 支持闪回表的DML、DDL操作。
- 支持库级闪回。
- 支持查询闪回。
配置参数¶
-
track_commit_timestamp
设置为on,开启事务提交时间跟踪,确保可以从事务号得到事务结束的时间。 -
shared_preload_libraries 设置shared_preload_libraries = 'sdtrashcan',加载此功能需要用的库。
-
flashback_mode
设置flashback_mode = 'mod',来保证不涉及删除表文件的事务可以被闪回,不必重启服务,但需要重新加载配置参数。 设置flashback_mode = 'all',来保证所有事务可以被闪回,不必重启服务,但需要重新加载配置参数。 -
autovacuum
控制是否使用autovacuum功能,设置autovacuum = 'off',关闭该功能。
说明
前两个参数需要重启服务才能生效。
闪回单表¶
能够在短时间内恢复错误操作等造成的数据错误问题,恢复错误的 DML、DDL操作,为数据库的数据恢复提供更加便捷的途径。
功能描述:
允许将表中数据恢复到做DML或DDL操作前的某一指定状态。
工作原理:
在 SeaboxSQL中,根据mvcc原理,删除或者更新元组并没有立即删除旧数据,而只是标记为已删除,在vacuum清理之前,这些数据还存在page页中,根据元组可见性,通过闪回查询过去某个时间点或某个事务可见的数据,然后恢复到表中。
指定时间点闪回¶
功能描述:
使用FLASHBACK语句将表闪回至某个过去时间点的状态。
闪回语法:
FLASHBACK TABLE table_name TIMESTAMP expression
示例:
- DML操作
seaboxsql=# create table test(id int,tx text,ts timestamp);
CREATE TABLE
seaboxsql=# insert into test values (1, 'beijing', now());
INSERT 0 1
seaboxsql=# select * from test ;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2023-02-20 15:42:56.256888
(1 row)
seaboxsql=# update test set tx = 'tianjin', ts = now() where id = 1;
UPDATE 1
seaboxsql=# select * from test ;
id | tx | ts
----+---------+----------------------------
1 | tianjin | 2023-02-20 15:43:12.663977
(1 row)
seaboxsql=# update test set tx = 'hebei', ts = now() where id = 1;
UPDATE 1
seaboxsql=# select * from test ;
id | tx | ts
----+-------+----------------------------
1 | hebei | 2023-02-20 15:43:37.055783
(1 row)
- 闪回DML
seaboxsql=# flashback table test timestamp '2023-02-20 15:43:13';
FLASHBACK TABLE
seaboxsql=# select * from test;
id | tx | ts
----+---------+----------------------------
1 | tianjin | 2023-02-20 15:43:12.663977
(1 row)
seaboxsql=# flashback table test timestamp '2023-02-20 15:42:57';
FLASHBACK TABLE
seaboxsql=# select * from test;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2023-02-20 15:42:56.256888
(1 row)
- DDL操作
seaboxsql=# create table test(id int,tx text,ts timestamp);
CREATE TABLE
seaboxsql=# insert into test values (1, 'beijing', now());
INSERT 0 1
seaboxsql=# select * from test;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2023-06-06 11:15:08.210109
(1 row)
seaboxsql=# select * from now();
now
-------------------------------
2023-06-06 11:15:08.212382+08
(1 row)
seaboxsql=# drop table test;
DROP TABLE
- 闪回DDL
seaboxsql=# flashback table test timestamp '2023-06-06 11:15:08.212382';
FLASHBACK TABLE
seaboxsql=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+------+-------+---------------+---------
public | dual | view | zhanghailiang |
public | test | table | zhanghailiang | heap
(2 rows)
seaboxsql=# select * from test;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2023-06-06 11:15:08.210109
(1 row)
指定事务号闪回¶
功能描述:
使用 FLASHBACK 语句将表闪回至某个过去事务号的状态。
闪回语法:
FLASHBACK TABLE table_name XID expression
示例:
- DML操作
seaboxsql=# create table test(id int,tx text,ts timestamp);
CREATE TABLE
seaboxsql=# insert into test values (1, 'beijing', now());
INSERT 0 1
seaboxsql=# select xmin,xmax,* from test;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
1344 | 0 | 1 | beijing | 2023-02-20 16:01:14.504023
(1 row)
seaboxsql=# update test set tx = 'tianjin', ts = now() where id = 1;
UPDATE 1
seaboxsql=# select xmin,xmax,* from test;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
1345 | 0 | 1 | tianjin | 2023-02-20 16:05:19.336343
(1 row)
seaboxsql=# update test set tx = 'hebei', ts = now() where id = 1;
UPDATE 1
seaboxsql=# select xmin,xmax,* from test;
xmin | xmax | id | tx | ts
------+------+----+-------+----------------------------
1346 | 0 | 1 | hebei | 2023-02-20 16:05:32.188188
(1 row)
- 闪回DML
seaboxsql=# flashback table test xid 1345;
FLASHBACK TABLE
seaboxsql=# select xmin,xmax,* from test;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
1347 | 0 | 1 | tianjin | 2023-02-20 16:05:19.336343
(1 row)
seaboxsql=# flashback table test xid 1344;
FLASHBACK TABLE
seaboxsql=#
seaboxsql=# select xmin,xmax,* from test;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
1348 | 0 | 1 | beijing | 2023-02-20 16:01:14.504023
(1 row)
- DDL操作
seaboxsql=# create table test(id int,tx text,ts timestamp);
CREATE TABLE
seaboxsql=# insert into test values (1, 'beijing', now());
INSERT 0 1
seaboxsql=# select xmin, xmax, * from test;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
741 | 0 | 1 | beijing | 2023-06-06 11:19:06.028686
(1 row)
seaboxsql=# drop table test;
DROP TABLE
seaboxsql=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+------+------+---------------+---------
public | dual | view | zhanghailiang |
(1 row)
- 闪回DDL
seaboxsql=# flashback table test xid 741;
FLASHBACK TABLE
seaboxsql=# \d
List of relations
Schema | Name | Type | Owner | Storage
--------+------+-------+---------------+---------
public | dual | view | zhanghailiang |
public | test | table | zhanghailiang | heap
(2 rows)
seaboxsql=# select * from test;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2023-06-06 11:19:06.028686
(1 row)
库级闪回¶
能够在短时间内恢复当前数据库内错误操作等造成的数据错误问题,恢复错误的 DML、DDL操作,为数据库的数据恢复提供更加便捷的途径。
功能描述:
允许将数据库中数据恢复到做DML或DDL操作前的某一指定状态。
工作原理:
在 SeaboxSQL中,根据mvcc原理,删除或者更新元组并没有立即删除旧数据,而只是标记为已删除,在vacuum清理之前,这些数据还存在page页中,根据元组可见性,通过闪回查询过去某个时间点或某个事务可见的数据,然后恢复到表中。
指定时间点闪回¶
功能描述:
使用db_flashback_xid
函数将数据库闪回至某个过去时间点的状态。
闪回语法:
SELECT db_flashback_xid(XID)
示例:
seaboxsql=# create extension if not exists sdtrashcan;
CREATE EXTENSION
seaboxsql=# create table t1(a int);
CREATE TABLE
seaboxsql=# insert into t1 values(1),(2);
INSERT 0 2
seaboxsql=# create table t2(a int);
CREATE TABLE
seaboxsql=# insert into t2 values(1),(2);
INSERT 0 2
seaboxsql=# select txid_current();
txid_current
--------------
745
(1 row)
seaboxsql=# drop table t1;
DROP TABLE
seaboxsql=# drop table t2;
DROP TABLE
seaboxsql=# select db_flashback_xid(745);
db_flashback_xid
---------------------------------------
(745,"2023-08-21 17:29:20.550879+08")
(1 row)
seaboxsql=# select * from t1;
a
---
1
2
(2 rows)
seaboxsql=# select * from t2;
a
---
1
2
(2 rows)
闪回查询¶
闪回查询允许查询过去时间点数据,或过去时间段数据变化。能够在短时间内恢复错误操作等造成的数据错误问题,恢复错误的DML操作,为数据库的数据恢复提供更加便捷的途径。
闪回查询¶
功能描述:
闪回查询允许查询过去时间点数据,或过去时间段数据变化。能够在短时间内恢复错误操作等造成的数据错误问题,恢复错误的DML操作,为数据库的数据恢复提供更加便捷的途径。
工作原理:
在SeaboxSQL中,根据mvcc原理,删除或者更新元组并没有立即删除旧数据,而只是标记为已删除,在vacuum清理之前,这些数据还存在page页中,根据元组可见性,闪回查询过去某个时间点或某个事务可见的数据。
指定时间点闪回查询¶
功能描述:
在SELECT中使用FLASHBACK子句指定过去时间点查询。
闪回语法:
SELECT column_name[, …]
FROM table_name
[FLASHBACK TIMESTAMP expression]
[WHERE condition]
其中, FLASHBACK用于指定闪回查询时查询的时间点。时间为timestamp类型,时间格式为“YYYY-MM-DD HH24:MI:SS”。
示例:
- 事务操作
=> create table test(id int,tx text,ts timestamp);
CREATE TABLE
=> insert into test values (1, 'beijing', now());
INSERT 0 1
=> select xmin,xmax,* from test ;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
550 | 0 | 1 | beijing | 2020-06-15 16:01:35.947974
(1 row)
=> update test set tx = 'tianjin', ts = now() where id = 1;
UPDATE 1
=> select xmin,xmax,* from test ;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
551 | 0 | 1 | tianjin | 2020-06-15 16:01:47.453507
(1 row)
=> update test set tx = 'hebei', ts = now() where id = 1;
UPDATE 1
=> select xmin,xmax,* from test ;
xmin | xmax | id | tx | ts
------+------+----+-------+----------------------------
552 | 0 | 1 | hebei | 2020-06-15 16:01:59.399336
(1 row)
- 闪回查询
=> select * from test flashback timestamp '2020-06-15 16:01:47';
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 16:01:35.947974
(1 row)
=> select * from test flashback timestamp '2020-06-15 16:01:59';
id | tx | ts
----+---------+----------------------------
1 | tianjin | 2020-06-15 16:01:47.453507
(1 row)
指定事务号闪回查询¶
功能描述:
在SELECT中使用FLASHBACK子句指定事务号查询。
闪回语法:
SELECT column_name[, …]
FROM table_name
[FLASHBACK XID expression]
[WHERE condition]
示例:
=> select * from test flashback xid 550;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 16:01:35.947974
(1 row)
=> select * from test flashback xid 551;
id | tx | ts
----+---------+----------------------------
1 | tianjin | 2020-06-15 16:01:47.453507
(1 row)
闪回版本查询¶
功能描述:
闪回版本查询返回在指定时间间隔或事务号间隔内的所有版本。
工作原理:
与闪回查询同理,返回一个时间段内所有的版本。
指定时间点闪回版本查询¶
功能描述:
在 SELECT 中使用 FLASHBACK BETWEEN 子句指定时间点查询。
闪回语法:
SELECT column_name[, …]
FROM table_name
[FLASHBACK BETWEEN
TIMESTAMP expression AND expression]
WHERE condition
=> select * from test flashback between timestamp '2020-06-15 16:01:35' and '2020-06-15 16:02:00' where id = 1;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 16:01:35.947974
1 | tianjin | 2020-06-15 16:01:47.453507
1 | hebei | 2020-06-15 16:01:59.399336
(3 rows)
=> select * from test flashback between timestamp '2020-06-15 16:01:35' and '2020-06-15 16:01:59' where id = 1;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 16:01:35.947974
1 | tianjin | 2020-06-15 16:01:47.453507
(2 rows)
指定事务号闪回版本查询¶
功能描述:
在SELECT中使用FLASHBACK BETWEEN子句指定事务号查询。
闪回语法:
SELECT column_name[, …]
FROM table_name
[FLASHBACK BETWEEN
XID expression AND expression]
WHERE condition
-
FLASHBACK BETWEEN 用于指定闪回版本查询时查询的事务号段。
-
示例 1
=> select * from test flashback between xid 550 and 552 where id = 1;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 16:01:35.947974
1 | tianjin | 2020-06-15 16:01:47.453507
1 | hebei | 2020-06-15 16:01:59.399336
(3 rows)
=> select * from test flashback between xid 550 and 551 where id = 1;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 16:01:35.947974
1 | tianjin | 2020-06-15 16:01:47.453507
(2 rows)
在同一个事务中对一行更新多次,只显示最后一次提交的版本。
=> create table test(id int,tx text,ts timestamp);
CREATE TABLE
=> insert into test values (1, 'beijing', now());
INSERT 0 1
=> select xmin,xmax,* from test ;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
555 | 0 | 1 | beijing | 2020-06-15 16:38:42.170305
(1 row)
=> begin;
BEGIN
=> update test set tx = 'tianjin' where id = 1;
UPDATE 1
=> update test set tx = 'hebei' where id = 1;
UPDATE 1
=> commit;
COMMIT
=> select xmin,xmax,* from test ;
xmin | xmax | id | tx | ts
------+------+----+-------+----------------------------
556 | 0 | 1 | hebei | 2020-06-15 16:38:42.170305
(1 row)
=> select xmin,xmax,* from test flashback between timestamp '2020-06-15 16:38:42' and '2020-06-15 16:40:42';
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
555 | 556 | 1 | beijing | 2020-06-15 16:38:42.170305
556 | 0 | 1 | hebei | 2020-06-15 16:38:42.170305
(2 rows)
通过闪回查询进行数据恢复¶
闪回查询可以支持数据恢复,将数据恢复到过去某个时刻的状态。
示例 1
在更新时,未指定where条件,导致全表更新,闪回查询过去时间点的数据放到临时表,从临时表恢复原数据或者重命名表。
=> select xmin,xmax,* from test ;
xmin | xmax | id | tx | ts
------+------+----+---------+----------------------------
559 | 0 | 1 | beijing | 2020-06-15 17:19:35.540812
560 | 0 | 2 | tianjin | 2020-06-15 17:19:35.542743
561 | 0 | 3 | hebei | 2020-06-15 17:19:35.544101
(3 rows)
=> update test set tx = 'shanghai';
UPDATE 3
=> select * from test;
id | tx | ts
----+----------+----------------------------
1 | shanghai | 2020-06-15 17:19:35.540812
2 | shanghai | 2020-06-15 17:19:35.542743
3 | shanghai | 2020-06-15 17:19:35.544101
(3 rows)
=> select * from test flashback timestamp '2020-06-15 17:19:36';
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 17:19:35.540812
2 | tianjin | 2020-06-15 17:19:35.542743
3 | hebei | 2020-06-15 17:19:35.544101
(3 rows)
=> create table test_tmp as select * from test flashback timestamp '2020-06-15 17:19:36';
SELECT 3
=> select * from test_tmp;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 17:19:35.540812
2 | tianjin | 2020-06-15 17:19:35.542743
3 | hebei | 2020-06-15 17:19:35.544101
(3 rows)
=> update test as a set tx = (select b.tx from test_tmp as b where a.id = b.id);
UPDATE 3
=> select * from test;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 17:19:35.540812
2 | tianjin | 2020-06-15 17:19:35.542743
3 | hebei | 2020-06-15 17:19:35.544101
(3 rows)
# 重命名表名
=> alter table test_tmp rename to test;
ALTER TABLE
=> select * from test;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 17:19:35.540812
2 | tianjin | 2020-06-15 17:19:35.542743
3 | hebei | 2020-06-15 17:19:35.544101
(3 rows)
示例 2
使用UPDATE … (SELECT … FLASHBACK …)恢复数据。
=> update test set tx = (select tx from test flashback timestamp '2020-06-15 17:19:36' where id =1) where id = 1;
UPDATE 1
=> update test set tx = (select tx from test flashback timestamp '2020-06-15 17:19:36' where id =2) where id = 2;
UPDATE 1
=> update test set tx = (select tx from test flashback timestamp '2020-06-15 17:19:36' where id =3) where id = 3;
UPDATE 1
=> select * from test;
id | tx | ts
----+---------+----------------------------
1 | beijing | 2020-06-15 17:19:35.540812
2 | tianjin | 2020-06-15 17:19:35.542743
3 | hebei | 2020-06-15 17:19:35.544101
(3 rows)
注意事项¶
目前闪回查询功能只能对DML(insert、 update 和 delete)操作进行闪回查询,对于DDL truncate对表的操作,目前闪回查询还不支持。除此之外,闪回查询也不支持表结构做出的修改操作。