Oracle 数据闪回机制详解
概述
Oracle 的闪回功能主要用于处理意外的数据变更或删除操作。它可以将表恢复到某个历史状态,也可以还原已被删除的表。
- 误操作后的数据恢复(插入、更新、删除)
- 恢复被删除的表
- 查看表的历史变更记录
- 撤销已提交的事务
主要类型:
- 闪回表数据:将表恢复到某一时间点
- 闪回已删除的表:从回收站中恢复
- 闪回事务:基于事务号进行回滚
- 闪回数据库(了解):整体数据库恢复到历史时间点
- 闪回归档日志(了解)
参数配置
查看当前参数
SHOW PARAMETER undo;
输出示例:
NAME TYPE VALUE
------------------------------------ ---------------------- ------------------------------
undo_management string AUTO
undo_retention integer 900
undo_tablespace string UNDOTBS1
调整保留时间
ALTER SYSTEM SET undo_retention=1200 SCOPE=BOTH;
说明:
SCOPE 参数含义:
- MEMORY:仅内存生效
- SPFILE:仅配置文件生效
- BOTH:两者同时生效
表闪回操作
前提条件:需授予用户对表的闪回权限
GRANT FLASHBACK ANY TABLE TO scott;
获取 SCN 时间戳
SELECT TIMESTAMP_TO_SCN(SYSDATE) AS scn FROM DUAL;
示例流程
CREATE TABLE testfb (
id NUMBER,
name VARCHAR2(20)
);
INSERT INTO testfb VALUES (1, 'zhangsan');
INSERT INTO testfb VALUES (2, 'lisi');
INSERT INTO testfb VALUES (1, 'zhangsan');
DELETE FROM testfb WHERE id = 1;
COMMIT;
使用 FLASHBACK TABLE 进行恢复:
FLASHBACK TABLE testfb TO SCN 12312;
若报错提示"未启用行移动",则需先启用:
ALTER TABLE testfb ENABLE ROW MOVEMENT;
FLASHBACK TABLE testfb TO SCN 1195871;
注意事项
- 必须通过 SCN 或时间点来定位目标状态
- 系统表不可被闪回
- 不能跨 DDL 操作(如创建新表)进行闪回
回收站中的表恢复
删除表后会进入回收站:
DROP TABLE testfb;
SHOW RECYCLEBIN;
查看回收站内容:
ORIGINAL NAME RECYCLEBIN NAME OBJECT TYPE DROP TIME
---------------- ------------------------------ ------------ -------------------
TESTFB BIN$p0uIW1njR1CJAhmiOvsfpQ==$0 TABLE 2022-07-17:12:19:13
恢复表:
FLASHBACK TABLE testfb TO BEFORE DROP;
如果存在同名表,则需重命名:
FLASHBACK TABLE testfb TO BEFORE DROP RENAME TO test2;
也可以通过回收站名称恢复:
FLASHBACK TABLE 'BIN$p0uIW1njR1CJAhmiOvsfpQ==$0' TO BEFORE DROP;
清空回收站:
PURGE RECYCLEBIN;
直接删除不进回收站:
DROP TABLE testfb PURGE;
闪回事务
用于恢复特定事务的操作,依赖于事务日志。
准备测试数据
INSERT INTO testfb VALUES (1, 'zhangsan1');
INSERT INTO testfb VALUES (2, 'zhangsan2');
INSERT INTO testfb VALUES (3, 'zhangsan3');
COMMIT;
INSERT INTO testfb VALUES (4, 'zhangsan4');
INSERT INTO testfb VALUES (5, 'zhangsan5');
INSERT INTO testfb VALUES (6, 'zhangsan6');
COMMIT;
INSERT INTO testfb VALUES (7, 'zhangsan7');
INSERT INTO testfb VALUES (8, 'zhangsan8');
INSERT INTO testfb VALUES (9, 'zhangsan9');
COMMIT;
查询事务信息
SELECT id, name, versions_xid, versions_operation, versions_starttime, versions_endtime
FROM testfb VERSIONS BETWEEN TIMESTAMP MINVALUE AND MAXVALUE;
获取 UNDO SQL
SELECT operation, undo_sql
FROM flashback_transaction_query
WHERE xid='02000A004E030000';
权限要求:
GRANT SELECT ANY TRANSACTION TO scott;
如果未开启补充日志,可能无法获取完整的 UNDO 语句:
ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;
执行 UNDO SQL
必须执行与事务相关的所有 UNDO 语句才能完全回滚,否则只能部分还原。