Oracle 19c 备份与恢复

Oracle 19c 备份与恢复

本文档为Oracle 19c数据库备份与恢复流程,覆盖归档模式配置、用户管理备份、RMAN核心操作、多场景故障恢复、闪回技术、逻辑备份等核心内容。如有错误,欢迎批评指正。


环境准备与基础概念

备份恢复概述

数据库备份恢复是DBA核心职责,是保障数据安全的关键防线。Oracle提供了多种备份恢复方式,各有其适用场景。

备份方式 特点 适用场景
用户管理的备份 直接使用操作系统命令复制物理文件,分为冷备(一致性)和热备(非一致性) 学习原理、小型环境、RMAN不可用时的备选方案
RMAN 备份 Oracle 内置工具,支持增量备份、压缩、加密、自动化管理 生产环境首选,支持复杂恢复需求
逻辑备份 exp/impexpdp/impdp,导出为逻辑文件(dmp) 数据迁移、部分数据导出、跨平台传输

恢复分为两种核心类型:

  • 完全恢复:利用备份和归档日志,将数据库恢复到故障前的最新状态,不丢失任何已提交事务。

  • 不完全恢复:将数据库恢复到过去的某个时间点、SCN或日志序列,会丢失之后的数据,适用于误操作(如删表、truncate)或日志丢失的场景。

环境要求

  • 已安装Oracle 19c数据库软件,并创建了对应数据库实例
  • 操作系统:Linux 7+
  • 建议创建普通用户(如bakuser)用于存放备份文件

开启归档模式(自定义归档路径)

归档模式是数据库能够进行联机备份的基础,非归档模式下仅能进行冷备,且恢复点仅限于最近一次备份,生产环境必须开启归档模式。

操作步骤:

  1. 创建归档日志存放目录
bash 复制代码
mkdir -p /u01/archive
chown oracle:oinstall /u01/archive
chmod 755 /u01/archive
  1. 查看当前归档状态
sql 复制代码
archive log list;

未开启归档时,输出会显示Database log mode No Archive Mode

  1. 关闭数据库,确保一致性
sql 复制代码
shutdown immediate;
  1. 启动数据库到mount状态
sql 复制代码
startup mount;
  1. 设置自定义归档路径
sql 复制代码
alter system set log_archive_dest_1='location=/u01/archive' scope=both;
  1. 启用归档模式
sql 复制代码
alter database archivelog;
  1. 打开数据库
sql 复制代码
alter database open;
  1. 验证归档状态
sql 复制代码
archive log list;

开启成功后,输出会显示Database log mode Archive ModeAutomatic archival Enabled

⚠️ 注意事项:

  • 修改log_archive_dest_n参数后,使用scope=both可立即生效,建议重启数据库确保所有后台进程正确识别新路径
  • 归档目录必须提前创建,且Oracle用户需拥有读写权限,否则数据库无法归档最终会挂起
  • 首次开启归档后,建议立即执行一次全库冷备,用于后续恢复测试
  • 若同时使用快速恢复区(FRA),可保留db_recovery_file_dest用于存放闪回日志和RMAN备份集,与归档路径独立配置

可选配置:快速恢复区(FRA)

快速恢复区是Oracle推荐的集中存储备份、闪回日志的区域,可简化管理,与归档路径相互独立,无需闪回数据库或集中管理备份可跳过此步骤。

操作步骤:

  1. 创建FRA目录
bash 复制代码
mkdir -p /u01/app/oracle/fra
chown oracle:oinstall /u01/app/oracle/fra
chmod 755 /u01/app/oracle/fra
  1. 设置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;
  1. 查看FRA配置
sql 复制代码
show parameter db_recovery_file;

创建测试数据

为后续恢复验证,创建测试表空间、用户和测试数据:

  1. 创建测试表空间
sql 复制代码
create tablespace tbs_test datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' size 100m;
  1. 创建测试用户并授权
sql 复制代码
create user test identified by test default tablespace tbs_test;
grant connect, resource, dba to test;
  1. 连接测试用户,创建测试表并插入数据
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;
  1. 验证测试数据
sql 复制代码
select * from emp;

创建备份目录

bash 复制代码
mkdir -p /u01/backup/rman
chown oracle:oinstall /u01/backup/rman
chmod 755 /u01/backup/rman

用户管理的备份与恢复

用户管理的备份直接通过操作系统命令复制数据库物理文件,理解该方法有助于深入掌握备份恢复底层原理,也是应对RMAN不可用等极端场景的必备技能。

冷备份(一致性备份)

冷备要求数据库完全关闭,所有文件头部SCN一致,还原后无需恢复即可直接打开,适用于非归档模式或需要静态备份的场景。

操作步骤:

  1. 查询数据库核心文件位置
