Oracle数据库归档模式详解:开启步骤、配置与运维实践
2026/9/17 12:31:41 网站建设 项目流程

1. 归档模式到底解决了什么问题:从一次数据库故障说起

做Oracle DBA这些年,我遇到过不少因为没开归档模式而把团队逼到墙角的场景。印象最深的一次是刚接手某套业务系统时,凌晨三点接到电话说数据库起不来了,检查发现控制文件和联机重做日志全部损坏。因为这套库一直跑在非归档模式,最后一次全备还是两个月前做的,也就是说恢复出来会丢掉整整两个月的业务数据。当时那种头皮发麻的感觉,到现在都记得。

这就是归档模式的价值所在——它解决的是"数据库文件不幸全坏之后,数据究竟能找回多少"的问题。非归档模式下,数据库只保留当前正在使用的联机重做日志(Online Redo Log),日志切换后会直接覆盖旧日志,历史操作记录根本存不下来。一旦数据文件损坏,你手里的恢复介质只有之前做过的全量备份,备份之后的所有变更全部丢失。而开启归档模式后,系统会将每次切换出来的联机日志完整复制到指定目录,形成连续的归档日志(Archive Log)。配合全量备份,你可以在任何时间点把数据库恢复到过去的某个状态,丢失窗口被压缩到几乎为零。

简单说,归档模式就是给数据库的"操作流水账"加了一份永不删除的备份。这份流水账既用于介质恢复,也支撑DataGuard容灾构建、逻辑误操作找回、基于时间点的恢复等关键场景。对那些数据是核心资产的企业,这几乎等于保险单。对个人学习者来说,理解并掌握归档模式的操作,也是从"会装数据库"迈向"会管数据库"的必经之路。

这篇文章我会从实际运维视角出发,手把手讲清楚三件事:当前数据库处于什么模式、如何安全开启归档模式、开启后还要配套做好哪些设置和监控。最后再把我在实际环境中踩过的一些坑和排查思路一并整理出来。

2. 登录数据库先看三处:判断当前是否处于归档模式

在动手做任何配置之前,第一步永远是确认现状。Oracle判断实例是否处于归档模式,主要通过三个途径来查看,结果是一致的,但适用场景略有不同。

2.1 用archive log list命令快速确认

这是最直接、最快的方式。以sysdba身份登入数据库,执行:

sqlplus / as sysdba SQL> archive log list;

正常情况下输出类似这样:

Database log mode No Archive Mode Automatic archival DISABLED Archive destination /u01/app/oracle/oradata/ORCL/archive Oldest online log sequence 10 Next log sequence to archive 12 Current log sequence 12

重点看第一行和第二行。Database log mode显示No Archive Mode,说明当前是非归档模式;如果显示Archive Mode,则说明已经开启。Automatic archival一栏对应的是数据库是否启用了自动归档,生产环境必须保持ENABLED状态,否则即使开了归档模式,日志切换时也不会自动生成归档文件,等于白开。

这一命令的本质是读取控制文件里的数据库属性和当前日志状态,所以它不需要数据库处于open状态也能执行,在mount阶段同样可用。这给后续开启归档过程中的反复确认提供了很大便利。

2.2 查询v$database视图确认模式

如果你习惯用SQL来确认,可以查询:

SQL> select name, log_mode, open_mode from v$database; NAME LOG_MODE OPEN_MODE --------- ------------ ------------ ORCL ARCHIVELOG READ WRITE

LOG_MODE字段只有两种取值:ARCHIVELOGNOARCHIVELOG,分别对应归档模式和非归档模式。OPEN_MODE用来辅助确认库当前的打开状态——做归档切换操作时,数据库必须处于MOUNTED状态才算进入可变更阶段,这个等下讲开启步骤时会详细展开。

