ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Oracle Data Guard同步停止+UNNAME文件故障排查与恢复实战

Oracle Data Guard同步停止+UNNAME文件故障排查与恢复实战 很多刚接触Oracle Data Guard的DBA都有过这种经历某天登录备库一看MRP0进程状态不是“APPLYING_LOG”而是“WAITING_FOR_LOG”同步早就悄悄停了再翻alert日志发现一条带着UNNAME字段的错误记录还跟着一串类似UNNAMED00518.arc或者UNNAMED00003.dbf的文件名。这就是标题里说的“dg同步停止UNNAME文件”场景。这篇文章就把这个组合故障从原理到恢复讲透包括UNNAME文件是怎么来的、怎么确认同步停在哪一段日志、以及归档日志丢失时最稳妥的追平方式。不管你是刚上手DG的新手还是负责生产库的运维老手这套排查思路和恢复动作都能直接照用。1. 先搞清楚UNNAME文件是怎么冒出来的1.1 Oracle Data Guard同步链路里的三个关键角色要理解UNNAME文件先得说清楚DG同步的正常工作链路。主库那边的日志传输要么靠LGWR进程实时把redo推给备库要么靠ARCH进程归档后传输备库这边接收到日志的进程叫RFS它会把redo写进standby redo log如果配置了或者直接归档最终真正把日志内容应用进备库数据文件的进程是MRP0。MRP0扫到一个日志文件打开它、读取redo记录、apply进去然后继续扫下一个。这条链路里任何一环出了问题同步都会卡住。但“卡住”也分两种一种是RFS还在正常收日志只是MRP0应用不过来这种通常表现为备库不断累积延迟不一定会立刻产生UNNAME文件另一种是MRP0需要的某个归档日志“根本不存在”这个时候Oracle就会尝试用UNNAME占位文件名去引用它同时把同步状态改成WAITING或中断。所以UNNAME文件可以理解为“MRP0找不到日志时打的一张欠条”是故障结果而不是故障原因。1.2 UNNAME文件在“同步停止”里扮演什么角色UNNAME文件的典型出现过程是这样备库的MRP0正按序列号sequence顺序应用归档比如已经应用到了1_128下一个需要的是1_129但备库上翻遍自己的归档目录、FRA闪回恢复区都找不到1_129对应的物理文件。于是MRP0尝试在配置好的归档目标位置创建一个名为UNNAMExxxxx的文件同时在alert日志里报出错误。常见伴随错误是ORA-00308无法打开归档日志和ORA-01291缺少日志文件。这里有一点容易误导人UNNAME文件不一定是真实落盘的大文件很多时候它只是Oracle内部元数据里的一个占位记录。你可能会在备库的db_recovery_file_dest目录下看到一个0字节或者几KB的UNNAME文件也可能什么都看不到但DBA视图里它已经存在了。我在实际环境里两种都见过。如果是RAC双实例备库还可能在两个实例各自的FRA下各出现一个UNNAME占位文件排查时要多看一个维度。搞清楚这个机制后后面所有排查都应该围绕一个问题展开MRP0要的那段日志到底还在不在在的话在哪里不在的话怎么补2. 同步停止排查从确认进程到定位缺失归档2.1 用三个视图快速给备库“体检”发现同步停止后不要急着去补日志先把备库的当前状态完整摸一遍。我习惯按下面顺序执行三组SQL。第一组看MRP0和RFS进程状态SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, DELAY_MINS FROM V$MANAGED_STANDBY;重点看MRP0这一行。状态如果是WAITING_FOR_LOG说明MRP0已经不再继续应用正在等某个日志如果看到APPLYING_LOG说明它还在尽力往后追同步停止可能是刚发生或者应用速度跟不上RFS一行如果状态异常则问题出在日志接收环节。第二组直接查缺口gapSELECT * FROM V$ARCHIVE_GAP;这个视图是Oracle专门用来显示备库当前缺失日志范围的。如果查询有返回第一列是thread第二列是缺失的起始sequence第三列是结束sequence。比如返回1, 130, 132意思就是备库缺1号线程的130到132三段日志。没有返回不代表万事大吉只能说明当前没有检测到连续缺口仍需要结合归档列表确认。第三组看备库已应用日志的完整清单SELECT THREAD#, SEQUENCE#, APPLIED, DELETED, NAME FROM V$ARCHIVED_LOG ORDER BY THREAD#, SEQUENCE#;这里主要看APPLIED列。如果有大量归档处于NO状态说明MRP0停在那里很久了再结合NAME列可能就是UNNAME文件出现在那个位置附近。2.2 alert日志和trace里该看什么视图查完后一定要去备库alert日志里核实具体报错。大部分时候你会看到类似下面的内容Errors in file /u01/app/oracle/diag/rdbms/standby/standby/trace/standby_mrp0_12345.trc: ORA-00308: cannot open archived log /u01/app/oracle/fast_recovery_area/STANDBY/archivelog/2024_11_03/o1_mf_1_130_UNNAME.arc ORA-01291: missing log file注意看两个关键信息一个是报错路径它会直接告诉你MRP0在哪个目录下找文件另一个是trace文件名里的进程ID方便进一步翻trace。顺着手上的UNNAMED1_130.arc这个文件名已经能定位到缺失的序列号是130。我还遇到过一种情况alert日志里报的是RFS进程的错比如RFS: Possible network disconnect但MRP0还在正常应用。这种其实不是真正的UNNAME问题只是归档传输短暂中断RFS和MRP0之间的等待拉长了。先查网络和监听不要一上来就用增量备份把备库重建一遍那样反而把简单问题复杂化。3. 恢复同步的两种实操路线3.1 归档文件还在只是没传到备库这是最理想的情况。确认备库缺少某段归档后先去主库查这段日志是否还存在。主库执行SELECT NAME, SEQUENCE#, DELETED FROM V$ARCHIVED_LOG WHERE THREAD# 1 AND SEQUENCE# BETWEEN 130 AND 132 ORDER BY SEQUENCE#;如果主库返回的DELETEDNO说明物理文件还在。接下来只要把它从主库拷贝到备库对应目录再在备库手动注册归档MRP0就能继续。具体步骤先取消当前的恢复进程避免它和你抢文件ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;然后在主库把归档文件拷贝到备库。可以用操作系统scp也可以用Oracle的DBMS_FILE_TRANSFER包。我在生产环境更倾向于直接在备库从主库拉文件因为这样不占用主库本地磁盘IO写路径。拷贝的目标目录必须和alert日志里报错路径一致比如上次报错路径是/u01/app/oracle/fast_recovery_area/STANDBY/archivelog/2024_11_03/就要把文件放到同样的年月子目录下。拷贝完成后在备库注册这段日志让Oracle认可它ALTER DATABASE REGISTER LOGFILE /u01/app/oracle/fast_recovery_area/STANDBY/archivelog/2024_11_03/o1_mf_1_130_xxxxx.arc;注册无误后重新启动恢复进程ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;之后等几分钟再查V$MANAGED_STANDBYMRP0状态应该变成APPLYING_LOGV$ARCHIVE_GAP也没有记录了。如果备库一直处于实时应用模式理论上它会自动开始追平主库新产生的日志。3.2 归档文件已经丢失用增量备份追平如果主库上那些缺失的归档也已经被删除那就不能靠“补文件”解决因为文件物理上已经不存在了。这种情况下最稳妥、我实站使用最多的方案是用RMAN增量备份把备库追平到断点附近而不是直接重建备库。操作思路并不复杂找一个主库上的SCN作为增量起点这个SCN就是备库已经应用到的位置之后的那个点。可以从备库查询最近一个成功应用日志的NEXT_SCN也可以直接用主库当前scn往前推。实际操作我建议用下面方法确认起点在备库查最近已应用日志SELECT THREAD#, MAX(SEQUENCE#) KEEP (DENSE_RANK LAST ORDER BY SEQUENCE#) AS LAST_APPLIED_SEQ, MAX(NEXT_CHANGE#) KEEP (DENSE_RANK LAST ORDER BY SEQUENCE#) AS NEXT_SCN FROM V$ARCHIVED_LOG WHERE APPLIED YES GROUP BY THREAD#;拿到对应SCN后在主库执行增量备份rman target / BACKUP INCREMENTAL FROM SCN 636967240 DATABASE FORMAT /backup/incr_%U TAG DG_CATCHUP INCLUDE CURRENT CONTROLFILE FOR STANDBY;这里的关键点是FROM SCN它决定了增量备份只包含从断点之后产生的数据块体积远小于全量备份传输时间和恢复时间都可控。如果断点离当前时间已经很久增量备份也可能很大但那也比全备好。把生成的备份集传给备库后在备库RMAN里执行rman target / CATALOG START WITH /backup/incr; RESTORE STANDBY CONTROLFILE FROM TAG DG_CATCHUP; ALTER DATABASE MOUNT; RESTORE DATABASE FROM TAG DG_CATCHUP; RECOVER DATABASE NOREDO;RECOVER DATABASE NOREDO在这里值得解释一下它的意思是只更新数据文件头不实际应用数据块因为增量备份已经包含了断点以来所有变化的块随后再启动MRP0应用断点之后的归档日志即可。最后别忘了在备库重新启动日志应用ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;这项工作做完后备库的UNNAME报错会消失MRP0会从新的一致性点继续追日志。我处理过的几个案例里这种方式追平的时间基本都在半小时到两小时之间取决于日志量和网络带宽。3.3 UNNAME文件到底能不能直接删很多人在恢复过程中会犹豫既然UNNAME文件是个“错的占位文件”能不能直接rm掉我的建议是不要在没有解决GAP之前动手删它。原因很简单UNNAME文件虽然看着碍眼但它记录的是MRP0找不到日志时的引用信息。一旦你强行删除了文件而MRP0还在等待那段日志后续日志应用时可能直接报更严重的文件打开错误。正确顺序永远是——先解决缺失归档或增量追平等MRP0已经正常继续应用后再检查那个UNNAME文件是否还存在。如果它作为一个实际文件还存在且没有进程占用可以用操作系统命令删除或者留着不管对恢复没有实质影响。曾经有个同事在处理过程中直接删了UNNAME文件接着MRP0立刻从WAITING变成ABORTED最后只能重新做增量恢复多花了一个多小时。这个坑希望你能避开。4. 常见报错和避坑经验4.1 报错速查表DG同步停止时alert日志里可能同时出现好几类错误我把常见的组合整理成了下面的速查表方便遇到问题先对号入座。错误或状态根因方向处理优先动作ORA-00308归档日志文件不存在或路径不对查主备库归档是否还在补传并REGISTERORA-01291缺少连续的多段归档GAP未解决查V$ARCHIVE_GAP按缺段范围处理ORA-16055FAL自动补日志失败fal_server配置问题核对主备TNS、fal客户端与服务端配置MRP0: WAITING_FOR_LOG等不到可用归档可能网络或GAP导致检查进程状态和归档路径再决定是否增量追平RFS: POSSIBLE NETWORK DISCONNECT主备网络或监听中断先修网络和监听不急于操作备库RFS: NO RECOVERY备库未处于恢复/归档模式确认备库MOUNT状态并重新启动MRP这张表不是让你死记硬背而是排查时先看报错属于“文件缺失”还是“进程等待”类别。方向定对了动作就不会乱。4.2 哪些配置能从源头减少UNNAME文件的出现上一次线上故障解决后我顺手优化了几处配置后面同类问题明显少了很多分享出来。第一备库的归档目标和FRA要设计清晰。很多UNNAME问题本质是备库的LOG_ARCHIVE_DEST和DB_RECOVERY_FILE_DEST配置混乱RFS收到的日志被放置到某个不明确路径MRP0却去另一个路径找文件。我建议备库统一使用FRA接收归档并固定目录结构同时主库和备库的DB_RECOVERY_FILE_DEST_SIZE都给足余量至少保留一天的归档容量。第二FAL配置一定要正确。备库自动请求缺失日志靠的是FAL_SERVER参数它要指向主库的TNS别名而FAL_CLIENT指向备库自己。很多人把两个参数写反导致备库永远无法自动请求补日志只能靠人工处理。每次DG搭建完我都会在主备库分别执行SHOW PARAMETER FAL核对配置。第三主库归档删除策略要照顾备库。生产环境经常有人设置主库归档超过3天就自动删除备库因为网络或维护原因停了几天等备库恢复时主库已经把中间日志删光了。这种情况几乎必出UNNAME文件。我现在的做法是做好归档备份的前提下主库归档保留策略中额外判断备库是否已应用该段日志没应用就不允许清理。4.3 监控脚本的设计经验因为UNNAME文件是同步停止的典型信号我把它写进了日常监控。简单做法是定时脚本扫描备库alert日志一旦出现UNNAMED字样立即触发告警并顺手抓取V$MANAGED_STANDBY和V$ARCHIVE_GAP快照留档。这样即使DBA在睡梦中第二天也能直接定位到缺失范围。有条件的朋友还可以对V$ARCHIVE_GAP做轮询检查每5分钟一次查到非空结果就发短信和邮件同时自动执行主库归档日志存在性检查。这一步能大幅缩短故障发现时间。要知道DG同步停止不可怕可怕的是停了很久没有人发现UNNAME文件出现得越早恢复成本越低。我经历过一次半夜备库同步中断第二天上班才被业务侧发现的情况从那以后监控脚本里UNNAME关键字就再也没去掉过。最后再分享一个实际体会UNNAME文件只是表象核心永远是GAP。整个处理过程我都在心里默念“找到缺的日志补上它或者用增量追平它”。只要顺着这个思路走不管遇到UNNAMED00518还是UNNAMExxxxx都不会被吓住。顺手把备库的FRA容量和归档保留策略调整好这类问题出一次的频率会大幅下降。如果你也按这套流程处理过类似故障欢迎交流你那边见过的UNNAME变体形态很多新版本的Oracle在错误信息呈现上还会有些细微差别。
返回列表