sql 复制代码
-- 控制文件位置
SELECT name FROM v$controlfile;
-- 数据文件位置
SELECT name FROM v$datafile;
-- 联机重做日志位置
SELECT member FROM v$logfile;
  1. 关闭数据库,确保一致性
sql 复制代码
shutdown immediate;
  1. 创建备份目录并复制核心文件
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/
  1. 验证备份文件
bash 复制代码
ls -l /u01/backup/cold_backup_$(date +%Y%m%d)/
  1. 启动数据库
sql 复制代码
startup;

⚠️ 注意事项:

  • 冷备期间数据库业务中断,生产环境通常不允许使用
  • 联机重做日志文件备份非必须,恢复时可通过归档日志重建,建议备份用于不完全恢复场景
  • 备份后建议使用dbv工具验证数据文件完整性

热备份(表空间备份模式)

热备在数据库打开状态下执行,要求数据库处于归档模式。核心原理是将表空间置于备份模式,冻结该表空间数据文件头部SCN,同时将修改块的完整前镜像写入重做日志,确保备份文件可通过归档恢复至一致状态。

操作步骤:

  1. 创建热备份目录并授权
bash 复制代码
mkdir -p /u01/backup/hot_backup
chown oracle:oinstall /u01/backup/hot_backup
chmod 755 /u01/backup/hot_backup
  1. 将目标表空间置于备份模式
sql 复制代码
alter tablespace tbs_test begin backup;
  1. 复制该表空间对应的数据文件
bash 复制代码
cp -v /u01/app/oradata/RHEL7/tbs_test01.dbf /u01/backup/hot_backup/
  1. 结束表空间备份模式
sql 复制代码
alter tablespace tbs_test end backup;

⚠️ 关键说明:

  • begin backup会触发检查点,将脏数据写入磁盘,并记录开始备份的SCN
  • 备份过程中数据文件可正常修改,修改内容的完整前镜像会记录到重做日志,用于恢复时应用
  • 若备份过程中数据库异常关闭,下次启动会报错文件需要介质恢复,可执行alter database end backup;强制结束备份模式,再应用归档日志恢复

用户管理的恢复操作(数据文件丢失场景)

模拟故障:删除测试表空间对应的数据文件,数据库仍可运行,但访问该文件会报错。

恢复步骤:

  1. 将损坏的数据文件脱机
sql 复制代码
alter database datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' offline;
  1. 从备份还原数据文件到原路径
bash 复制代码
cp /u01/backup/hot_backup/tbs_test01.dbf /u01/app/oradata/RHEL7/
  1. 恢复数据文件,应用归档日志
sql 复制代码
recover datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf';
  1. 将数据文件联机
sql 复制代码
alter database datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' online;
  1. 验证数据完整性
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命令设置,生产环境推荐配置如下:

  1. 设置备份保留策略
sql 复制代码
-- 保留最近2份有效备份
configure retention policy to redundancy 2;
  1. 开启控制文件自动备份(强烈推荐)
sql 复制代码
-- 每次备份后或数据库结构变化时,自动备份控制文件和spfile
configure controlfile autobackup on;
-- 设置控制文件自动备份路径与格式
configure controlfile autobackup format for device type disk to '/u01/backup/rman/cf_%F';
  1. 设置默认备份路径
sql 复制代码
configure channel device type disk format '/u01/backup/rman/%U';
  1. 启用备份优化
sql 复制代码
-- 自动跳过未变化的文件,如只读表空间
configure backup optimization on;
  1. 配置快照控制文件位置
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元数据,可管理多个目标数据库、长期保留备份历史,适用于多数据库管理场景。

  1. 恢复目录数据库中创建表空间与用户
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;
  1. RMAN中创建恢复目录
bash 复制代码
rman catalog rman/rman@catdb
sql 复制代码
create catalog tablespace rcat;
  1. 注册目标数据库
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完全恢复实战

完全恢复核心概念

完全恢复指将数据库恢复到故障发生时的最新状态,不丢失任何已提交事务,核心分为两个步骤:

  1. Restore:从备份中还原损坏或丢失的数据文件
  2. Recover:应用归档日志和联机重做日志,将数据文件前滚到最新SCN

RMAN会自动识别所需的备份和归档日志,无需手动查找。

数据文件丢失恢复(在线恢复)

模拟故障:删除测试表空间对应的数据文件,数据库仍在运行,访问该表空间会报错。

恢复步骤:

  1. 将损坏的数据文件脱机
sql 复制代码
alter database datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' offline;
  1. RMAN中还原并恢复数据文件
sql 复制代码
restore datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf';
recover datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf';
  1. 将数据文件联机
sql 复制代码
alter database datafile '/u01/app/oradata/RHEL7/tbs_test01.dbf' online;
  1. 验证数据完整性
sql 复制代码
select * from test.emp;

表空间丢失恢复