v$database视图查询有个小细节:通常只是select log_mode的话,普通用户也能执行;但如果是整个视图全字段查询,部分版本会要求具备足够权限。实际使用中如果遇到用户权限不足的报错,直接用sys用户查即可。

2.3 检查后台进程和归档文件目录

还有一个辅助确认手段:查看是否存在归档后台进程。非归档模式下,数据库不会有ARC0之类的归档进程;开启归档后,通常能看到类似ora_arc0_ORCL的进程在运行。

ps -ef | grep ora_arc | grep -v grep

如果没有任何输出,大概率还是非归档模式。另外也可以顺带看一眼归档目录里有没有已生成的.arc.dbf格式的归档日志文件。目录位置受log_archive_destdb_recovery_file_dest参数控制,后文会专门展开说明。

这三种方式本质上是从控制文件、动态性能视图、操作系统进程三个不同视角去确认同一个事实。日常巡检我习惯先跑archive log list,因为它信息量最全、最快;如果需要写脚本做自动化检测,则用v$database视图更规范;当怀疑归档进程异常时,结合进程检查能更快定位问题。

3. 从非归档切到归档的完整操作:关键一步是重启到mount状态

确认当前是非归档模式之后,开启归档的过程并不复杂,但操作顺序一旦错乱,轻则报错,重则影响可用性。完整流程分为四步:关闭数据库、启动到mount状态、切换归档模式、打开数据库。下面逐步拆解。

3.1 第一步:干净地关闭数据库实例

执行开启归档操作前,需要先关闭数据库实例。这里必须用干净关闭(clean shutdown)方式,也就是:

SQL> shutdown immediate;

shutdown immediate会回滚未提交事务、断开所有会话连接、关闭实例,整个过程不会产生实例恢复动作,数据文件、控制文件完全一致。不建议用shutdown abort,因为那相当于强制断电,下次启动会走崩溃恢复流程,虽然数据不会丢,但会让下面的操作多出很多不确定性。

如果数据库中还有活跃的长时间事务,shutdown immediate可能会等待事务回滚完成,耗时较长。这时可以通过v$session视图查看哪些会话还没断开,必要时与业务方确认是否可以强制终止会话。生产环境做这种操作前,一定要提前发变更通知,避免业务侧不知情的情况下连接被掐断。

3.2 第二步:启动到mount状态,让实例读取控制文件

数据库关闭后,执行:

SQL> startup mount;

这一步的作用是启动实例并装载数据库,但没有打开数据文件。mount阶段下,Oracle可以访问控制文件,从而识别数据库结构,但这个状态下业务无法访问数据。开启归档模式本质上是修改控制文件中记录的数据库持久化属性,所以必须在这个阶段操作。直接以open状态尝试执行alter database archivelog,一定会报ORA-01126之类的错误。

startup mount执行成功后,可以用之前的archive log list再次确认一遍当前还是非归档状态,顺便注意Current log sequence这个数值,方便后续对比。

3.3 第三步:执行alter database archivelog

mount状态下执行:

SQL> alter database archivelog;

这一条命令是整个过程的核心。它的作用是把数据库的日志模式从非归档切换为归档模式,并同步更新控制文件里对应的属性。执行成功后,再跑一次archive log list,会看到:

Database log mode Archive Mode Automatic archival ENABLED

到这里,归档模式已经开启。注意此时数据库还处于mount状态,业务还不能访问,需要继续下一步把数据库打开。

3.4 第四步:打开数据库并做基本验证

执行:

SQL> alter database open;

数据库正常打开后,建议做一轮验证,确认归档链路是真的通的:

  1. 执行archive log list确认模式为Archive ModeAutomatic archivalENABLED
  2. 手动触发一次日志切换,观察归档文件是否真的生成:
SQL> alter system switch logfile;
  1. 查看归档目录,确认新生成的文件时间戳是刚才切换的,而不是老旧的遗留文件。

