Oracle 19c 备份与恢复
本文档为Oracle 19c数据库备份与恢复流程,覆盖归档模式配置、用户管理备份、RMAN核心操作、多场景故障恢复、闪回技术、逻辑备份等核心内容。如有错误,欢迎批评指正。
环境准备与基础概念
备份恢复概述
数据库备份恢复是DBA核心职责,是保障数据安全的关键防线。Oracle提供了多种备份恢复方式,各有其适用场景。
| 备份方式 | 特点 | 适用场景 |
|---|---|---|
| 用户管理的备份 | 直接使用操作系统命令复制物理文件,分为冷备(一致性)和热备(非一致性) | 学习原理、小型环境、RMAN不可用时的备选方案 |
RMAN 备份 |
Oracle 内置工具,支持增量备份、压缩、加密、自动化管理 | 生产环境首选,支持复杂恢复需求 |
| 逻辑备份 | exp/imp、expdp/impdp,导出为逻辑文件(dmp) |
数据迁移、部分数据导出、跨平台传输 |
恢复分为两种核心类型:
-
完全恢复:利用备份和归档日志,将数据库恢复到故障前的最新状态,不丢失任何已提交事务。
-
不完全恢复:将数据库恢复到过去的某个时间点、SCN或日志序列,会丢失之后的数据,适用于误操作(如删表、
truncate)或日志丢失的场景。
环境要求
- 已安装Oracle 19c数据库软件,并创建了对应数据库实例
- 操作系统:Linux 7+
- 建议创建普通用户(如
bakuser)用于存放备份文件
开启归档模式(自定义归档路径)
归档模式是数据库能够进行联机备份的基础,非归档模式下仅能进行冷备,且恢复点仅限于最近一次备份,生产环境必须开启归档模式。
操作步骤:
- 创建归档日志存放目录
bash
mkdir -p /u01/archive
chown oracle:oinstall /u01/archive
chmod 755 /u01/archive
- 查看当前归档状态
sql
archive log list;
未开启归档时,输出会显示Database log mode No Archive Mode。
- 关闭数据库,确保一致性
sql
shutdown immediate;
- 启动数据库到mount状态
sql
startup mount;
- 设置自定义归档路径
sql
alter system set log_archive_dest_1='location=/u01/archive' scope=both;
- 启用归档模式
sql
alter database archivelog;
- 打开数据库
sql
alter database open;
- 验证归档状态
sql
archive log list;
开启成功后,输出会显示Database log mode Archive Mode、Automatic archival Enabled。
⚠️ 注意事项:
- 修改
log_archive_dest_n参数后,使用scope=both可立即生效,建议重启数据库确保所有后台进程正确识别新路径- 归档目录必须提前创建,且Oracle用户需拥有读写权限,否则数据库无法归档最终会挂起
- 首次开启归档后,建议立即执行一次全库冷备,用于后续恢复测试
- 若同时使用快速恢复区(FRA),可保留
db_recovery_file_dest用于存放闪回日志和RMAN备份集,与归档路径独立配置
可选配置:快速恢复区(FRA)
快速恢复区是Oracle推荐的集中存储备份、闪回日志的区域,可简化管理,与归档路径相互独立,无需闪回数据库或集中管理备份可跳过此步骤。
操作步骤:
- 创建FRA目录
bash
mkdir -p /u01/app/oracle/fra
chown oracle:oinstall /u01/app/oracle/fra
chmod 755 /u01/app/oracle/fra
- 设置FRA大小与路径
sql
alter system set db_recovery_file_dest_size=10G scope=both;
alter system set db_recovery_file_dest='/u01/app/oracle/fra' scope=both;
- 查看FRA配置
sql
show parameter db_recovery_file;
创建测试数据
为后续恢复验证,创建测试表空间、用户和测试数据:
- 创建测试表空间
sql
create tablespace tbs_test datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' size 100m;
- 创建测试用户并授权
sql
create user test identified by test default tablespace tbs_test;
grant connect, resource, dba to test;
- 连接测试用户,创建测试表并插入数据
sql
conn test/test
create table emp (id number, name varchar2(20));
insert into emp values (1, 'Alice');
insert into emp values (2, 'Bob');
commit;
- 验证测试数据
sql
select * from emp;
创建备份目录
bash
mkdir -p /u01/backup/rman
chown oracle:oinstall /u01/backup/rman
chmod 755 /u01/backup/rman
用户管理的备份与恢复
用户管理的备份直接通过操作系统命令复制数据库物理文件,理解该方法有助于深入掌握备份恢复底层原理,也是应对RMAN不可用等极端场景的必备技能。
冷备份(一致性备份)
冷备要求数据库完全关闭,所有文件头部SCN一致,还原后无需恢复即可直接打开,适用于非归档模式或需要静态备份的场景。
操作步骤:
- 查询数据库核心文件位置
sql
-- 控制文件位置
SELECT name FROM v$controlfile;
-- 数据文件位置
SELECT name FROM v$datafile;
-- 联机重做日志位置
SELECT member FROM v$logfile;
- 关闭数据库,确保一致性
sql
shutdown immediate;
- 创建备份目录并复制核心文件
bash
# 定义备份目录
BACKUP_DIR=/u01/backup/cold_backup_$(date +%Y%m%d)
# 创建目录并授权
mkdir -p $BACKUP_DIR
chown oracle:oinstall /u01/backup/
chmod 755 /u01/backup/
# 复制所有核心文件
cp -v /u01/app/oradata/RHEL7/*.dbf $BACKUP_DIR/
cp -v /u01/app/oradata/RHEL7/*.ctl $BACKUP_DIR/
cp -v /u01/app/oradata/RHEL7/*.log $BACKUP_DIR/
- 验证备份文件
bash
ls -l /u01/backup/cold_backup_$(date +%Y%m%d)/
- 启动数据库
sql
startup;
⚠️ 注意事项:
- 冷备期间数据库业务中断,生产环境通常不允许使用
- 联机重做日志文件备份非必须,恢复时可通过归档日志重建,建议备份用于不完全恢复场景
- 备份后建议使用
dbv工具验证数据文件完整性
热备份(表空间备份模式)
热备在数据库打开状态下执行,要求数据库处于归档模式。核心原理是将表空间置于备份模式,冻结该表空间数据文件头部SCN,同时将修改块的完整前镜像写入重做日志,确保备份文件可通过归档恢复至一致状态。
操作步骤:
- 创建热备份目录并授权
bash
mkdir -p /u01/backup/hot_backup
chown oracle:oinstall /u01/backup/hot_backup
chmod 755 /u01/backup/hot_backup
- 将目标表空间置于备份模式
sql
alter tablespace tbs_test begin backup;
- 复制该表空间对应的数据文件
bash
cp -v /u01/app/oradata/RHEL7/tbs_test01.dbf /u01/backup/hot_backup/
- 结束表空间备份模式
sql
alter tablespace tbs_test end backup;
⚠️ 关键说明:
begin backup会触发检查点,将脏数据写入磁盘,并记录开始备份的SCN- 备份过程中数据文件可正常修改,修改内容的完整前镜像会记录到重做日志,用于恢复时应用
- 若备份过程中数据库异常关闭,下次启动会报错文件需要介质恢复,可执行
alter database end backup;强制结束备份模式,再应用归档日志恢复
用户管理的恢复操作(数据文件丢失场景)
模拟故障:删除测试表空间对应的数据文件,数据库仍可运行,但访问该文件会报错。
恢复步骤:
- 将损坏的数据文件脱机
sql
alter database datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' offline;
- 从备份还原数据文件到原路径
bash
cp /u01/backup/hot_backup/tbs_test01.dbf /u01/app/oradata/RHEL7/
- 恢复数据文件,应用归档日志
sql
recover datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf';
- 将数据文件联机
sql
alter database datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' online;
- 验证数据完整性
sql
select * from test.emp;
RMAN基础与配置
RMAN核心概述
RMAN(Recovery Manager)是Oracle内置的备份恢复工具,通过服务器会话执行备份和恢复操作,是生产环境备份恢复的首选方案。
核心架构组成:
- RMAN可执行程序:用户接口,解析命令并调用目标数据库的PL/SQL包
- 服务器进程(通道):执行实际的备份和恢复I/O操作
- RMAN资料库:存储备份元数据,可存放在目标数据库的控制文件(nocatalog)或独立的恢复目录数据库(catalog)中
核心优势:
- 自动管理备份信息,无需手动记录备份文件名
- 支持增量备份,仅备份变化的数据块
- 自动检测并跳过未使用的块,节省存储空间
- 支持并行备份,提升备份性能
- 可自动检测数据块损坏
- 内置备份加密、压缩功能
连接RMAN
本地连接目标数据库命令:
bash
rman target /
不使用恢复目录时,RMAN会将元数据存储在目标数据库的控制文件中。
RMAN基础命令
sql
-- 显示所有RMAN配置
show all;
-- 列出所有备份信息
list backup;
-- 报告数据库结构,包含数据文件、表空间、文件号等信息
report schema;
RMAN核心参数配置
RMAN配置会持久化存储在控制文件中,通过configure命令设置,生产环境推荐配置如下:
- 设置备份保留策略
sql
-- 保留最近2份有效备份
configure retention policy to redundancy 2;
- 开启控制文件自动备份(强烈推荐)
sql
-- 每次备份后或数据库结构变化时,自动备份控制文件和spfile
configure controlfile autobackup on;
-- 设置控制文件自动备份路径与格式
configure controlfile autobackup format for device type disk to '/u01/backup/rman/cf_%F';
- 设置默认备份路径
sql
configure channel device type disk format '/u01/backup/rman/%U';
- 启用备份优化
sql
-- 自动跳过未变化的文件,如只读表空间
configure backup optimization on;
- 配置快照控制文件位置
sql
configure snapshot controlfile name to '/u01/backup/rman/snapcf_rhel7.f';
⚠️ 参数说明:
redundancy 2:至少保留2份有效备份,超出的备份会被标记为废弃,需手动执行delete obsolete删除%F:生成包含DBID、日期和序列号的唯一文件名,便于恢复时自动查找%U:由备份集号、时间戳等组成的唯一文件名,避免备份文件重名
控制文件备份记录保留配置
不使用恢复目录(nocatalog模式)时,备份记录存储在控制文件中,可通过以下参数调整保留时长:
sql
-- 查看当前保留天数
show parameter control_file_record_keep_time;
-- 修改为30天
alter system set control_file_record_keep_time=30 scope=both;
可选配置:恢复目录
恢复目录是独立的数据库,用于存储RMAN元数据,可管理多个目标数据库、长期保留备份历史,适用于多数据库管理场景。
- 恢复目录数据库中创建表空间与用户
sql
-- 创建表空间
create tablespace rcat datafile '/u01/app/oradata/CATDB/rcat01.dbf' size 100m;
-- 创建用户并授权
create user rman identified by rman default tablespace rcat quota unlimited on rcat;
grant recovery_catalog_owner, connect, resource to rman;
- RMAN中创建恢复目录
bash
rman catalog rman/rman@catdb
sql
create catalog tablespace rcat;
- 注册目标数据库
bash
rman target / catalog rman/rman@catdb
sql
register database;
RMAN备份实战
数据库全量备份(备份集)
全库备份包含所有数据文件和控制文件,搭配plus archivelog可同时备份归档日志,delete input可删除已备份的归档文件释放空间。
sql
backup database plus archivelog delete input;
备份管理相关命令:
sql
-- 预览废弃备份
report obsolete;
-- 删除废弃备份
delete obsolete;
-- 删除所有备份
delete noprompt backup;
镜像副本备份
镜像副本是数据文件的精确拷贝,与操作系统cp命令结果一致,RMAN会自动验证块完整性,可用于快速还原,也可作为增量备份的基础。
sql
-- 创建全库镜像副本备份
backup as copy database;
-- 删除镜像副本备份
delete copy;
增量备份
增量备份仅备份自上次备份以来变化的数据块,大幅节省备份时间与存储空间,必须先执行级别0备份作为基础。
- 级别0:全量备份,可作为级别1增量备份的基础(普通全备无法作为增量基础)
- 级别1差异增量(默认):备份自上次级别0或级别1备份以来变化的数据块
- 级别1累积增量:备份自上次级别0备份以来所有变化的数据块,恢复时仅需应用一次
sql
-- 级别0基础备份
backup incremental level 0 database;
-- 级别1差异增量备份
backup incremental level 1 database;
-- 级别1累积增量备份
backup incremental level 1 cumulative database;
⚠️ 注意:首次执行级别1备份时,若不存在级别0备份,会自动转为级别0备份,建议先手动执行级别0备份。
表空间与数据文件备份
针对特定表空间或数据文件的精细化备份,适用于频繁变化的表空间场景。
sql
-- 备份指定表空间
backup tablespace tbs_test;
-- 备份指定数据文件(通过文件号)
backup datafile 5;
数据文件号可通过report schema;或v$datafile视图查询。
控制文件与参数文件备份
控制文件和spfile是数据库启动与运行的核心文件,建议定期单独备份。
sql
-- 备份当前控制文件
backup current controlfile;
-- 备份spfile参数文件
backup spfile;
备份有效性验证
RMAN可验证备份是否可用于恢复,检测备份集是否存在物理损坏。
sql
-- 预览数据库恢复所需的备份文件
restore database preview;
-- 验证指定备份集的物理完整性
validate backupset <bskey>;
备份集关键字bskey可通过list backup命令查询。
RMAN完全恢复实战
完全恢复核心概念
完全恢复指将数据库恢复到故障发生时的最新状态,不丢失任何已提交事务,核心分为两个步骤:
- Restore:从备份中还原损坏或丢失的数据文件
- Recover:应用归档日志和联机重做日志,将数据文件前滚到最新SCN
RMAN会自动识别所需的备份和归档日志,无需手动查找。
数据文件丢失恢复(在线恢复)
模拟故障:删除测试表空间对应的数据文件,数据库仍在运行,访问该表空间会报错。
恢复步骤:
- 将损坏的数据文件脱机
sql
alter database datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' offline;
- RMAN中还原并恢复数据文件
sql
restore datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf';
recover datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf';
- 将数据文件联机
sql
alter database datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' online;
- 验证数据完整性
sql
select * from test.emp;
表空间丢失恢复
若整个表空间的所有数据文件都丢失,可直接对表空间执行在线恢复。
恢复步骤:
- 将目标表空间脱机
sql
alter tablespace tbs_test offline immediate;
- RMAN中还原并恢复表空间
sql
restore tablespace tbs_test;
recover tablespace tbs_test;
- 将表空间联机
sql
alter tablespace tbs_test online;
- 验证表空间可用性
sql
select * from test.emp;
SYSTEM表空间丢失恢复
SYSTEM表空间存放数据库数据字典,无法在线脱机,必须在mount状态下执行恢复。
模拟故障:删除system01.dbf数据文件,数据库重启后无法打开,仅能进入mount状态。
恢复步骤:
- 强制关闭异常数据库
sql
SHUTDOWN ABORT;
- 启动数据库到mount状态
sql
startup mount;
- RMAN中还原并恢复SYSTEM表空间
sql
restore datafile 1;
recover datafile 1;
- 打开数据库
sql
alter database open;
控制文件丢失恢复
控制文件存储数据库物理结构信息,全部丢失后数据库仅能启动到nomount状态,必须从备份恢复。
场景前提:SPFILE仍存在,所有控制文件全部丢失/损坏,数据库已关闭。
恢复步骤:
- 强制关闭异常数据库
sql
SHUTDOWN ABORT;
- 启动数据库到nomount状态
sql
startup nomount;
- RMAN中从自动备份恢复控制文件
sql
-- 方法1:通过DBID恢复(推荐,更精准)
set dbid 2387499594;
restore controlfile from autobackup;
-- 方法2:通过数据库名恢复(Oracle 12c以上支持)
set dbname RHEL7;
restore controlfile from autobackup;
-- 方法3:直接指定备份片路径恢复
restore controlfile from '/u01/backup/rman/cf_c-1234567890-20240115-00';
DBID可通过SELECT dbid FROM v$database;提前查询并记录。
- 将数据库启动到mount状态
sql
alter database mount;
- 还原并恢复数据库(确保数据一致性)
sql
restore database;
recover database;
- 以resetlogs方式打开数据库
sql
alter database open resetlogs;
⚠️ 注意:执行
resetlogs后会重置日志序列,创建新的数据库化身,必须立即执行一次全库备份。
参数文件(spfile)丢失恢复
SPFILE(服务器参数文件)丢失后,数据库无法启动到任何状态,Oracle在nomount阶段就需要读取参数文件,分为两种场景处理。
场景A:数据库仍在运行(未关闭)
sql
-- 从内存中导出PFILE文件
create pfile='/tmp/init.ora' from memory;
-- 关闭数据库
shutdown immediate;
-- 从PFILE生成新的SPFILE
create spfile from pfile='/tmp/init.ora';
-- 启动数据库
startup;
⚠️ 关键提示:只要数据库仍在运行,切勿关闭实例,否则内存中的参数会永久丢失。
场景B:数据库已关闭,无法启动
- 创建最小化PFILE文件
bash
echo "db_name=rhel7" > $ORACLE_HOME/dbs/initrhel7.ora
- 使用最小化PFILE启动到nomount状态
sql
startup nomount pfile='$ORACLE_HOME/dbs/initrhel7.ora';
- RMAN中恢复SPFILE
sql
-- 方法1:通过自动备份恢复
set dbid 2387499594;
SET CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '/u01/backup/rman/cf_%F';
restore spfile from autobackup;
-- 方法2:直接指定备份片路径恢复
restore spfile from '/u01/backup/rman/cf_c-2387499594-20260320-0b';
- 关闭实例,使用恢复后的SPFILE启动数据库
sql
shutdown immediate;
startup;
RMAN不完全恢复
不完全恢复用于恢复误操作(如误删表、truncate表)或丢失部分归档日志的场景,可将数据库恢复到过去的某个时间点、SCN或日志序列,会丢失目标时间点之后的数据。
恢复前提:
- 数据库处于归档模式,已开启归档日志
- 拥有完整的级别0备份/全备,以及自备份以来所有连续完整的归档日志
- 数据库可正常启动到mount状态
基于时间点的恢复
场景示例:2026-03-20 15:39:22 测试用户误删除emp表,需恢复到删除操作前的2026-03-20 15:38:20,找回丢失数据。
恢复步骤:
- 关闭数据库并启动到mount状态
sql
shutdown immediate;
startup mount;
- RMAN中执行时间点不完全恢复
sql
run {
set until time "to_date('2026-03-20 15:38:20','yyyy-mm-dd hh24:mi:ss')";
restore database;
recover database;
}
- 以resetlogs方式打开数据库
sql
alter database open resetlogs;
⚠️ 注意事项:
- 时间格式必须与NLS设置匹配,建议使用
to_date函数明确指定格式set until time指定的时间需早于误操作时间,建议预留1-2秒余量- 恢复完成后必须立即执行全库备份,
resetlogs后之前的备份可能不再适用
基于SCN的恢复
若已知误操作前的SCN(系统改变号),可基于SCN执行恢复,精度高于时间点恢复。
恢复步骤:
- 查询当前数据库SCN
sql
commit;
select current_scn from v$database;
- 关闭数据库并启动到mount状态
sql
shutdown immediate;
startup mount;
- RMAN中执行SCN不完全恢复(恢复到误操作SCN-1)
sql
run {
set until scn 1234566;
restore database;
recover database;
}
- 以resetlogs方式打开数据库
sql
alter database open resetlogs;
基于日志序列的恢复
适用于丢失部分归档日志的场景,可恢复到最后一个可用归档日志之前的状态。
sql
run {
set until sequence 100 thread 1;
restore database;
recover database;
}
alter database open resetlogs;
上述命令会将数据库恢复到日志序列100之前的状态,不包含序列100。
数据库化身(Incarnation)管理
每次使用resetlogs打开数据库,都会创建一个新的数据库化身(incarnation),恢复目录或控制文件中会记录所有化身信息。若需恢复到之前化身的时间点,必须先切换到对应化身。
核心操作命令:
sql
-- 列出所有数据库化身
list incarnation;
-- 切换到指定旧化身
reset database to incarnation 1;
-- 执行对应时间点的不完全恢复
run {
set until time "to_date('2024-01-15 10:20:00','yyyy-mm-dd hh24:mi:ss')";
restore database;
recover database;
}
-- 以resetlogs打开数据库
alter database open resetlogs;
闪回技术快速恢复
闪回技术是Oracle提供的一组在线、快速恢复机制,利用Undo数据或闪回日志,无需依赖传统备份即可将数据或数据库恢复到过去的时间点,快速修正逻辑错误。
| 闪回技术 | 核心作用 | 依赖组件 |
|---|---|---|
| Flashback Database | 将整个数据库回退到过去的某个时间点 | 闪回恢复区、闪回日志 |
| Flashback Drop | 恢复被DROP的表 |
回收站 |
| Flashback Query | 查询过去某个时间点的数据 | Undo表空间 |
| Flashback Version Query | 查询某行数据的历史版本变化 | Undo表空间 |
| Flashback Transaction Query | 查询事务的详细信息,生成撤销SQL | Undo表空间 |
| Flashback Table | 将表恢复到过去的某个时间点 | Undo表空间,需启用行移动 |
| Flashback Data Archive | 长期保存表的历史数据(可达数年) | 独立的存储区域 |
闪回数据库(Flashback Database)
闪回数据库可将整个数据库回退到过去的某个时间点、SCN或还原点,速度远快于传统RMAN不完全恢复,无需还原数据文件,仅需应用闪回日志中的块前镜像。
启用闪回数据库
启用前提:
- 数据库处于归档模式
- 已配置快速恢复区(FRA)且空间充足
- 已设置闪回保留时间参数
操作步骤:
- 检查闪回数据库当前状态
sql
SELECT flashback_on FROM v$database;
- 配置快速恢复区(未配置时执行)
sql
ALTER SYSTEM SET db_recovery_file_dest_size = 10G SCOPE=BOTH;
ALTER SYSTEM SET db_recovery_file_dest = '/u01/app/oracle/fra' SCOPE=BOTH;
- 设置闪回保留目标时长(单位:分钟,默认1440分钟即24小时)
sql
ALTER SYSTEM SET db_flashback_retention_target = 1440;
- 启用闪回数据库(需在mount状态下执行)
sql
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE FLASHBACK ON;
- 打开数据库并验证状态
sql
ALTER DATABASE OPEN;
SELECT flashback_on FROM v$database;
创建还原点(Restore Point)
还原点可为特定时间点、SCN命名,方便后续闪回操作,分为普通还原点和保证还原点。
sql
-- 普通还原点(依赖Undo保留)
CREATE RESTORE POINT before_update;
-- 保证还原点(强制保留闪回日志,直到还原点被删除)
CREATE RESTORE POINT before_update GUARANTEE FLASHBACK DATABASE;
执行闪回数据库
- 基于时间戳闪回
sql
-- 关闭数据库并启动到mount状态
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
-- 闪回到10分钟前
FLASHBACK DATABASE TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '10' MINUTE);
-- 只读打开验证数据
ALTER DATABASE OPEN READ ONLY;
SELECT * FROM test.emp;
-- 验证通过后,resetlogs打开数据库
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE OPEN RESETLOGS;
- 基于SCN闪回
sql
FLASHBACK DATABASE TO SCN 1234567;
- 基于还原点闪回
sql
FLASHBACK DATABASE TO RESTORE POINT before_update;
监控与管理
sql
-- 查看最早可闪回的SCN和时间
SELECT oldest_flashback_scn, oldest_flashback_time FROM v$flashback_database_log;
-- 查看闪回日志空间使用情况
SELECT * FROM v$flash_recovery_area_usage WHERE FILE_TYPE = 'FLASHBACK LOG';
-- 删除还原点,释放闪回日志空间
DROP RESTORE POINT before_update;
⚠️ 闪回数据库限制:
- 无法解决介质故障(如数据文件丢失),仍需RMAN恢复
- 无法回退数据文件删除、收缩、大小变更等操作
- 控制文件必须与闪回日志兼容,备份恢复的控制文件无法直接用于闪回
- 闪回后必须使用
RESETLOGS打开数据库,创建新的化身
闪回删除(Flashback Drop)
闪回删除利用Oracle回收站功能,将被DROP的表及其关联对象(索引、约束等)保留在回收站中,支持快速恢复,无需依赖备份。
回收站启用与禁用
回收站默认开启,可通过以下命令查看与配置:
sql
-- 查看回收站状态
SHOW PARAMETER recyclebin;
-- 会话级临时禁用回收站
ALTER SESSION SET recyclebin = OFF;
查看回收站内容
sql
-- 查看当前用户回收站
SHOW RECYCLEBIN;
SELECT original_name, object_name, type, droptime FROM user_recyclebin;
-- 查看所有用户回收站(需DBA权限)
SELECT owner, original_name, object_name, type, droptime FROM dba_recyclebin;
恢复被删除的表
sql
-- 恢复表并保留原名
FLASHBACK TABLE emp TO BEFORE DROP;
-- 恢复表并重命名
FLASHBACK TABLE emp TO BEFORE DROP RENAME TO emp_old;
-- 通过回收站系统名称恢复
FLASHBACK TABLE "BIN$abcde==0" TO BEFORE DROP;
回收站清理
sql
-- 清空当前用户回收站
PURGE RECYCLEBIN;
-- 清空指定表空间的回收站
PURGE TABLESPACE users;
-- 永久删除表,不进入回收站
DROP TABLE emp PURGE;
⚠️ 注意事项:
- SYS用户和SYSTEM表空间中的对象不会进入回收站
- 回收站中的对象仍占用表空间,需定期清理释放空间
- 表被多次删除时,默认恢复最近删除的版本
- 索引、约束等依赖对象会随表恢复,但名称仍为回收站中的命名,需手动重命名
闪回查询(Flashback Query)
闪回查询利用Undo数据,查询过去某个时间点或SCN的表数据,不会修改当前数据,适用于数据比对、少量误删数据恢复场景。
基于时间戳的闪回查询
sql
-- 查询10分钟前的emp表数据
SELECT * FROM test.emp AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '10' MINUTE);
-- 查询指定时间点的数据
SELECT * FROM test.emp AS OF TIMESTAMP TO_TIMESTAMP('2026-03-20 14:30:00', 'YYYY-MM-DD HH24:MI:SS');
基于SCN的闪回查询
sql
-- 查询指定SCN时的数据
SELECT * FROM test.emp AS OF SCN 1234567;
利用闪回查询恢复误删数据
sql
-- 将误删除的数据重新插入原表
INSERT INTO test.emp
SELECT * FROM test.emp AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '10' MINUTE)
WHERE id NOT IN (SELECT id FROM test.emp);
COMMIT;
⚠️ 限制说明:
- 仅能查询表数据,无法查询DDL变更后的结构
- Undo数据可能被覆盖,查询太久远的数据会触发ORA-01555快照过旧错误
- 无法查询超过Undo保留期的数据
闪回版本查询(Flashback Version Query)
闪回版本查询可查看某行数据在指定时间范围内的所有历史版本,包含每次修改的时间、事务ID、操作类型等信息,用于追溯数据变更历史。
sql
SELECT versions_startscn, versions_starttime,
versions_endscn, versions_endtime,
versions_operation, versions_xid,
id, name
FROM test.emp VERSIONS BETWEEN TIMESTAMP
TO_TIMESTAMP('2026-03-20 14:00:00', 'YYYY-MM-DD HH24:MI:SS')
AND TO_TIMESTAMP('2026-03-20 15:00:00', 'YYYY-MM-DD HH24:MI:SS')
WHERE id = 1;
关键字段说明:
VERSIONS_OPERATION:操作类型,I(插入)、U(更新)、D(删除)VERSIONS_START*:该版本生效的SCN/时间VERSIONS_END*:该版本失效的SCN/时间,NULL表示为当前版本VERSIONS_XID:操作对应的事务ID
闪回事务查询(Flashback Transaction Query)
闪回事务查询可查看某个事务的详细信息,包括撤销该事务的SQL语句,用于精准回滚误操作事务。
-
通过闪回版本查询获取误操作的事务ID(
VERSIONS_XID) -
查询事务详情与撤销SQL
sql
SELECT xid, start_scn, start_timestamp, commit_scn, commit_timestamp,
operation, table_name, undo_sql
FROM flashback_transaction_query
WHERE xid = HEXTORAW('000200030000002A');
- 执行
undo_sql列中的语句,回滚误操作事务的影响。
闪回表(Flashback Table)
闪回表可将单张表(含索引、约束)恢复到过去的某个时间点或SCN,不影响其他数据库对象,通过Undo数据实现,要求表启用行移动功能。
- 启用表的行移动功能
sql
ALTER TABLE test.emp ENABLE ROW MOVEMENT;
- 执行闪回表操作
sql
-- 基于时间戳闪回
FLASHBACK TABLE test.emp TO TIMESTAMP (SYSTIMESTAMP - INTERVAL '30' MINUTE);
-- 基于SCN闪回
FLASHBACK TABLE test.emp TO SCN 1234567;
-- 基于还原点闪回
FLASHBACK TABLE test.emp TO RESTORE POINT before_update;
⚠️ 限制说明:
- SYS用户下的表无法执行闪回表操作
- 无法闪回带外键约束的表,除非同时闪回关联表或禁用约束
- 无法闪回执行过DDL操作(增删列、修改结构)的表
- 需拥有
FLASHBACK ANY TABLE系统权限或表的FLASHBACK对象权限
闪回数据归档(Flashback Data Archive)
闪回数据归档(FDA)用于长期保存表的历史数据,可保存数月甚至数年,不受Undo保留期限制,将历史版本存储在独立表空间中,适用于审计、合规性要求场景。
- 创建归档专用表空间
sql
CREATE TABLESPACE fda_data DATAFILE '/u01/app/oracle/oradata/RHEL7/fda_data01.dbf' SIZE 500M;
- 创建闪回数据归档
sql
-- 创建默认闪回归档,保留1年
CREATE FLASHBACK ARCHIVE DEFAULT fda_archive_1y TABLESPACE fda_data RETENTION 1 YEAR;
- 为表启用闪回归档
sql
-- 启用默认闪回归档
ALTER TABLE test.emp FLASHBACK ARCHIVE;
-- 启用指定闪回归档
ALTER TABLE test.emp FLASHBACK ARCHIVE fda_archive_1y;
- 归档历史数据查询
sql
-- 查询6个月前的历史数据
SELECT * FROM test.emp AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '6' MONTH);
- 闪回归档管理
sql
-- 查看所有闪回归档
SELECT * FROM dba_flashback_archive;
-- 修改归档保留时间
ALTER FLASHBACK ARCHIVE fda_archive_1y SET RETENTION 2 YEAR;
-- 为归档新增表空间
ALTER FLASHBACK ARCHIVE fda_archive_1y ADD TABLESPACE fda_data2;
-- 禁用表的闪回归档
ALTER TABLE test.emp NO FLASHBACK ARCHIVE;
-- 删除闪回归档
DROP FLASHBACK ARCHIVE fda_archive_1y;
闪回技术最佳实践
| 故障场景 | 推荐技术 | 核心注意事项 |
|---|---|---|
误删整表(DROP) |
Flashback Drop | 确保回收站未禁用,表未被PURGE永久删除 |
| 误更新/删除表数据 | Flashback Table 或 Flashback Query | 启用行移动,注意外键约束限制 |
| 整个数据库需回退到指定时间点 | Flashback Database | 提前开启闪回数据库,设置合理的保留时长 |
| 追溯数据变更历史、定位误操作 | Flashback Version Query / Flashback Transaction Query | 确保Undo保留足够时长,长期追溯建议使用FDA |
| 长期历史数据保存、合规审计 | Flashback Data Archive | 创建独立表空间,设置匹配合规要求的保留期 |
通用建议:
- 重要操作前创建还原点(尤其是保证还原点),便于快速回退
- 定期监控Undo表空间和闪回恢复区的使用情况,避免空间不足导致闪回失败
- 生产环境执行闪回操作前,先以只读方式验证数据正确性
- 闪回技术不能替代备份,需结合RMAN定期备份,应对介质故障
逻辑备份与恢复(expdp/impdp)
逻辑备份是将数据库中的对象及其数据导出为二进制dmp文件,需要时再导入数据库。与物理备份不同,逻辑备份不关心数据的物理存储,仅关注逻辑内容,常用于数据迁移、部分数据恢复、跨平台传输场景。
Oracle数据泵(expdp/impdp)是Oracle 10g后引入的新一代逻辑备份工具,支持高性能并行处理、内置压缩加密、闪回支持等特性,是生产环境推荐的逻辑备份方案。
| 特性 | 传统exp/imp | 数据泵expdp/impdp |
|---|---|---|
| 运行位置 | 客户端工具 | 服务端工具,仅能在数据库服务器运行 |
| 性能 | 较慢,单线程 | 支持并行,性能大幅提升 |
| 压缩 | 无内置压缩 | 内置COMPRESSION压缩功能 |
| 加密 | 不支持 | 支持ENCRYPTION加密功能 |
| 闪回支持 | 不支持 | 支持FLASHBACK_SCN/FLASHBACK_TIME |
| 作业管理 | 无 | 支持作业暂停、重启、实时监控 |
⚠️ 重要说明:exp导出的dmp文件仅能使用imp导入,expdp导出的dmp文件仅能使用impdp导入,两者互不兼容。
环境准备:目录对象
expdp/impdp必须使用数据库中的目录对象(Directory)指定dmp文件的存放位置。
- 操作系统创建备份目录并授权
bash
mkdir -p /u01/backup/dump
chown oracle:oinstall /u01/backup/dump
chmod 755 /u01/backup/dump
- 数据库中创建目录对象并授权
sql
-- 创建目录对象(需DBA权限)
CREATE OR REPLACE DIRECTORY dump_dir AS '/u01/backup/dump';
-- 为测试用户授予目录读写权限
GRANT READ, WRITE ON DIRECTORY dump_dir TO test;
-- 查看已创建的目录对象
SELECT * FROM dba_directories;
expdp导出示例
expdp常用核心参数说明:
| 参数 | 核心说明 | 示例 |
|---|---|---|
DIRECTORY |
目录对象名 | directory=dump_dir |
DUMPFILE |
输出文件名,支持%U自动扩展 |
dumpfile=exp_%U.dmp |
LOGFILE |
日志文件名 | logfile=exp.log |
FULL |
全库导出 | full=y |
SCHEMAS |
导出指定用户列表 | schemas=test |
TABLES |
导出指定表列表 | tables=emp,dept |
QUERY |
按条件过滤导出数据 | query=emp:"where id=1" |
CONTENT |
导出内容范围(ALL/DATA_ONLY/METADATA_ONLY) | content=data_only |
PARALLEL |
导出并行度 | parallel=4 |
COMPRESSION |
压缩级别 | compression=all |
FLASHBACK_TIME |
闪回导出指定时间点数据 | flashback_time="to_timestamp(...)" |
常用导出场景命令:
- 导出单表
bash
expdp test/test directory=dump_dir dumpfile=emp.dmp logfile=exp_emp.log tables=emp
- 按条件导出表数据
bash
expdp test/test directory=dump_dir dumpfile=emp_id1.dmp tables=emp query=\"where id=1\"
- 导出整个用户模式
bash
expdp system/oracle directory=dump_dir dumpfile=test_user.dmp schemas=test
- 仅导出表结构(不导出数据)
bash
expdp test/test directory=dump_dir dumpfile=emp_meta.dmp tables=emp content=metadata_only
impdp导入示例
impdp常用核心参数说明:
| 参数 | 核心说明 | 示例 |
|---|---|---|
REMAP_SCHEMA |
源用户映射到目标用户 | remap_schema=test:newuser |
REMAP_TABLESPACE |
源表空间映射到目标表空间 | remap_tablespace=tbs_test:users |
TABLE_EXISTS_ACTION |
表已存在时的处理方式(SKIP/APPEND/TRUNCATE/REPLACE) | table_exists_action=truncate |
TRANSFORM |
转换段属性 | transform=segment_attributes:n |
SQLFILE |
将DDL语句写入文件,不执行导入 | sqlfile=ddl.sql |
常用导入场景命令:
- 导入表(目标库表不存在)
bash
impdp test/test directory=dump_dir dumpfile=emp.dmp logfile=imp_emp.log tables=emp
- 表已存在时追加数据
bash
impdp test/test directory=dump_dir dumpfile=emp.dmp tables=emp table_exists_action=append
- 表已存在时先清空再导入
bash
impdp test/test directory=dump_dir dumpfile=emp.dmp tables=emp table_exists_action=truncate
- 导入到其他用户(目标用户需提前创建)
bash
# 提前创建目标用户并授权
SQL> CREATE USER test2 IDENTIFIED BY test2 DEFAULT TABLESPACE users;
SQL> GRANT CONNECT, RESOURCE TO test2;
# 执行导入并映射用户
impdp system/oracle directory=dump_dir dumpfile=test_user.dmp remap_schema=test:test2
- 生成DDL脚本,不执行实际导入
bash
impdp test/test directory=dump_dir dumpfile=emp.dmp sqlfile=/tmp/emp_ddl.sql
高级功能
- 并行处理
使用PARALLEL参数提升导出导入速度,需配合%U文件名替换符,确保dump文件数量不少于并行度。
bash
# 并行导出
expdp test/test directory=dump_dir dumpfile=exp_%U.dmp schemas=test parallel=4
# 并行导入
impdp test/test directory=dump_dir dumpfile=exp_%U.dmp schemas=test parallel=4
- 压缩导出
bash
expdp test/test directory=dump_dir dumpfile=emp_comp.dmp tables=emp compression=all
- 闪回导出(导出历史时间点数据)
bash
expdp test/test directory=dump_dir dumpfile=emp_before.dmp tables=emp flashback_time=\"to_timestamp('2026-03-20 10:00:00','yyyy-mm-dd hh24:mi:ss')\"
- 加密导出
bash
# 加密导出
expdp test/test directory=dump_dir dumpfile=emp_enc.dmp tables=emp encryption=all encryption_password=Secret123
# 加密导入(需提供相同密码)
impdp test/test directory=dump_dir dumpfile=emp_enc.dmp encryption_password=Secret123
- 网络链接直接导入(无中间dmp文件)
在目标库创建指向源库的数据库链接,直接通过网络导入,无需生成中间dmp文件。
sql
-- 目标库创建数据库链接
CREATE DATABASE LINK source_db CONNECT TO test IDENTIFIED BY test USING '源库TNS';
bash
# 直接通过网络链接导入
impdp test/test directory=dump_dir network_link=source_db schemas=test remap_schema=test:test2