若整个表空间的所有数据文件都丢失,可直接对表空间执行在线恢复。

恢复步骤:

  1. 将目标表空间脱机
sql 复制代码
alter tablespace tbs_test offline immediate;
  1. RMAN中还原并恢复表空间
sql 复制代码
restore tablespace tbs_test;
recover tablespace tbs_test;
  1. 将表空间联机
sql 复制代码
alter tablespace tbs_test online;
  1. 验证表空间可用性
sql 复制代码
select * from test.emp;

SYSTEM表空间丢失恢复

SYSTEM表空间存放数据库数据字典,无法在线脱机,必须在mount状态下执行恢复。

模拟故障:删除system01.dbf数据文件,数据库重启后无法打开,仅能进入mount状态。

恢复步骤:

  1. 强制关闭异常数据库
sql 复制代码
SHUTDOWN ABORT;
  1. 启动数据库到mount状态
sql 复制代码
startup mount;
  1. RMAN中还原并恢复SYSTEM表空间
sql 复制代码
restore datafile 1;
recover datafile 1;
  1. 打开数据库
sql 复制代码
alter database open;

控制文件丢失恢复

控制文件存储数据库物理结构信息,全部丢失后数据库仅能启动到nomount状态,必须从备份恢复。

场景前提:SPFILE仍存在,所有控制文件全部丢失/损坏,数据库已关闭。

恢复步骤:

  1. 强制关闭异常数据库
sql 复制代码
SHUTDOWN ABORT;
  1. 启动数据库到nomount状态
sql 复制代码
startup nomount;
  1. 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;提前查询并记录。

  1. 将数据库启动到mount状态
sql 复制代码
alter database mount;
  1. 还原并恢复数据库(确保数据一致性)
sql 复制代码
restore database;
recover database;
  1. 以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:数据库已关闭,无法启动
  1. 创建最小化PFILE文件
bash 复制代码
echo "db_name=rhel7" > $ORACLE_HOME/dbs/initrhel7.ora
  1. 使用最小化PFILE启动到nomount状态
sql 复制代码
startup nomount pfile='$ORACLE_HOME/dbs/initrhel7.ora';
  1. 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';
  1. 关闭实例,使用恢复后的SPFILE启动数据库
sql 复制代码
shutdown immediate;
startup;

RMAN不完全恢复

不完全恢复用于恢复误操作(如误删表、truncate表)或丢失部分归档日志的场景,可将数据库恢复到过去的某个时间点、SCN或日志序列,会丢失目标时间点之后的数据。

恢复前提:

  • 数据库处于归档模式,已开启归档日志
  • 拥有完整的级别0备份/全备,以及自备份以来所有连续完整的归档日志
  • 数据库可正常启动到mount状态

基于时间点的恢复

场景示例:2026-03-20 15:39:22 测试用户误删除emp表,需恢复到删除操作前的2026-03-20 15:38:20,找回丢失数据。

恢复步骤:

  1. 关闭数据库并启动到mount状态
sql 复制代码
shutdown immediate;
startup mount;
  1. RMAN中执行时间点不完全恢复
sql 复制代码
run {
set until time "to_date('2026-03-20 15:38:20','yyyy-mm-dd hh24:mi:ss')";
restore database;
recover database;
}
  1. 以resetlogs方式打开数据库
sql 复制代码
alter database open resetlogs;

⚠️ 注意事项:

  • 时间格式必须与NLS设置匹配,建议使用to_date函数明确指定格式
  • set until time指定的时间需早于误操作时间,建议预留1-2秒余量
  • 恢复完成后必须立即执行全库备份,resetlogs后之前的备份可能不再适用

基于SCN的恢复

若已知误操作前的SCN(系统改变号),可基于SCN执行恢复,精度高于时间点恢复。

恢复步骤:

  1. 查询当前数据库SCN
sql 复制代码
commit;
select current_scn from v$database;
  1. 关闭数据库并启动到mount状态
sql 复制代码
shutdown immediate;
startup mount;
  1. RMAN中执行SCN不完全恢复(恢复到误操作SCN-1)
sql 复制代码
run {
set until scn 1234566;
restore database;
recover database;
}
  1. 以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)且空间充足
  • 已设置闪回保留时间参数

操作步骤:

  1. 检查闪回数据库当前状态
sql 复制代码
SELECT flashback_on FROM v$database;
  1. 配置快速恢复区(未配置时执行)
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;
  1. 设置闪回保留目标时长(单位:分钟,默认1440分钟即24小时)
sql 复制代码
ALTER SYSTEM SET db_flashback_retention_target = 1440;
  1. 启用闪回数据库(需在mount状态下执行)
sql 复制代码
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE FLASHBACK ON;
  1. 打开数据库并验证状态
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;
执行闪回数据库
  1. 基于时间戳闪回
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;
  1. 基于SCN闪回