这三步做完,才算真正完成了归档模式的开启。很多初学者执行完alter database archivelog就以为大功告成,结果忘了检查Automatic archival是否为ENABLED,或者忘了确认归档文件实际落盘,等到需要恢复时才发现归档链路根本没通,那时候就非常被动了。

整个操作流程对库里数据没有任何影响,挂载和打开的过程也不会触发数据搬迁,时长主要取决于shutdown immediate的收尾速度。对正常业务库而言,整个过程一般在几分钟内就能完成,但前提是提前做好业务停机窗口的沟通。

4. 开启归档后的首选配置:归档路径、格式与闪回区规划

很多文章讲完alter database archivelog就收笔了,但以我的运维经验来看,真正拉开新手和熟手差距的,恰恰是归档开启之后这一堆配套参数。归档模式只是给了你一颗"种子",怎么把归档日志这个东西管好,让它既安全又不撑爆磁盘,才是后续运维的重头戏。

4.1 归档路径参数:log_archive_dest与log_archive_dest_n

Oracle归档日志要写到哪个目录,并不是自动分配的,而是由参数决定。最经典的参数是log_archive_dest,指定一个本地目录:

SQL> alter system set log_archive_dest='/u01/arch/orcl' scope=both;

生产环境我强烈建议用log_archive_dest_n系列参数,它可以同时配置多个归档路径,实现冗余:

SQL> alter system set log_archive_dest_1='location=/u01/arch/orcl mandatory' scope=both; SQL> alter system set log_archive_dest_2='location=/u02/arch_backup optional' scope=both;

其中mandatory表示这个归档路径是强制的,日志必须成功归档到这里,否则日志切换会被阻塞;optional表示可选路径,归档失败不影响日志切换。为了数据安全,主路径建议设置成mandatory,备份路径设置为optional,这样既能保证核心归档一定落盘,又不至于因为备份盘故障拖累整个库。

需要留意一点:如果设置了多个归档路径,Oracle要求至少有一个路径标记为mandatory。如果全部是optional,系统会隐式将其中一个视为强制路径,但这种隐式行为容易产生误解,不如显式配置来得清晰。

4.2 归档文件命名格式:log_archive_format

log_archive_format参数控制归档日志的文件名格式。默认格式在不同版本里略有差异,但常见形式类似:

arch_%t_%s_%r.arc

其中%t代表线程号(RAC环境多个实例时为1、2、3...),%s代表日志序列号,%r代表resetlogs ID。建议保持默认,不要轻易改动。这里重点提醒:如果数据库发生过不完全恢复并使用了resetlogs,日志序列号会重置,%r能让你区分不同"世代"的同序列号日志,这对恢复路径的选择至关重要。

4.3 闪回恢复区:db_recovery_file_dest_size的合理性

归档日志既可以写到log_archive_dest指定的路径,也可以写到数据库的快速恢复区(Fast Recovery Area),后者由db_recovery_file_destdb_recovery_file_dest_size两个参数控制:

SQL> alter system set db_recovery_file_dest='/u03/fra' scope=both; SQL> alter system set db_recovery_file_dest_size=512G scope=both;

这里有个非常经典的坑:默认情况下,如果设置了快速恢复区,那么log_archive_dest即使配置了,归档日志也可能优先写到快速恢复区。准确说,在Oracle 10g之后,如果不显式指定log_archive_dest_n,归档日志的默认落点就是快速恢复区。很多DBA只设置了db_recovery_file_dest,没设置db_recovery_file_dest_size,或者大小设置得过小,结果归档日志写满恢复区后,整个数据库直接hang住,任何提交操作都动不了。这是我见过最多的"开完归档后库突然卡死"的原因,没有之一。

