达梦DM8之闪回功能测试
当用户操作不慎导致错误的删改数据时,非常希望有一种简单快捷的方式可以恢复数据。闪回技术,就是为了用户可以迅速处理这种数据逻辑损坏的情况而产生的。
闪回技术主要是通过回滚段存储的 UNDO 记录来完成历史记录的还原。设置ENABLE_FLASHBACK 为 1 后,开启闪回功能。DM 会保留回滚段一段时间,回滚段保留的时间代表着可以闪回的时间长度。由 UNDO_RETENTION 参数指定。
开启闪回功能后,DM 会在内存中记录下每个事务的起始时间和提交时间。通过用户指定的时刻,查询到该时刻的事务号,结合当前记录和回滚段中的 UNDO 记录,就可以还原出特定事务号的记录。即指定时刻的记录状态。从而完成闪回查询。闪回查询功能完全依赖于回滚段管理,对于 DROP 等误操作不能恢复。
闪回特性可应用在以下方面:
1. 自我维护过程中的修复:当一些重要的记录被意外删除,用户可以向后移动到一个时间点,查看丢失的行并把它们重新插入现在的表内恢复;
2. 用于分析数据变化:可以对同一张表的不同闪回时刻进行链接查询,以此查看变化的数据。
注意:闪回功能适用于DML误操作回退使用,不适用于drop,truncate等DDL操作。切记在生产环境慎用drop,truncate等危险命令。
1. 检查闪回是否开启
查询闪回功能状态,数据库默认关闭(0-关闭,1-打开)。示例语句如下所示:
SQL> select para_name,para_value,default_value,para_type from v$dm_ini where para_name like '%FLASHBACK%';
行号 PARA_NAME PARA_VALUE DEFAULT_VALUE PARA_TYPE
---------- ---------------- ---------- ------------- ---------
1 ENABLE_FLASHBACK 0 0 SYS
已用时间: 3.806(毫秒). 执行号:702.
SQL>
2. 开启数据库闪回功能
SQL> SP_SET_PARA_VALUE (1, 'ENABLE_FLASHBACK', 1);
DMSQL 过程已成功完成
已用时间: 3.869(毫秒). 执行号:704.
-- 检查闪回功能是否开启
SQL> select para_name,para_value,default_value,para_type from v$dm_ini where para_name like '%FLASHBACK%';
行号 PARA_NAME PARA_VALUE DEFAULT_VALUE PARA_TYPE
---------- ---------------- ---------- ------------- ---------
1 ENABLE_FLASHBACK 1 0 SYS
已用时间: 2.676(毫秒). 执行号:705.
或
SQL> SELECT SF_GET_PARA_VALUE (1, 'ENABLE_FLASHBACK') in_file,
SF_GET_PARA_VALUE (2, 'ENABLE_FLASHBACK') in_mem;2
行号 IN_FILE IN_MEM
---------- -------------------- --------------------
1 1 1
已用时间: 3.265(毫秒). 执行号:706.
SQL>
3. 查看回滚段记录保存时间
由于回滚段会自动清理,所以需要延长回滚记录的保留时间,单位是秒。回滚段参数太大容易引发回滚段膨胀,需要合理的规划和设置。
SQL> select para_name,para_value,default_value,para_type from v$dm_ini where para_name like '%UNDO_RETENTION%';
行号 PARA_NAME PARA_VALUE DEFAULT_VALUE PARA_TYPE
---------- -------------- ---------- ------------- ---------
1 UNDO_RETENTION 90.000000 90.000000 SYS
已用时间: 2.836(毫秒). 执行号:707.
SQL>
-- 这里设置为 1200s。示例语句如下所示:
SQL> SP_SET_PARA_DOUBLE_VALUE (1, 'UNDO_RETENTION', 1200);
DMSQL 过程已成功完成
已用时间: 4.311(毫秒). 执行号:709.
SQL>
或者
SQL> ALTER SYSTEM SET 'undo_retention'=1200 BOTH;
DMSQL 过程已成功完成
已用时间: 4.475(毫秒). 执行号:710.
SQL>
-- 检查修改后的UNDO_RETENTION
SQL> select para_name,para_value,default_value,para_type from v$dm_ini where para_name like '%UNDO_RETENTION%';
行号 PARA_NAME PARA_VALUE DEFAULT_VALUE PARA_TYPE
---------- -------------- ----------- ------------- ---------
1 UNDO_RETENTION 1200.000000 90.000000 SYS
已用时间: 3.943(毫秒). 执行号:711.
SQL>
4. 闪回测试
4.1 测试delete删除表数据恢复
1) 构建测试数据
create table PERSON.PERSON1 as select * from PERSON.PERSON;
SQL> select * from PERSON.PERSON1;
行号 PERSONID SEX NAME EMAIL PHONE
---------- ----------- --- --------- ------------- -----------
1 1 F 李丽 lily@sina.com 02788548562
2 2 M 王刚 02787584562
3 3 M 李勇 02782585462
4 4 F 郭艳 02787785462
5 5 F 孙丽 13055173012
6 6 M 黄非 13355173012
7 7 F 王菲 13255173012
8 8 M 张平 13455173012
9 9 M 张红 13555173012
10 10 F 刘佳 13955173012
11 11 F 王南 15955173012
12 12 F 李飞 15954173012
13 13 F 张大海 15955673012
14 14 F 王宇轩 15955175012
15 15 F 桑泽恩 15955173024
16 16 F 刘青 15955173055
17 17 F 杨凤兰 NULL 02785584662
17 rows got
已用时间: 0.265(毫秒). 执行号:713.
SQL>
2)删除数据测试闪回功能
SQL> select sysdate();
行号 SYSDATE()
---------- -------------------
1 2022-06-02 17:23:41
已用时间: 0.664(毫秒). 执行号:714.
---- 整张表数据delete删除掉
SQL> delete from PERSON.PERSON1;
影响行数 17
已用时间: 1.068(毫秒). 执行号:715.
SQL> commit;
操作已执行
已用时间: 1.826(毫秒). 执行号:716.
-- 此时可以看到表中已经没有任何数据记录了
SQL> select * from PERSON.PERSON1;
未选定行
已用时间: 0.265(毫秒). 执行号:717.
SQL>
-- 通过闪回查询WHEN TIMESTAMP查看原始数据:
SQL> select * from PERSON.PERSON1 WHEN TIMESTAMP '2022-06-02 17:23:41';
行号 PERSONID SEX NAME EMAIL PHONE
---------- ----------- --- --------- ------------- -----------
1 1 F 李丽 lily@sina.com 02788548562
2 2 M 王刚 02787584562
3 3 M 李勇 02782585462
4 4 F 郭艳 02787785462
5 5 F 孙丽 13055173012
6 6 M 黄非 13355173012
7 7 F 王菲 13255173012
8 8 M 张平 13455173012
9 9 M 张红 13555173012
10 10 F 刘佳 13955173012
11 11 F 王南 15955173012
12 12 F 李飞 15954173012
13 13 F 张大海 15955673012
14 14 F 王宇轩 15955175012
15 15 F 桑泽恩 15955173024
16 16 F 刘青 15955173055
17 17 F 杨凤兰 NULL 02785584662
17 rows got
已用时间: 0.901(毫秒). 执行号:718.
3)通过闪回功能恢复表数据
SQL> insert into PERSON.PERSON1 select * from PERSON.PERSON1 WHEN TIMESTAMP '2022-06-02 17:23:41';
影响行数 17
已用时间: 1.635(毫秒). 执行号:721.
SQL> commit;
操作已执行
已用时间: 1.993(毫秒). 执行号:722.
SQL> select * from PERSON.PERSON1;
行号 PERSONID SEX NAME EMAIL PHONE
---------- ----------- --- --------- ------------- -----------
1 1 F 李丽 lily@sina.com 02788548562
2 2 M 王刚 02787584562
3 3 M 李勇 02782585462
4 4 F 郭艳 02787785462
5 5 F 孙丽 13055173012
6 6 M 黄非 13355173012
7 7 F 王菲 13255173012
8 8 M 张平 13455173012
9 9 M 张红 13555173012
10 10 F 刘佳 13955173012
11 11 F 王南 15955173012
12 12 F 李飞 15954173012
13 13 F 张大海 15955673012
14 14 F 王宇轩 15955175012
15 15 F 桑泽恩 15955173024
16 16 F 刘青 15955173055
17 17 F 杨凤兰 NULL 02785584662
17 rows got
已用时间: 0.309(毫秒). 执行号:723.
SQL>
4.2 测试insert更新表数据恢复
1)insert更新数据
insert into PERSON.PERSON1 values (20,'M','王20','ily@sina.com','02785584662');
insert into PERSON.PERSON1 values (21,'M','李21','ily@sina.com','02785584662');
commit;
SQL> select sysdate();
行号 SYSDATE()
---------- -------------------
1 2022-06-02 17:40:35
已用时间: 0.350(毫秒). 执行号:724.
SQL> insert into PERSON.PERSON1 values (20,'M','王20','ily@sina.com','02785584662');
insert into PERSON.PERSON1 values (21,'M','李21','ily@sina.com','02785584662');DMSQL 过程已成功完成
已用时间: 0.840(毫秒). 执行号:725.
SQL>
影响行数 1
已用时间: 0.553(毫秒). 执行号:726.
SQL> commit;
操作已执行
已用时间: 1.198(毫秒). 执行号:727.
SQL> select * from PERSON.PERSON1;
行号 PERSONID SEX NAME EMAIL PHONE
---------- ----------- --- --------- ------------- -----------
1 1 F 李丽 lily@sina.com 02788548562
2 2 M 王刚 02787584562
3 3 M 李勇 02782585462
4 4 F 郭艳 02787785462
5 5 F 孙丽 13055173012
6 6 M 黄非 13355173012
7 7 F 王菲 13255173012
8 8 M 张平 13455173012
9 9 M 张红 13555173012
10 10 F 刘佳 13955173012
11 11 F 王南 15955173012
12 12 F 李飞 15954173012
13 13 F 张大海 15955673012
14 14 F 王宇轩 15955175012
15 15 F 桑泽恩 15955173024
16 16 F 刘青 15955173055
17 17 F 杨凤兰 NULL 02785584662
18 20 M 王20 ily@sina.com 02785584662
19 21 M 李21 ily@sina.com 02785584662
19 rows got
已用时间: 0.285(毫秒). 执行号:728.
SQL>
2)查询更新前的数据
SQL> select * from PERSON.PERSON1 WHEN TIMESTAMP '2022-06-02 17:40:35';
行号 PERSONID SEX NAME EMAIL PHONE
---------- ----------- --- --------- ------------- -----------
1 1 F 李丽 lily@sina.com 02788548562
2 2 M 王刚 02787584562
3 3 M 李勇 02782585462
4 4 F 郭艳 02787785462
5 5 F 孙丽 13055173012
6 6 M 黄非 13355173012
7 7 F 王菲 13255173012
8 8 M 张平 13455173012
9 9 M 张红 13555173012
10 10 F 刘佳 13955173012
11 11 F 王南 15955173012
12 12 F 李飞 15954173012
13 13 F 张大海 15955673012
14 14 F 王宇轩 15955175012
15 15 F 桑泽恩 15955173024
16 16 F 刘青 15955173055
17 17 F 杨凤兰 NULL 02785584662
17 rows got
已用时间: 1.191(毫秒). 执行号:729.
SQL>
4.3 闪回查询指定TRXID
1)构造修改记录
update PERSON.PERSON1 set NAME = '李丽丽' where PERSONID=1;
update PERSON.PERSON1 set NAME = '王刚刚' where PERSONID=2;
commit;
SQL> update PERSON.PERSON1 set NAME = '李丽丽' where PERSONID=1;
update PERSON.PERSON1 set NAME = '王刚刚' where PERSONID=2;
commit;
2 3 DMSQL 过程已成功完成
已用时间: 2.739(毫秒). 执行号:739.
SQL>
SQL> select * from PERSON.PERSON1;
行号 PERSONID SEX NAME EMAIL PHONE
---------- ----------- --- --------- ------------- -----------
1 1 F 李丽丽 lily@sina.com 02788548562
2 2 M 王刚刚 02787584562
3 3 M 李勇 02782585462
4 4 F 郭艳 02787785462
5 5 F 孙丽 13055173012
6 6 M 黄非 13355173012
7 7 F 王菲 13255173012
8 8 M 张平 13455173012
9 9 M 张红 13555173012
10 10 F 刘佳 13955173012
11 11 F 王南 15955173012
12 12 F 李飞 15954173012
13 13 F 张大海 15955673012
14 14 F 王宇轩 15955175012
15 15 F 桑泽恩 15955173024
16 16 F 刘青 15955173055
17 17 F 杨凤兰 NULL 02785584662
17 rows got
已用时间: 0.298(毫秒). 执行号:740.
2)通过闪回版本查询TRXID
SQL> SELECT VERSIONS_STARTTRXID,VERSIONS_ENDTRXID, VERSIONS_OPERATION,NAME FROM PERSON.PERSON1 VERSIONS BETWEEN TIMESTAMP '2022-06-02 18:01:34' AND SYSDATE;
行号 VERSIONS_ENDTRXID NAME
---------- -------------------- ---------
1 NULL 李丽丽
2 NULL 王刚刚
3 NULL 李勇
4 NULL 郭艳
5 NULL 孙丽
6 NULL 黄非
7 NULL 王菲
8 NULL 张平
9 NULL 张红
10 NULL 刘佳
11 NULL 王南
12 NULL 李飞
13 NULL 张大海
14 NULL 王宇轩
15 NULL 桑泽恩
16 NULL 刘青
17 NULL 杨凤兰
18 21390 李丽
19 21390 王刚
19 rows got
已用时间: 1.390(毫秒). 执行号:742.
SQL>
3)根据 TRXID 确定版本
SQL> select * from PERSON.PERSON1 WHEN TRXID 21390;
行号 PERSONID SEX NAME EMAIL PHONE
---------- ----------- --- --------- ------------- -----------
1 1 F 李丽 lily@sina.com 02788548562
2 2 M 王刚 02787584562
3 3 M 李勇 02782585462
4 4 F 郭艳 02787785462
5 5 F 孙丽 13055173012
6 6 M 黄非 13355173012
7 7 F 王菲 13255173012
8 8 M 张平 13455173012
9 9 M 张红 13555173012
10 10 F 刘佳 13955173012
11 11 F 王南 15955173012
12 12 F 李飞 15954173012
13 13 F 张大海 15955673012
14 14 F 王宇轩 15955175012
15 15 F 桑泽恩 15955173024
16 16 F 刘青 15955173055
17 17 F 杨凤兰 NULL 02785584662
17 rows got
已用时间: 0.766(毫秒). 执行号:744.
SQL>
5. 闪回事务查询
闪回事务查询提供系统视图 V$FLASHBACK_TRX_INFO 供用户查看在事务级对数据库所做的更改。根据视图信息,可以确定如何还原指定事务或指定时间段内的修改。
举例说明
例1 查询指定时间之后的事务信息,可为闪回查询操作提供参考。
SELECT * FROM V$FLASHBACK_TRX_INFO WHERE COMMIT_TIMESTAMP > '2022-06-02 17:23:41';
更多咨询请查看:达梦在线服务平台 达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台