oracle数据库中误删数据是比较常见的操作失误,不同场景下的误删有不同的恢复方案,用户可以根据自身的环境和误操作情况选择对应的恢复方式。

利用闪回功能恢复误删数据
oracle的闪回功能是恢复误删数据最便捷的方式,前提是数据库开启了闪回相关功能,且误操作的时间在闪回保留周期内。
恢复误删的表数据
如果是误执行了delete语句删除了表中的部分数据,可以通过闪回查询找回历史数据。
-- 查询误删前时间点的表数据,假设误操作时间是10分钟前 SELECT * FROM 表名 AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE; -- 将查询到的数据重新插入到原表中 INSERT INTO 表名 SELECT * FROM 表名 AS OF TIMESTAMP SYSTIMESTAMP - INTERVAL '10' MINUTE WHERE 条件; -- 可选,用于筛选需要恢复的数据
恢复误删的表
如果是误执行了DROP TABLE语句删除了整张表,可以通过闪回表功能恢复。
-- 查看回收站中被删除的表 SELECT OBJECT_NAME, ORIGINAL_NAME, DROP_TIME FROM RECYCLEBIN; -- 闪回恢复被删除的表 FLASHBACK TABLE 原表名 TO BEFORE DROP; -- 如果原表名已经被新表占用,可以重命名恢复 FLASHBACK TABLE 原表名 TO BEFORE DROP RENAME TO 新表名;
通过undo表空间恢复数据
如果闪回功能没有开启,但是undo表空间的数据还没有被覆盖,也可以通过undo中的数据恢复误删的记录。
-- 查看当前undo表空间的保留时间,单位是秒
SHOW PARAMETER undo_retention;
-- 查询undo中保存的历史数据
SELECT * FROM 表名 AS OF TIMESTAMP TO_TIMESTAMP('误删时间点', 'YYYY-MM-DD HH24:MI:SS');
-- 将历史数据插入原表
INSERT INTO 表名
SELECT * FROM 表名 AS OF TIMESTAMP TO_TIMESTAMP('误删时间点', 'YYYY-MM-DD HH24:MI:SS');
需要注意的是,undo中的数据保留时间由undo_retention参数控制,如果超过了保留时间,数据可能被覆盖,就无法通过这种方式恢复了。
使用备份文件恢复误删数据
如果以上两种方式都无法恢复数据,就需要使用之前做的数据库备份文件来还原了,这种方式恢复时间相对较长,且会丢失备份之后的新数据。
全库备份恢复
如果有全库备份,可以通过RMAN工具进行恢复,步骤如下:
- 关闭数据库并启动到mount状态
- 执行RMAN恢复命令还原全库
- 打开数据库并重置日志
-- RMAN恢复全库示例
RUN {
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
RESTORE DATABASE;
RECOVER DATABASE;
ALTER DATABASE OPEN RESETLOGS;
}
表级备份恢复
如果之前单独导出过该表的备份,可以通过imp或者impdp工具导入备份数据。
-- 使用impdp导入表备份 impdp 用户名/密码 DIRECTORY=备份目录 DUMPFILE=表备份文件.dmp TABLES=表名;
不同恢复方式对比
| 恢复方式 | 适用场景 | 恢复速度 | 数据丢失情况 |
|---|---|---|---|
| 闪回查询恢复 | 误删行数据,在闪回保留期内 | 快 | 无丢失 |
| 闪回表恢复 | 误删整张表,表在回收站中 | 快 | 无丢失 |
| undo恢复 | 误删行数据,undo数据未覆盖 | 较快 | 无丢失 |
| 备份文件恢复 | 以上方式均不可行 | 慢 | 丢失备份后的新数据 |
误删恢复的注意事项
- 发生误删操作后,第一时间停止对该表的相关写入操作,避免新数据覆盖undo或者闪回区的内容
- 恢复操作前最好先对当前数据库做一次备份,避免恢复失败导致数据进一步丢失
- 生产环境执行恢复操作前,尽量先在测试环境验证恢复步骤的正确性
- 定期做数据库全量备份和增量备份,降低误删操作带来的风险