所以我的建议是:要么完全走log_archive_dest_n指定独立目录,要么完全走快速恢复区,并做好db_recovery_file_dest_size的空间规划。规划时不能只看当前库有多大数据量,要按"一天产生多少日志量 × 预期保留天数"去估算。举个例子,如果业务高峰期每小时产生10GB日志,一天就是240GB,保留三天至少需要720GB,此时设置db_recovery_file_dest_size=1024G并配合定时备份清理才合理。快速恢复区里的空间是共享的,不仅归档日志会占,控制文件自动备份、RMAN备份集都可能占用,所以预留空间时一定要留出至少30%的余量。

另外还有一个容易被忽略的参数:db_flashback_retention_target。如果数据开启了闪回数据库(Flashback Database)功能,快速恢复区还需要额外承载闪回日志。这部分空间需求和归档日志相互叠加,配置时需要一并考虑。

4.4 归档空间满了会发生什么:理解LGWR的阻塞机制

关于归档空间满这个问题,值得多说几句。很多刚接触Oracle的人会有一个错误认知:归档目录满了,最多就是归档不写而已,数据库还能正常跑。实际情况完全不是这样。当mandatory归档路径写不进去时,LGWR进程在日志切换时无法完成归档确认,这时日志切换会被阻塞,然后又因为日志无法复用,整个数据库的DML操作会被卡住,表现为所有写事务全部挂起,只有读操作还勉强能执行。这个状态非常危险,因为一旦出现,连正常的shutdown immediate都可能因为活跃事务挂起而无法顺利完成。

因此,开启归档模式后,监控归档空间使用率是第一优先级的事情。常见的监控手段是查询v$archive_dest视图看归档目标的状态,结合操作系统层面的磁盘空间监控,双管齐下:

SQL> select destination, status, error from v$archive_dest where status='VALID';

当磁盘使用率达到80%以上时就要着手清理,超过90%时必须介入处理。清理手段包括:用RMAN删除已备份的归档日志、调整归档保留策略、扩容磁盘或增加新的归档路径。具体做法后面第六部分会详细说。

5. 归档模式上线后的维护清单:监控、清理与备份策略

把归档模式开起来只是第一步,真正的挑战在于日复一日地维护它。归档日志这个文件类型比较特殊——它永远在产生,而且只增不减,如果不做清理,再大的磁盘也会有被写满的一天。这里列一份我个人日常维护归档环境的清单,照着做基本不会出大问题。

5.1 监控归档生成速率与空间消耗

归档生产速率的监控可以结合两个层面来查:一个是基础视图,一个是操作系统层面。

在Oracle里,归档日志的生成记录存在v$archived_log视图中,可以按天统计生成量:

select trunc(completion_time) day, count(*) cnt, round(sum(blocks*block_size)/1024/1024/1024,2) gb from v$archived_log group by trunc(completion_time) order by day desc;

另外,v$log_history视图记录了每一次日志切换的历史信息,通过对比first_time的间隔,可以评估日志切换频率。如果切换频率异常高,比如每几分钟就切一次,可能导致归档文件碎片化严重,还会加大数据库的检查点压力。正常情况下,建议日志切换间隔至少在15到30分钟以上,如果切换过于频繁,就要考虑增大联机日志文件的大小,或者检查是否存在业务量暴增、某些操作反复刷日志的问题。

5.2 定时清理归档日志的两种稳妥做法

清理归档日志的手段主要有两种,一种是手工用RMAN删除已经安全备份的归档文件,另一种是配置归档日志删除策略,让数据库更自动化地去管理。这里我重点强调一个原则:清理归档日志必须以"已经被备份或已被DataGuard端同步"为前提,绝不能无脑按时间或数量删除

手工清理的典型RMAN命令:

RMAN> delete archivelog all completed before 'sysdate - 7';

这条命令会删除7天之前的全部归档日志。风险在于:如果这7天内的全备或增量备份还没做,删除之后就失去了基于时间点恢复的能力。更稳妥的写法是:

RMAN> delete noprompt archivelog all backed up 2 times to device type disk completed before 'sysdate - 3';

