Oracle数据库归档模式开启与运维实战指南

📅 发布时间:2026/9/17 13:13:23
Oracle数据库归档模式开启与运维实战指南
1. 归档模式是什么生产库为什么要开先讲一个真实的教训。我早年间接手过一套跑了两年的业务系统数据库跑在非归档模式下每天凌晨做一次全量备份。当时觉得备份有了就万事大吉结果某天凌晨磁盘阵列突然坏了两块盘数据文件所在的盘组直接掉了。恢复的时候才发现最近的一次全量备份是前一天凌晨的这意味着当天所有业务数据全部丢失而且因为没开归档redo log里那点增量根本不够用来做不完全恢复。最后只能拿昨天的备份恢复损失了近一整天的数据。那次事故之后我接手任何一套Oracle数据库第一件事就是检查归档模式是否开启。归档模式说白了就是数据库在每次日志切换之后把写满的redo log文件复制一份保存到指定位置。这些保存下来的文件就是归档日志它们和全量备份组合在一起才能支撑起真正的“按时间点恢复”。非归档模式下日志切换之后旧的redo log会被直接覆盖数据库只能恢复到上一次备份的时刻中间的数据全部丢失。而归档模式下通过全量备份加归档日志你可以把数据库恢复到任意一个历史时间点甚至可以恢复到故障发生前的最后一秒。更关键的是归档模式是搭建Data Guard、使用LogMiner做日志分析、以及实现在线热备份的基础。只要你的数据库是生产环境无论是跑业务系统还是做数据仓库没有任何理由不开归档模式。开发库和测试库可以不开但生产库必须开这是数据库运维的底线。这篇文章会把查看和开启归档模式的完整流程讲清楚包括环境检查、参数配置、操作步骤和常见故障排查。内容基于Oracle 11g到19c的通用实践有一点Linux基础、能自己登录数据库执行SQL的人都可以照着操作。2. 动手之前先搞清楚数据库当前处于什么状态2.1 用一条命令快速查看归档模式状态查看当前数据库是否处于归档模式最直接的方式是用SQL*Plus登录数据库后执行archive log list命令。这个命令是Oracle提供的最直观的归档状态查看方式输出信息一目了然。sqlplus / as sysdba SQL archive log list; Database log mode Archive Mode Automatic archival ENABLED Archive destination /u01/app/oracle/archive Oldest online log sequence 120 Next log sequence to archive 122 Current log sequence 122关键看两行Database log mode显示Archive Mode代表已经开启显示No Archive Mode代表没开Automatic archival显示ENABLED代表自动归档开启显示DISABLED代表即使处于归档模式也没有自动归档。Archive destination这一行列出了归档日志的存放路径如果这里为空说明没有配置归档路径这种情况即使归档模式开启了也存不下日志后续会专门讲这个问题。2.2 用SQL查询验证更详细的状态信息如果你需要更详细的信息比如归档目的地是否有效、归档日志的序列号范围可以通过查询动态性能视图和历史视图来确认。v$database视图的log_mode字段直接显示数据库当前的日志模式。SELECT name, log_mode, open_mode FROM v$database;返回结果中log_mode为ARCHIVELOG代表归档模式为NOARCHIVELOG代表非归档模式。open_mode字段显示数据库是READ WRITE读写模式还是MOUNTED挂载模式开启归档的过程中需要确认数据库所处的挂载状态。如果你还想知道归档目的地是否可用可以查询v$archive_dest_status视图。这个视图会列出所有配置的归档目的地以及它们当前的状态STATUS为VALID表示目的地正常可用如果是ERROR或INACTIVE则需要处理。SELECT dest_name, status, destination, error FROM v$archive_dest_status WHERE dest_name IN (LOG_ARCHIVE_DEST_1, LOG_ARCHIVE_DEST_2);2.3 查看当前日志序列号判断归档日志是否在持续产生除了确认模式本身还要确认归档日志确实在正常产生。日志切换时会产生新的序列号每一次切换之后当前日志序列号都会递增归档日志也会同步增加一份。SELECT sequence#, archived, status FROM v$log ORDER BY sequence#; SELECT MAX(sequence#) AS max_archived_seq FROM v$archived_log;v$log视图显示当前所有redo log日志组的状态archived字段标记日志组是否已经归档。v$archived_log记录了所有已经生成的归档日志信息查询MAX(sequence#)可以得到最新的归档序列号。如果数据库处于非归档模式你会在v$log中看到部分日志组显示CURRENT或ACTIVE但没有对应的归档记录。这时需要注意在非归档模式下日志切换时可能会因为无法覆盖尚未备份的日志而导致数据库挂起这也是非归档模式在生产环境中风险极高的原因之一——因为只要日志写满但无法覆盖整个数据库就会hang住直接拒绝所有新的写入请求。3. 完整开启归档模式操作步骤与核心参数说明3.1 开启前必须做的三件事开启归档模式不是一条命令就完事的操作它涉及数据库实例的重启任何误操作都可能导致业务中断。在我实际操作中开启归档模式前有三件事必须确认清楚。第一确认磁盘空间是否充足。归档日志会持续增长必须计算好存放目录的空间。一个简单的估算方法如果数据库每天产生10GB的redo log归档日志也大约是这个量级建议至少预留7天的归档日志空间。如果使用快速恢复区Fast Recovery AreaFRA启动归档时Oracle会自动把归档日志放到这里那就需要确保FRA容量足够大否则归档日志写满FRA会导致数据库直接hang住这是一种非常常见的生产事故。第二确认维护窗口时间。开启归档模式需要重启数据库实例从shutdown immediate到alter database open完成整个过程一般来说几分钟内可以完成但如果你在业务高峰期操作这个窗口期内的所有请求都会失败。所以建议在业务低谷期操作并提前和业务方沟通好维护窗口。第三确认当前是否有未完成的备份。如果数据库处于非归档模式并且使用了alter database backup controlfile之类的备份命令建议先完成一次全量备份。更严谨的做法是在开启归档模式之后再做一次全量备份——因为开启归档之前的备份无法配合归档日志用于恢复完整备份的基线应该是开启归档之后的那一次全量备份。3.2 一步步操作从shutdown到open的完整流程一切确认无误之后按以下步骤操作。以下命令均以sysdba身份登录SQL*Plus执行。先关闭数据库实例。生产库建议使用shutdown immediateOracle会自动完成事务回滚和进程清理如果长时间无法关闭可以使用shutdown transactional等待事务完成尽量不要贸然使用shutdown abort除非是紧急情况。sqlplus / as sysdba SQL shutdown immediate;接下来数据库实例关闭后需要以MOUNT模式启动。这里有个新手容易犯的错误startup之后直接执行alter database archivelog会报ORA-01126: database must be mounted in this instance and not open in any instance错误。原因在于归档模式的修改需要在数据库处于MOUNT状态而非OPEN状态时才能执行。SQL startup mount;然后执行开启归档的命令SQL alter database archivelog;这条命令本身执行速度很快它修改的是控制文件中的数据库日志模式记录不需要做数据迁移。执行成功后返回Database altered.。之后打开数据库让业务恢复访问SQL alter database open;最后再次用archive log list确认状态SQL archive log list; Database log mode Archive Mode Automatic archival ENABLED Archive destination /u01/app/oracle/archive Oldest online log sequence 120 Next log sequence to archive 123 Current log sequence 123到这里归档模式已经成功开启。3.3 关键参数配置归档路径与归档格式归档模式开启之后必须确认归档日志写入的位置和文件命名格式。如果这两个参数没配置好后续恢复可能会遇到各种麻烦。归档路径的核心参数是log_archive_dest和log_archive_dest_n。其中log_archive_dest是旧的单一目的地参数log_archive_dest_n支持配置多个目的地最多可以配置31个。在实际运维中建议至少配置两个归档目的地。原因很实际如果归档日志只写一份一旦磁盘坏了归档日志也就全没了那么数据库依然无法恢复到最新状态。多写一份就多一层保障而且Oracle对多个归档目的地的处理是同步写入的不会因为多一个目的地而影响性能太多。ALTER SYSTEM SET log_archive_dest_1LOCATION/u01/app/oracle/archive MANDATORY; ALTER SYSTEM SET log_archive_dest_2LOCATION/u02/app/oracle/archive2;上面第一行的MANDATORY关键字表示这个目的地是强制的只有归档日志成功写入该目的地日志切换才能完成。如果不加MANDATORY默认是OPTIONAL归档失败时数据库不会立即挂起而是在后台不断重试。归档格式的参数是log_archive_format如果是Oracle 11g及以上版本建议使用以下格式ALTER SYSTEM SET log_archive_formatarch_%t_%s_%r.arc SCOPESPFILE;这个格式中各占位符的含义是%t表示线程编号RAC环境下每个实例对应一个线程号%s表示日志序列号%r表示resetlogs的ID。有了%r这个标识即使数据库执行过不完全恢复并重置了日志序列号归档文件名也不会冲突。这个参数必须设置到SPFILE中因为它要在实例启动时读取如果只在当前会话中生效下次重启又恢复原样。修改后需要重启实例才能生效。3.4 快速恢复区与自动归档的选择在Oracle 11g之后很多环境会使用快速恢复区来管理备份和归档文件。如果配置了db_recovery_file_dest归档日志默认会写到快速恢复区中而不需要显式配置log_archive_dest_n指向某个文件系统目录。ALTER SYSTEM SET db_recovery_file_dest/u03/fast_recovery_area; ALTER SYSTEM SET db_recovery_file_dest_size100G;使用快速恢复区的优势在于统一管理备份和归档共享同一份空间Oracle自动管理空间回收。但它的风险也很明显如果快速恢复区的空间被占满数据库会立即挂起因为归档日志写不进去了。很多DBA在快速恢复区满的时候被搞到焦头烂额原因就在这。所以我个人的建议是对于生产系统不要把归档和备份放在同一个快速恢复区直接用文件系统目录指定归档路径再配合一个独立的备份目录。这样即使备份把磁盘写满了归档日志依然有独立的写空间至少不会因为备份而影响数据库可用性。自动归档的控制参数是log_archive_start但要注意这个参数在Oracle 10g之后已经被废弃了数据库默认就是自动归档。如果你看到一些老教程让你设置log_archive_starttrue可以直接忽略这个参数在11g和19c中执行会直接报错或提示已被废弃。3.5 RAC环境开启归档模式的特殊说明如果你管理的是RAC集群环境开启归档模式的思路一样但操作细节有区别。RAC环境中数据库同样需要先关闭所有实例然后在其中一个实例以MOUNT模式启动执行alter database archivelog最后同步启动所有实例。srvctl stop database -d orcl srvctl start instance -d orcl -i orcl1 -o mount sqlplus / as sysdba SQL alter database archivelog; SQL alter database open;之后用srvctl start database -d orcl启动所有实例并通过srvctl config database -d orcl -a确认归档配置。这里有一个RAC特别容易踩的坑每个实例都需要配置独立的log_archive_dest_n。比如两个实例的RAC环境LOG_ARCHIVE_DEST_1和LOG_ARCHIVE_DEST_2可能会配置成指向共享存储上的同一目录这种情况没有问题但如果每个实例都有独立的归档目录必须保证每个实例都能正确写入否则某一实例的日志切换会hang住。在多实例环境中建议把归档目录配置在共享存储上避免某个实例访问不到其他实例的归档目录。4. 开启归档之后日常运维必须掌握的几个动作4.1 手动切换日志验证归档是否正常归档模式开启之后建议手动触发一次日志切换然后马上查看归档日志是否生成。这个动作相当于验证整个归档链路的完整性和正确性别等到真正需要恢复时才发现归档日志根本写不进去。ALTER SYSTEM SWITCH LOGFILE;执行这条命令会强制Oracle切换到下一个redo log日志组。切换之后原来的日志组会进入ACTIVE状态随后被归档进程复制到归档目录最终变为INACTIVE状态。然后查看归档日志是否生成SELECT sequence#, name, blocks, block_size, creator FROM v$archived_log ORDER BY sequence# DESC FETCH FIRST 3 ROWS ONLY;或者直接到文件系统查看ls -lht /u01/app/oracle/archive | head -5如果看到最新的归档文件已经生成说明归档链路正常。如果v$archived_log里查不到记录或者文件系统里没有新的归档文件就需要检查归档进程状态和告警日志这属于后面会讲到的问题排查内容。4.2 归档日志会一直膨胀必须建立清理机制归档目录不像数据库数据文件那样有固定大小它会随着业务的写入量持续增长。如果业务每天产生50GB的redo log归档日志就会以每天50GB的速度增长不清理的话再大的磁盘也会被撑爆。清理归档日志最稳妥的方式是基于全量备份来清理。核心原则是归档日志的保留时间至少要覆盖到最近一次全量备份的时间点。如果每天凌晨2点做全量备份那么在备份完成之前不要删除任何归档日志备份完成后可以删除这个备份时间点之前的归档日志。一种最简单的清理思路是保留最近7天的归档日志更早的直接删除。这个策略适合业务增长相对平稳、每天数据量变化不大的系统。但如果你想做更精细的管理建议通过RMAN来清理RMAN DELETE ARCHIVELOG ALL COMPLETED BEFORE SYSDATE-7;这条命令会删除7天前且已被备份过的归档日志准确来说是已经被RMAN标记为备份过的归档日志。使用RMAN的好处是它会自动检查归档日志是否已被备份未被备份的归档日志即使超过7天也不会删除这样能避免误删需要用于恢复的日志。需要注意绝对不要在归档目录里直接rm -rf删除归档文件这样做会让控制文件中的归档信息与文件系统不一致后续RMAN备份时会报错甚至影响恢复操作。正确做法永远是使用RMAN或者先查询v$archived_log确认后再处理。4.3 监控归档目录空间设置合理告警阈值归档目录满了是生产中比较常见的事故场景。一旦归档目录满了ARCH进程无法写入新的归档日志Oracle会挂起所有事务——因为在强制归档模式下日志切换需要等待归档完成如果归档写不进去redo log文件也无法覆盖整个数据库都无法写入。我见过不少案例就是因为没人盯归档目录结果磁盘悄悄写满业务突然就停了。所以归档目录的空间监控一定要提前做好。最原始的监控方式是每天写脚本检查归档目录的使用率#!/bin/bash # 检查归档目录使用率超过90%告警 THRESHOLD90 USAGE$(df -h /u01/app/oracle/archive | awk NR2 {print $5} | tr -d %) if [ $USAGE -gt $THRESHOLD ]; then echo Archive dir usage $USAGE% exceeds threshold $THRESHOLD% | mail -s Oracle Archive Alert dbaexample.com fi这个脚本可以作为cron定时任务每小时执行一次。当然如果有Zabbix、Prometheus这类监控系统直接在监控面板上添加上这个目录的磁盘空间监控设置告警阈值效果更好。告警阈值我建议分两级80%做预警90%做紧急告警。这样你既能在问题发生前从容处理也不至于被频繁的告警信息骚扰。4.4 归档模式下的备份策略调整归档模式开启后数据库的备份策略需要同步调整否则光开了归档但没有相应的备份配合等于白白增加了额外IO和存储开销却享受不到归档带来的恢复能力。正确做法是全量备份加归档日志备份组合使用。完整备份的周期可以是每周一次或每天一次取决于恢复时间目标Recovery Time ObjectiveRTO和数据恢复点目标Recovery Point ObjectiveRPO。归档日志则持续备份确保每一次日志切换后产生的归档日志都被纳入备份体系。RMAN备份完整数据库的经典命令rman target / RMAN BACKUP DATABASE PLUS ARCHIVELOG DELETE INPUT;这里的DELETE INPUT表示备份归档日志之后直接删除原归档文件这样既完成了备份也顺带清理了归档目录空间一举两得。这种备份方式执行一次全量备份和归档日志备份都在里面恢复时逻辑清晰。值得提醒的是不要只做全量备份而忽略归档日志备份也不要光归档不清理。归档日志本身只是中间产物核心目标是保证“全量备份归档日志”可以恢复数据库到任意时间点然后在此基础上回收无用的归档文件。这个思路想明白了后续运维都会变得很清晰。5. 开启归档模式过程中的常见故障与排查思路5.1 ORA-00265: 要求实例恢复无法归档这是从非归档模式切换到归档模式时容易遇到的一个错误。报错信息类似ORA-00265: instance recovery required, cannot set ARCHIVELOG mode出现这个错误的原因通常是因为数据库上一次是异常关闭的比如使用了shutdown abort实例在Mount状态下检测到有未完成的事务恢复。Oracle需要在归档模式修改之前先完成实例恢复确保数据文件的SCN一致性。排查思路很简单先让数据库完成恢复。打开数据库执行一次正常关闭再用正常流程启动到Mount状态重新执行alter database archivelog。如果数据文件损坏严重无法打开那就不是切换归档模式的问题了需要先处理恢复问题。这个错误提醒我们切换归档模式前一定要保证数据库是正常关闭的。引用我之前遇到的一次现场某天新来的同事在数据库异常重启后马上就执行启动Mount并尝试开启归档结果就报了这个错误。后面正常alter database open完成恢复后再关库重新来一遍问题就没了。5.2 ORA-16038: 日志无法归档数据库直接hang住ORA-16038: log 1 sequence# 123 at ... cannot be archived这条错误基本可以确认归档目的地出问题了。最常见的原因是磁盘空间不足归档进程无法写入新文件。这里有一个细节如果是使用了快速恢复区并且快速恢复区空间满了Oracle会在告警日志中记录ORA-19809: error occurred in the Recovery Area和ORA-19815: Warning: db_recovery_file_dest_size of ... bytes is 100% used等报错信息出现这类报错时数据库可能会直接挂起拒绝写入需要立即处理。处理步骤一般是优先确认归档目的地是否可写、空间是否充足如果空间不够清理过期归档日志如果是路径权限问题检查目录权限和数据库进程用户是否一致处理完成之后通过alter system archive log start或者手动触发日志切换恢复正常。这里特别提醒不要直接强制重启数据库来“恢复”因为如果数据库已经因为归档写不了而挂起重启后还会是同样的问题。必须先解决归档写不进去的原因再恢复数据库的正常运行。5.3 归档日志不生成或生成延迟特别大有时候切换到归档模式后发现日志切换已经发生但归档目录中迟迟看不到新的归档文件。这种情况通常不是模式没开起来而是归档进程出现问题。排查顺序可以先看归档进程状态SELECT process, status FROM v$archive_processes;正常状态下应看到多个ARCH进程状态为ACTIVE。如果进程状态异常可以尝试重启实例或手动触发一次日志切换看看能否恢复。再看一下告警日志查看归档相关的错误信息tail -100 $ORACLE_BASE/diag/rdbms/orcl/orcl/trace/alert_orcl.log | grep -i archive告警日志中会记录归档进程的详细错误比如目的地不可达、文件权限问题、IO错误等。大部分情况下根据告警日志中的ORA-xxxxx错误码就能准确定位问题所在。另外一个常见的原因是归档目的地配置在了本地文件系统但数据库运行用户对目录没有写权限。比如归档目录属主是root而Oracle进程用户是oracle这种情况下归档进程自然会报权限错误。设置归档目录时建议在创建目录后立刻执行chown oracle:oinstall调整属主避免这种问题。5.4 日志切换频繁导致归档进程跟不上如果业务写入量特别大或者redo log日志组文件太小会导致日志切换非常频繁归档进程来不及处理归档日志生成延迟越来越大甚至影响业务。这种情况通常可以通过调整redo log的大小来缓解。一个合适的redo log大小应该能让日志切换频率保持在15到30分钟一次比较理想。如果你的数据库每几分钟就切换一次日志说明日志文件太小了需要添加更大的日志组。ALTER DATABASE ADD LOGFILE GROUP 4 /u01/app/oracle/oradata/orcl/redo04.log SIZE 2G;添加新日志组之后可以手动切换几次日志让旧的日志组慢慢退役最后把新日志组设为当前使用。同时也可以适当增加归档进程数量ALTER SYSTEM SET log_archive_max_processes4;归档进程数默认为2或4在日志切换频繁的环境中可以调大到8但不建议无脑调大需要结合系统CPU和IO负载情况判断。我的实际经验是大部分业务量级的数据库归档进程保持默认值就够了真正的问题通常在redo log太小球才会翻转。5.5 常见问题排查速查表整理一个速查表方便遇到问题时快速定位故障现象常见原因最先排查的地方切换归档模式报ORA-00265实例上次未正常关闭需要实例恢复检查数据库是否正常关闭完成后重试日志切换后数据库挂起归档目录空间不足或路径不可写检查磁盘空间、目录权限、归档目的地状态归档目录文件不增长归档进程异常或目的地配置错误查询v$archive_processes和告警日志ORA-19809/19815快速恢复区满快速恢复区空间耗尽清理快速恢复区内的过期备份和归档日志日志切换频繁影响性能redo log日志组太小添加更大的日志组并切换归档进程状态异常实例异常或资源不足检查告警日志、系统负载必要时重启实例6. 归档模式开启之后再做一次全量备份很多人在开启归档模式后就认为工作完成了但我要强调一个细节开启归档模式之后请务必立刻做一次全量备份。为什么因为归档日志的恢复能力必须和它之后的全量备份配合使用。你把数据库恢复到某个时间点的时候恢复路径是最近一次全量备份 这之后到目标时间点的所有归档日志。如果你在开启归档模式之前做的全量备份这个备份点已经早于归档日志的起始点恢复时可能出现备份与归档日志之间断档的情况无法完整恢复。用RMAN执行全量备份rman target / RMAN BACKUP DATABASE PLUS ARCHIVELOG DELETE INPUT;注意这里使用的是PLUS ARCHIVELOG而不是简单地BACKUP DATABASE。加上PLUS ARCHIVELOG之后RMAN会自动在备份数据库之前先备份当前的归档日志并在备份完成后删除已备份的归档日志。这样整个备份过程中产生的归档日志也被完整包含了恢复的链条不断。这条命令执行完你的备份策略才算是真正建立在归档模式之上了。之后配合每日归档日志备份和定期全量备份数据库的恢复能力才算完整。7. 归档模式运维中容易被忽视的几个细节最后分享几个实操中容易被忽视的细节都是踩过坑之后才总结出来的。第一定期检查归档目的地状态不要只在出问题时才想到看。我建议在每周的数据库巡检清单中加入一条查询v$archive_dest_status确认所有归档目的地状态为VALID。如果是ERROR状态尽早发现和提早处理要比等到业务停了再抢修从容得多。第二归档日志的保留时长要结合业务恢复需求和存储成本来做平衡。有的银行系统要求能恢复到任意时间点那归档日志就要长期保留有的内部系统只需要恢复到前一周那保留两周就够了。这个策略明确之后再配合自动化清理工具执行不要等到磁盘满了才手动清。第三部署监控脚本时不要只监控归档目录所在的文件系统空间。如果你用的是快速恢复区需要额外监控db_recovery_file_dest_size参数设置的容量是否足够同时关注V$RECOVERY_FILE_DEST视图中的空间使用情况因为这里的空间使用率是Oracle自己管理的。第四如果数据库同时承担OLTP业务和批量任务日志切换的频率在不同时段差异会非常大。批量任务跑批的时候日志切换可能非常频繁归档日志的生成速度也会很快。可以在批量任务高峰期前手动执行一次日志切换让归档进程提前开始工作避免高峰期日志切换和归档积压同时发生。根据我个人多年的运维体会归档模式不是一个配置完就可以彻底忘记的功能它需要日常的关注与维护。但只要把查看状态、定期备份、空间监控和故障排查这几个动作都落实到日常运维中归档模式就能真正成为数据库数据安全的坚实防线。希望这篇文章能帮你把归档模式的查看与开启流程一次走顺不再踩我当年踩过的坑。