3.1 闪回查询
瀚高数据库从企业版V5.6.1开始增加了闪回查询(HG_FBQ)功能(瀚高专利),但安全版V4并不支持,安全版V4.5.1开始全面支持。本章节对本功能进行详细说明以及如何去操作。
3.1.1 介绍
闪回查询功能基于MVCC机制,可以用于恢复或者查询已提交删除或者更新的数据。数据恢复方法基于数据闪回查询方法,将返回的数据作为恢复数据。
总体架构图:
使用场景:
- 数据丢失、错误操作等小问题;
- 常规使用备份恢复、低效耗时、需要停服务中断业务。针对一些小错误的修改大材小用,且增加修正的复杂度,所以此类恢复需要使用闪回查询;
- 使用闪回查询恢复迅速,不需要停机(前提是参数配置已经生效);
- 闪回查询还可以查看数据在特定时间区间不同的版本差异,防范人为的数据误操作。
3.1.2 参数配置
涉及到闪回功能,在postgresql.conf中一共有3个参数:
- track_commit_timestamp:
启用闪回功能需要设置为on(默认是off),以开启事务提交时间跟踪,确保可以从事务号得到事务结束的时间。需要重启数据库才能使变更生效。
- HG_FBQ_RETENTION:
闪回查询数据保存时间,单位为秒(s),默认是0(没有闪回查询功能),建议最大值不要超过432000(5天)。
系统当前时间之前保留的时间值,如设置为30,即保存当前时间之前30秒的数据,此参数设置后,该时间范围内的数据不允许进行autovacuum操作,但允许手工vacuum清理。
- HG_FBQ_GUARANTEE:
开启闪回查询后,是否保证HG_FBQ_RETENTION参数设置内的数据可以闪回查询到。默认为off,即不允许autovacuum清理该参数时间范围内的数据,但不限制手工vacuum操作。
HG_FBQ_RETENTION大于0时,此参数才会生效。
配置实例:
使用数据库管理员执行:
ALTER SYSTEM SET track_commit_timestamp = on;
ALTER SYSTEM SET hg_fbq_retention = '43200s';
ALTER SYSTEM SET hg_fbq_guarantee = off;
说明:瀚高企业版数据库管理员为highgo,瀚高安全版数据库管理员为sysdba。
需要重启数据库。如果是后面两个参数则不需要,执行select pg_reload_conf();即可。
3.1.3 创建测试实例
创建用户、数据库、模式:
create user test password 'Hello@1234';
create database testdb with owner=test template=template0 encoding=utf8 connection limit=100;
\c testdb
create schema test authorization test;
\c testdb test
创建表对象,插入数据库:
CREATE TABLE EMPLOYEES (
emp_no INT NOT NULL , /*员工编号*/
emp_name VARCHAR(60) NOT NULL , /*姓名*/
gender VARCHAR(10) NOT NULL , /*性别*/
birth_date VARCHAR(10) NOT NULL , /*生日*/
hire_date VARCHAR(10) NOT NULL , /*入职时间*/
PRIMARY KEY (emp_no)
);
INSERT INTO EMPLOYEES VALUES (10001,'刘亦菲','女','1953-09-02','1986-06-26');
INSERT INTO EMPLOYEES VALUES (10002,'房祖名','男','1953-09-02','1985-11-21');
INSERT INTO EMPLOYEES VALUES (10003,'郭雪芙','女','1953-09-02','1986-08-28');
INSERT INTO EMPLOYEES VALUES (10004,'陈晓','女','1953-09-02','1986-12-01');
INSERT INTO EMPLOYEES VALUES (10005,'黄子韬','女','1953-09-02','1989-09-12');
INSERT INTO EMPLOYEES VALUES (10006,'肖战','男','1953-09-02','1989-06-02');
INSERT INTO EMPLOYEES VALUES (10007,'蔡徐坤','男','1953-09-02','1989-02-10');
INSERT INTO EMPLOYEES VALUES (10008,'杨幂','女','1953-09-02','1994-09-15');
INSERT INTO EMPLOYEES VALUES (10009,'陈伟霆','男','1953-09-02','1985-02-18');
INSERT INTO EMPLOYEES VALUES (10010,'邓紫棋','男','1953-09-02','1989-08-24');
3.1.4 语法结构
可以根据时间点、事务号去查询某个点的数据。
- 指定时间点的查询语法:
SELECT column_name[ , … ] FROM table_name
[ FLASHBACK TIMESTAMP expression ]
[ WHERE condition ];
- 指定事务号的查询语法:
SELECT column_name[ , … ] FROM table_name
[ FLASHBACK XID expression ]
[ WHERE condition ];
还可以根据时间段、事务号段去查询某个范围的数据。
- 指定时间段的查询语法:
SELECT column_name[ , … ] FROM table_name
[ FLASHBACK BETWEEN TIMESTAMP expression1 AND expression2 ]
[ WHERE condition ];
- 指定事务号段的查询语法:
SELECT column_name[ , … ] FROM table_name
[ FLASHBACK BETWEEN XID expression1 AND expression2 ]
[ WHERE condition ];
3.1.5 最佳实践
我们要查看一个历史版本的数据,但我们未必知道确切的事务ID或对应的时间戳。可以估算出大概的时间,根据时间段来查出所有的数据行版本(我们设定的是12小时内的数据),如:
testdb=> select xmin, xmax, * from employees FLASHBACK BETWEEN TIMESTAMP '2021-01-23 21:00:00' AND '2021-01-24 00:05:00';
xmin | xmax | emp_no | emp_name | gender | birth_date | hire_date
------+------+--------+----------+--------+------------+------------
502 | 0 | 10009 | 陈伟霆 | 男 | 1953-09-02 | 1985-02-18
503 | 0 | 10010 | 邓紫棋 | 男 | 1953-09-02 | 1989-08-24
505 | 506 | 10007 | 蔡徐坤 | 男 | 2000-01-02 | 1989-02-10
506 | 507 | 10007 | 蔡徐坤 | 男 | 2000-01-02 | 1989-02-10
507 | 508 | 10007 | 蔡徐坤 | 男 | 2000-12-25 | 1989-02-10
508 | 0 | 10007 | 蔡徐坤 | 男 | 1975-01-01 | 1989-02-10
可以看到10007有多个版本的数据行,如果右边范围的时间选择的是最新的事务时间,xmin最大的那个就是当前的行(xmax只是当前行执行的最后一个事务ID,无论该事务是否成功。)
如果我们要使用xmin为506的那个版本的数据,则执行以下语句:
testdb=> select xmin, xmax, * from employees FLASHBACK xid 506 where emp_no='10007';
xmin | xmax | emp_no | emp_name | gender | birth_date | hire_date
------+------+--------+----------+--------+------------+------------
506 | 507 | 10007 | 蔡徐坤 | 男 | 2000-01-02 | 1989-02-10
(1 row)
可以得想要的数据行版本,并进行下一步的操作,如:恢复数据。
目前闪回查询功能只能对DML(insert、update 和delete)操作进行闪回查询,对于DDL 及truncate 对表的操作,目前闪回查询还不支持。除此之外,闪回查询也不支持表结构做出的修改操作。