当用户操作不慎导致错误的删改数据时,非常希望有一种简单快捷的方式可以恢复数据。闪回技术,就是为了用户可以迅速处理这种数据逻辑损坏的情况而产生的。
闪回技术主要是通过回滚段存储的UNDO记录来完成历史记录的还原。设置ENABLE_FLASHBACK为1后,开启闪回功能。DM会保留回滚段一段时间,回滚段保留的时间代表着可以闪回的时间长度。由UNDO_RETENTION参数指定。
开启闪回功能后,DM会在内存中记录下每个事务的起始时间和提交时间。通过用户指定的时刻,查询到该时刻的事务号,结合当前记录和回滚段中的UNDO记录,就可以还原出特定事务号的记录。即指定时刻的记录状态。从而完成闪回查询。闪回查询功能完全依赖于回滚段管理,对于DROP等误操作不能恢复。闪回特性可应用在以下方面:
Ø 自我维护过程中的修复:当一些重要的记录被意外删除,用户可以向后移动到一个时间点,查看丢失的行并把它们重新插入现在的表内恢复;
Ø 用于分析数据变化:可以对同一张表的不同闪回时刻进行链接查询,以此查看变化的数据。
1. 适用场景
|
软件 |
版本 |
|
操作系统 |
Redhat 7 及以上版本 |
|
DM 数据库 |
DM 8.0 及以上版本 |
|
CPU 架构 |
x86 、ARM、龙芯、飞腾等国内外主流 CPU |
2. 相关参数设置
查询闪回功能状态,数据库默认关闭(0-关闭,1-打开)。示例语句如下所示:
|
SELECT name , TYPE , VALUE , sys_value, file_value FROM v$parameter WHERE name LIKE '%FLASHBACK%'; |
输出结果:
|
NAME TYPE VALUE SYS_VALUE FILE_VALUE ---------------- ---- ----- --------- ---------- ENABLE_FLASHBACK SYS 0 0 0 |
1) 开启闪回功能方法一,示例语句如下所示:
|
SQL> alter system set 'enable_flashback'=1 both; DMSQL 过程已成功完成 SQL> select name,type,value,sys_value,file_value from v$parameter where name='ENABLE_FLASHBACK';
NAME TYPE VALUE SYS_VALUE FILE_VALUE ---------------- ---- ----- --------- ---------- ENABLE_FLASHBACK SYS 1 1 1 |
注意:该方法设置参数时,参数名必须加单引号。
2) 开启闪回功能方法二,示例语句如下所示:
|
SP_SET_PARA_VALUE (1, 'ENABLE_FLASHBACK', 1); |
//scope 为 1 表示 dm.ini 文件和内存参数都修改,不需要重启服务器。
//scope 为 2 表示只修改 dm.ini 文件,服务器重启后生效。
//value : 设置的值。
获取参数,示例语句如下所示:
|
SELECT SF_GET_PARA_VALUE (1, 'ENABLE_FLASHBACK') in_file, SF_GET_PARA_VALUE (2, 'ENABLE_FLASHBACK') in_mem; |
由于回滚段默认每秒种都会自动清理,所以需要延长回滚记录的保留时间,单位是秒。回滚段参数太大容易引发回滚段膨胀,这里设置为 1200s。示例语句如下所示:
|
ALTER SYSTEM SET 'undo_retention'=1200 BOTH;
SELECT name , TYPE , VALUE , sys_value, file_value FROM v$parameter WHERE name = 'UNDO_RETENTION'; |
输出结果:
|
NAME TYPE VALUE SYS_VALUE FILE_VALUE -------------- ---- ----------- ----------- ----------- UNDO_RETENTION SYS 1200.000000 1200.000000 1200.000000 |
3. 闪回查询
1) 按时间查询历史记录
通过指定一个时间(timestamp类型),通常可以用一个日期时间字符串表达。
测试在 disql 工具中进行,使用 dmhr 模式下的 city 表。示例语句如下所示:
|
SELECT * FROM dmhr.city WHERE city_id = 'CD'; UPDATE dmhr.city SET region_id = 10 WHERE city_id = 'CD'; SELECT * FROM dmhr.city WHERE city_id = 'CD'; SELECT * FROM dmhr.city WHEN TIMESTAMP '2021-05-13 20:17:57' WHERE city_id='CD'; |
输出结果:
|
20:17:55 SQL> SELECT * FROM dmhr.city WHERE city_id = 'CD';
CITY_ID CITY_NAME REGION_ID ------- --------- ----------- CD 成都 7
20:17:58 SQL> UPDATE dmhr.city SET region_id = 10 WHERE city_id = 'CD'; 影响行数 1
20:18:05 SQL> SELECT * FROM dmhr.city WHERE city_id = 'CD';
CITY_ID CITY_NAME REGION_ID ------- --------- ----------- CD 成都 10
20:18:21 SQL> SELECT 2 * 3 FROM 4 dmhr.city WHEN TIMESTAMP ' 2021-05-13 20:17:57' 5 WHERE 6 city_id='CD';
CITY_ID CITY_NAME REGION_ID ------- --------- ----------- CD 成都 7 |
2) 按事务id号查询历史记录
首先使用 versions_endtrxid 伪列查询事务 id 号。用户通过闪回版本查询子句,可以得到指定表过去某个时间段内,事务导致记录变化的全部记录,指定条件可以为时刻或事务号。
执行闪回版本查询,示例语句如下所示:
|
SELECT versions_endtrxid, * FROM dmhr.job VERSIONS BETWEEN TIMESTAMP '2021-05-13 20:25:00' AND SYSDATE WHERE JOB_ID = 22; |
输出结果:
|
VERSIONS_ENDTRXID JOB_ID JOB_TITLE MIN_SALARY MAX_SALARY -------------------- ------ --------- ----------- ----------- NULL 22 文员 2500 5000 |
NULL 表示该行的版本仍然是当前版本。
Ø 第一次调整文员的最低工资为 3500 并提交,示例语句如下所示:
|
UPDATE dmhr.job SET MIN_SALARY = 3500 WHERE JOB_ID = 22;
COMMIT; |
Ø 第二次调整文员的最低工资为 2800 并提交,示例语句如下所示:
|
UPDATE dmhr.job SET MIN_SALARY = 2800 WHERE JOB_ID = 22;
COMMIT; |
再次执行闪回版本查询,示例语句如下所示:
|
SELECT versions_endtrxid, * FROM dmhr.job VERSIONS BETWEEN TIMESTAMP '2021-05-13 20:25:00' AND SYSDATE WHERE JOB_ID = 22; |
输出结果:
|
VERSIONS_ENDTRXID JOB_ID JOB_TITLE MIN_SALARY MAX_SALARY -------------------- ------ --------- ----------- ----------- NULL 22 文员 2800 5000 9337 22 文员 3500 5000 9336 22 文员 2500 5000 |
两个事务分别对应了 2 个版本,可以随意查询任何版本。示例语句如下所示:
|
SELECT TRXID, * FROM dmhr.job WHEN TRXID 9336 WHERE JOB_ID=22
union all
SELECT TRXID, * FROM dmhr.job WHEN TRXID 9337 WHERE JOB_ID=22; |
输出结果:
|
TRXID JOB_ID JOB_TITLE MIN_SALARY MAX_SALARY -------------------- ------ --------- ----------- ----------- 9325 22 文员 2500 5000 9336 22 文员 3500 5000 |
显示了第一次提交前和第一次提交后的数据。
4. 闪回事务查询
闪回事务查询提供系统视图 V$FLASHBACK_TRX_INFO,查看在事务级对数据库所做的更改。根据该视图信息,可以确定如何还原指定事务或指定时间段内的修改。
查询指定时间之后的事务信息,示例语句如下所示:
|
SELECT commit_trxid, operation, table_name, undo_sql FROM V$FLASHBACK_TRX_INFO; |
输出结果:
|
COMMIT_TRXID OPERATION TABLE_NAME UNDO_SQL -------------------- --------- ---------- ------------------------------------------------- 9337 O NULL NULL 9337 U JOB UPDATE DMHR.JOB SET MIN_SALARY=2500 WHERE ROWID=5 9337 C NULL NULL 9338 O NULL NULL 9338 U JOB UPDATE DMHR.JOB SET MIN_SALARY=3500 WHERE ROWID=5 9338 C NULL NULL |