它只删除"已经被备份过至少2次、而且生成时间在3天之前"的归档。注意backed up 2 times是RMAN备份记录,如果从来没做过RMAN备份,这个条件不会匹配,也就不会误删任何文件。

如果配置了快速恢复区,还可以使用Oracle的归档日志删除策略:

RMAN> configure archivelog deletion policy to backed up 1 times to device type disk;

配置了删除策略后,当快速恢复区空间不足时,Oracle会按照策略自动选择可删除的归档文件,优先清理已备份的副本,减轻人工干预压力。这对7x24的生产系统非常友好。

5.3 归档日志与RMAN备份的节奏配合

开了归档模式后,RMAN备份的核心思想就变成了"全量+增量+归档日志"的组合拳。一套比较通用的备份策略大致如下:

  • 每周日凌晨做一次0级全备(level 0)
  • 每天晚上做一次1级增量备份(level 1)
  • 每30分钟或1小时备份一次归档日志(backup archivelog
  • 备份动作完成后,按策略删除已备份的归档

这样做的好处是:一旦数据文件损坏,可以先恢复最近的全备,再应用增量备份,最后追补最后的归档日志,实现数据库恢复到故障前一刻。没有归档日志支撑的RMAN备份只能恢复到备份完成的时间点,两者能力差距天差地别。

如果你在搭建DataGuard环境,归档日志的传递是主备同步的根基。主库的归档进程需要将日志传到备库节点,备库再通过MRP进程应用日志。这种场景下,主库归档日志的清理策略还要考虑备库是否已经接收到对应日志,通常可以用delete archivelog all completed before 'sysdate - 1'结合备库同步校验来操作,避免主库日志清得太快,备库还没来得及拉走。

5.4 定期做一次真实恢复演练

无论配置多完善,没有经过验证的备份和归档链路,在真正出故障时都不敢保证能用。我的习惯是每季度找一台测试机做一次完整的恢复演练:先用RMAN把最近的全备恢复到测试环境,再应用最近的增量备份,最后追补归档日志,打开数据库,对比生产环境的关键数据记录是否一致。这个流程看着简单,但一旦实际执行,经常能发现备份脚本里路径写错、归档日志有缺失、参数文件不完整等平时根本暴露不出来的问题。归档模式的开启只是给数据安全提供了一个基础设施,只有当恢复链路全程畅通时,这个基础设施才真正有意义。

6. 归档开启过程中常见的三个坑与排查思路

我接触过的Oracle环境五花八门,从11g到19c都有,开启归档模式的操作大同小异,但踩坑的姿势几乎总是那么几个。这里把我遇到频率最高、也最容易让人困惑的三种情况整理出来,每个都给到完整的排查思路。

6.1 第一个坑:ORA-00265错误,实例恢复需要被强制执行

这个报错长这样:

ORA-00265: instance recovery required, cannot set ARCHIVELOG mode

出现这个错误的场景通常是:数据库上次不是正常关闭的,比如环境断电或执行过shutdown abort,重新启动后发现要做实例恢复,此时直接startup mount再执行alter database archivelog,Oracle会阻止你切换。

发生原因也很简单:数据库处于需要实例恢复的状态,控制文件记录的日志应用进度还没走完,直接改归档模式会让恢复过程变得不干净。正确的操作方式是先正常打开数据库一次:

SQL> startup;

Oracle会自动执行崩溃恢复,等库正常open后,再shutdown immediate,然后走标准的mount切换流程。如果startup因为其他原因起不来,则要结合alert.log定位具体阻塞点。

6.2 第二个坑:归档路径没有提前建好或者权限不对

日志切换归档时,如果归档目录不存在或Oracle用户没权限写入,会出现ORA-19504或ORA-16038系列错误,比如:

ORA-16038: log 1 sequence# 100 cannot be archived ORA-19504: failed to create file "/u01/arch/orcl"

很多人执行完alter system set log_archive_dest='/u01/arch/orcl'之后,没有在操作系统层面手动创建这个目录,也没有授权给Oracle用户,结果日志一切换就直接报错。这是开启归档后最早可能出现的问题之一。

排查思路很简单:

  1. 确认目录是否存在:ls -ld /u01/arch/orcl
  2. 确认属主和权限:目录须属于oracle用户(或oinstall组),并且有写权限
  3. 如果是ASM磁盘组路径,则需要确认磁盘组已挂载且有足够空间

正确的姿势是在配置参数前就把目录建好:

mkdir -p /u01/arch/orcl chown oracle:oinstall /u01/arch/orcl chmod 750 /u01/arch/orcl

我对这种问题的态度是"宁可事前多敲三条命令,不要事后半夜查告警"。创建目录、授权、再配置参数,这个顺序别反过来。

6.3 第三个坑:归档日志切换失败,数据库hang住不动

这个属于严重事故级别的坑了,症状是整个库写操作全部挂起,操作日志里全是等待事件的堆积。根本原因基本就是归档目录满了,或者归档目标路径不可用,导致日志切换阻塞。此时LGWR无法完成日志切换,所有提交都悬着。

遇到这种情况,正确的排查链路是:

第一步,查看归档目标状态:

SQL> select dest_id, destination, status, error from v$archive_dest;

如果status不是VALID,且error列有内容,说明归档目标异常。

第二步,查看操作系统磁盘空间:

df -h

如果空间满了,立即清理。清理方式是在确认归档日志已经安全备份之后,删除部分归档文件腾出空间。一旦释放空间,数据库通常会自动恢复日志切换,不一定要重启实例。

第三步,如果归档目录空间充足但归档进程异常,考虑手动重启归档进程:

SQL> alter system archive log stop; SQL> alter system archive log start;

这一步会强制重新初始化归档进程。执行完后再手动切换一次日志:

SQL> alter system switch logfile;

确认归档日志能正常生成,数据库的hang住状态即可解除。

这里我还要额外提醒一句:如果在RAC环境下操作,归档参数和目录必须在所有节点上保持一致,包括创建的目录和权限配置。我曾经见过一个双节点RAC,只在一个节点上建了归档目录,另一个节点日志切换时找不到路径,结果整个集群写事务全部被拖垮。RAC环境的操作,一定要养成"所有节点同步执行"的习惯。

7. 我个人的生产环境实操建议

最后把我这些年在生产环境里总结的一些操作习惯分享出来。比如在变更脚本里,我习惯先把整个操作过程写入一个文本文件,每执行一步记录一步,尤其对生产库做模式切换这种变更,留一份可追溯的操作痕迹会方便很多。团队协作时,把归档模式的检查项纳入日常巡检脚本里,每天自动跑一遍,能尽早发现隐患。

开启归档时还有一个细节值得注意:如果库是要长期接受归档日志、配合容灾或数据分析系统使用,建议在切换归档模式的同时,顺带和网络、存储团队确认一下归档目录所在磁盘的I/O能力。日志写入是顺序写为主的负载,机械磁盘通常也能应付,但如果业务并发很高、日志量很大,归档盘I/O会成为新的瓶颈,必要时得考虑SSD或独立存储。

另外,在完成归档模式开启后,我哪天都不会急着把旧的全备文件删掉。正常情况下开归档不影响已有数据文件,但为了应对万一出现"开启操作后存在不可预期的问题需要恢复到开启前状态"的极端情况,保留一份开启前的全备或至少保留开启前的那几个联机日志,能让自己始终有退路。

从实际运维角度来看,归档模式本身只是一个开关,真正的功夫在开关之后的设计与维护。日志空间规划、清理策略、恢复链路验证、日常监控告警,这些环节环环相扣。数据库出问题不可怕,可怕的是出问题时发现自己没有退路。把归档模式开好、管好,就是给自己和团队留一条最可靠的退路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询