sql 复制代码
FLASHBACK DATABASE TO SCN 1234567;
  1. 基于还原点闪回
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语句,用于精准回滚误操作事务。

  1. 通过闪回版本查询获取误操作的事务ID(VERSIONS_XID)

  2. 查询事务详情与撤销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');
  1. 执行undo_sql列中的语句,回滚误操作事务的影响。

闪回表(Flashback Table)

闪回表可将单张表(含索引、约束)恢复到过去的某个时间点或SCN,不影响其他数据库对象,通过Undo数据实现,要求表启用行移动功能。

  1. 启用表的行移动功能
sql 复制代码
ALTER TABLE test.emp ENABLE ROW MOVEMENT;
  1. 执行闪回表操作
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保留期限制,将历史版本存储在独立表空间中,适用于审计、合规性要求场景。

  1. 创建归档专用表空间
sql 复制代码
CREATE TABLESPACE fda_data DATAFILE '/u01/app/oracle/oradata/RHEL7/fda_data01.dbf' SIZE 500M;
  1. 创建闪回数据归档
sql 复制代码
-- 创建默认闪回归档,保留1年
CREATE FLASHBACK ARCHIVE DEFAULT fda_archive_1y TABLESPACE fda_data RETENTION 1 YEAR;
  1. 为表启用闪回归档
sql 复制代码
-- 启用默认闪回归档
ALTER TABLE test.emp FLASHBACK ARCHIVE;

-- 启用指定闪回归档
ALTER TABLE test.emp FLASHBACK ARCHIVE fda_archive_1y;
  1. 归档历史数据查询
sql 复制代码
-- 查询6个月前的历史数据
SELECT * FROM test.emp AS OF TIMESTAMP (SYSTIMESTAMP - INTERVAL '6' MONTH);
  1. 闪回归档管理
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文件的存放位置。

  1. 操作系统创建备份目录并授权
bash 复制代码
mkdir -p /u01/backup/dump
chown oracle:oinstall /u01/backup/dump
chmod 755 /u01/backup/dump
  1. 数据库中创建目录对象并授权
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(...)"

常用导出场景命令:

  1. 导出单表
bash 复制代码
expdp test/test directory=dump_dir dumpfile=emp.dmp logfile=exp_emp.log tables=emp
  1. 按条件导出表数据
bash 复制代码
expdp test/test directory=dump_dir dumpfile=emp_id1.dmp tables=emp query=\"where id=1\"
  1. 导出整个用户模式
bash 复制代码
expdp system/oracle directory=dump_dir dumpfile=test_user.dmp schemas=test
  1. 仅导出表结构(不导出数据)
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

常用导入场景命令:

  1. 导入表(目标库表不存在)
bash 复制代码
impdp test/test directory=dump_dir dumpfile=emp.dmp logfile=imp_emp.log tables=emp
  1. 表已存在时追加数据
bash 复制代码
impdp test/test directory=dump_dir dumpfile=emp.dmp tables=emp table_exists_action=append
  1. 表已存在时先清空再导入
bash 复制代码
impdp test/test directory=dump_dir dumpfile=emp.dmp tables=emp table_exists_action=truncate
  1. 导入到其他用户(目标用户需提前创建)
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
  1. 生成DDL脚本,不执行实际导入
bash 复制代码
impdp test/test directory=dump_dir dumpfile=emp.dmp sqlfile=/tmp/emp_ddl.sql

高级功能

  1. 并行处理

使用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
  1. 压缩导出
bash 复制代码
expdp test/test directory=dump_dir dumpfile=emp_comp.dmp tables=emp compression=all
  1. 闪回导出(导出历史时间点数据)
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')\"
  1. 加密导出
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
  1. 网络链接直接导入(无中间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

相关推荐
于歌8521 小时前
Oracle批处理操作方法
数据库·oracle
hhb_6183 小时前
VB老旧项目代码重构与性能优化实战方案
oracle·性能优化·重构
whn19773 小时前
虚拟机搭建oracle 19c rac 点滴
数据库·oracle
鸽芷咕4 小时前
KingbaseES数据类型完全指南:从基础CHAR到JSON/XML/几何类型
xml·oracle·json
Irene19915 小时前
大数据开发场景下,总结并翻译 Oracle 中常见的错误(补充其他错误码:适合初学者)
大数据·oracle
摇滚侠14 小时前
expdp 查看帮助
java·数据库·oracle
zxrhhm17 小时前
Oracle 索引完整指南
数据库·oracle
折哥的程序人生 · 物流技术专研19 小时前
从“卡死”到“秒过”:WMS销售数据跨库回填的极限优化之旅
数据库·机器学习·oracle
马优晨21 小时前
oracle 的 Schema
数据库·oracle·oracle的schema·数据库的 schema·oracle的schema数据