Oracle 实战:利用 RMAN + ArchiveLog + LogMiner 找回误 DELETE 数据
问题背景
线上数据库发生了误删除(DELETE)数据,但由于 RMAN 全量备份已经在清理周期后被清理,备份片不完整无法直接恢复数据库数据。并因此无法直接通过已有备份进行RMAN还原。
最终采用以下方案完成数据恢复:
找回备份的 ArchiveLog → RMAN Catalog 注册 → Restore ArchiveLog → LogMiner 挖掘日志 → 获取 SQL_UNDO → 恢复误删除数据
整个恢复流程如下:
text
确认误删除时间
│
▼
查询归档日志 Sequence
│
▼
恢复缺失 ArchiveLog
│
▼
LogMiner 挖掘归档日志
│
▼
找到 DELETE 操作
│
▼
获取 SQL_UNDO
│
▼
执行 Undo SQL 恢复数据
一、确定误删除时间
首先需要确认数据删除的大概时间。
例如:
2026-06-18 02:50:50
~
2026-06-18 18:00:50
时间范围越准确,后续日志挖掘效率越高。
二、查询对应 ArchiveLog Sequence
先确认当天涉及哪些归档日志。
sql
SELECT *
FROM v$archived_log a
WHERE a.FIRST_TIME >= TO_DATE('2026-06-18','yyyy-mm-dd')
AND a.FIRST_TIME < TO_DATE('2026-06-19','yyyy-mm-dd');
记录对应的:
- Sequence#
- Thread#
- FIRST_TIME
- NEXT_TIME
后续恢复归档日志需要使用对应的 Sequence。
三、恢复缺失的 ArchiveLog
由于数据库中的归档已经不存在,需要从备份中恢复。
1、Catalog 备份文件
将备份文件注册到 RMAN。
rman
catalog backuppiece '/home/oracle/arch_20260619_5b4r14ep_1_1';
catalog backuppiece '/home/oracle/arch_20260619_594r14ep_1_1';
catalog backuppiece '/home/oracle/arch_20260619_5c4r14ep_1_1';
catalog backuppiece '/home/oracle/arch_20260619_5a4r14ep_1_1';
catalog backuppiece '/home/oracle/arch_20260619_584r14ep_1_1';
catalog backuppiece '/home/oracle/arch_20260619_5t4r16b5_1_1';
注册成功后会看到类似输出:
text
cataloged backup piece
RECID=100541
STAMP=1236954536
2、恢复指定 Sequence 的归档日志
rman
run {
set archivelog destination to '/home/oracle/archivelog-restore';
restore archivelog
from sequence 285410
until sequence 285421
thread 1;
}
恢复完成后,会得到对应的 ArchiveLog 文件。
例如:
/home/oracle/archivelog-restore/1_285421_929291329.dbf
四、使用 LogMiner 挖掘归档日志
1、加载归档日志
sql
BEGIN
DBMS_LOGMNR.ADD_LOGFILE(
LOGFILENAME => '/home/oracle/archivelog-restore/1_285421_929291329.dbf',
OPTIONS => DBMS_LOGMNR.NEW
);
END;
/
查看当前加载的日志:
sql
SELECT filename
FROM v$logmnr_logs;
2、启动 LogMiner
sql
BEGIN
DBMS_LOGMNR.START_LOGMNR(
OPTIONS => DBMS_LOGMNR.DICT_FROM_ONLINE_CATALOG
);
END;
/
3、查询指定表的操作记录
例如查询:
am_studentcontact
sql
SELECT
x.TIMESTAMP,
x.TABLE_NAME,
x.SQL_REDO,
x.SQL_UNDO
FROM v$logmnr_contents x
WHERE x.TIMESTAMP >= TO_DATE(
'2026-06-18 02:50:50',
'yyyy-MM-dd hh24:mi:ss'
)
AND x.TIMESTAMP < TO_DATE(
'2026-06-18 18:00:50',
'yyyy-MM-dd hh24:mi:ss'
)
AND x.TABLE_NAME = UPPER('am_studentcontact')
ORDER BY x.TIMESTAMP;
查询结果中重点关注:
- SQL_REDO
- SQL_UNDO
例如:
SQL_REDO
DELETE FROM AM_STUDENTCONTACT WHERE ID='1001';
对应会生成:
SQL_UNDO
INSERT INTO AM_STUDENTCONTACT(...)
VALUES(...);
这就是恢复数据所需要执行的 SQL。
4、结束 LogMiner
sql
BEGIN
DBMS_LOGMNR.END_LOGMNR;
END;
/
如此重复,解析整个时间段内的多个archivelog,得到当天DELETE的所有SQL记录。
五、执行 SQL_UNDO 恢复数据
找到对应删除操作后,直接执行:
sql
SQL_UNDO
即可恢复误删除的数据。
相比整库恢复,这种方式:
- 不影响业务
- 不需要恢复整个数据库
- 可以精准恢复单条或单表数据
整个恢复思路总结
text
误 DELETE 数据
│
▼
确定误删除时间
│
▼
查询 ArchiveLog Sequence
│
▼
发现归档已不存在
│
▼
找到备份 ArchiveLog
│
▼
RMAN Catalog 注册
│
▼
Restore ArchiveLog
│
▼
LogMiner 挖掘日志
│
▼
找到 SQL_UNDO
│
▼
执行 Undo SQL
│
▼
数据恢复完成