尧图精选

Data Guard同步停止复盘:UNNAMED文件卡死MRP的排查与修复

🕒 发布时间:2026/10/2 9:10:13 📁 来源:尧图网络
一次dg同步停止的完整复盘UNNAME文件是怎么把Data Guard卡死的如果你管着一套 Oracle Data Guard那dg同步停止这六个字基本等于半夜手机被监控短信打爆的序曲。我这次遇到的还不是普通的 apply gap而是备库控制文件里直接躺了一个叫UNNAMED00018的文件——V$DATAFILE 里查得到条目磁盘上却压根没有实体文件。这篇就把整个过程摊开说UNNAME 文件怎么冒出来的、怎么一步步定位到它、备库上修复命令怎么敲以及事后如何防止同类问题反复出现。适合所有负责 Data Guard 日常运维、正准备接手 DG 环境的朋友。1. UNNAME文件现身一次dg同步停止事故的现场还原1.1 告警先行的周一早上那是个再普通不过的周一早上八点出头监控平台的消息就炸了PROD - DRC 数据同步停止apply lag 持续增长。我第一反应是网络抖动或者主库归档传输断了这种问题一般几分钟能缓过来。结果打开备库的V$ARCHIVED_LOG一看序列号停在1_14236_1182093407主库的 current log 已经跑到了1_14258_1182093407中间差了快二十个归档没应用——这不是瞬间抖动是恢复进程彻底卡死了。登录备库查V$DATAGUARD_STATUS不出意外满屏都是ORA-01157开头的报错。顺手翻备库的 alert log关键信息就挂在日志尾部Media Recovery Log /archivelog/1_14236_1182093407.dbf ORA-01157: cannot identify/lock data file 18 - see DBWR trace file ORA-01110: data file 18: UNNAMED00018看到UNNAMED00018的时候我心里其实咯噔了一下——这玩意出现了意味着备库的恢复进程不光是被某条归档卡住而是整个MRP0进程都会因为打不开数据文件直接退出。只要它退出后续所有从主库传来的归档全部无法应用gap 自然会越堆越大看起来就像dg同步停止。1.2 UNNAMED和普通数据文件有什么本质区别说句大实话很多 DBA 对 UNNAMED 文件只有一个模糊概念觉得哦就是备库上缺文件建一个就行了。其实它跟普通数据文件有个关键区别UNNAMED 文件的条目存在于控制文件里但磁盘上没有对应的真实文件。你可以理解成控制文件里有个空壳指针指向一个不存在的地址DBWR 进程每次尝试打开它都会失败。正因为如此v$datafile里能看到它的file#和状态但dba_data_files查不到对应行OS 层ls也找不到文件。备库恢复路径上也凑不齐完整数据集MRP 就只能在那边干瞪眼。再往深一层说UNNAMED 通常不是一个随机故障它的出现几乎都指向同一个根因主库新增了数据文件但备库侧因为路径映射、参数配置或者磁盘布局的问题没能生成对应的物理文件。我当时第一反应是先查一下主库近期有没有加过表空间或数据文件结果确实如此上周五业务侧在 PROD 上给TS_APP表空间加了一个 8GB 的新数据文件/data/prod/ts_app01.dbf。归档传过来后备库想按同样路径去/data/standby/创建文件但偏偏这个新路径不在DB_FILE_NAME_CONVERT设定的映射规则里——问题就是这么一环扣一环地出来的。2. 排查链路拆解从告警日志到V$DATAFILE的完整取证过程2.1 第一条命令永远不是修而是定位处理 DG 故障有个铁律先确认问题边界再动手修复。很多新手看到ORA-01157就直接去建文件结果把状态搞得更乱。我当时的排查顺序是这样的首先在备库执行SELECT thread#, MAX(sequence#) AS last_applied_seq FROM v$archived_log WHERE applied YES GROUP BY thread#;这一步是为了确认当前 apply 停在哪一个归档上。如果连last_applied_seq都查不出来说明 MRP 进程状态异常需要先看V$RECOVERY_PROGRESS或者直接查V$DATAGUARD_STATS。我这边的结果是1_14234比前面看到的传输位置又靠后了两位说明恢复进程在建立一致性检查点时也遇到了阻碍。然后看 MRP 是否还活着SELECT process, status, thread#, sequence#, block# FROM v$managed_standby;正常情况下这里应该能看到MRP0进程状态为APPLYING_LOG而我这边MRP0的状态是WAIT_FOR_LOG——不是正常的等待新日志而是等待条件满足但永远等不到因为打不开文件数据库处于一种半卡死状态。2.2 V$DATAFILE里的UNNAMED文件长什么样接着重点来了在备库上直接查 V$DATAFILESELECT file#, name, status, bytes, con_id FROM v$datafile WHERE name LIKE UNNAMED%;输出结果干净利落就一行FILE#NAMESTATUSBYTES18UNNAMED00018OFFLINE8589934592注意这个BYTES是 8GB跟主库新增的数据文件大小完全吻合。看到这两个信息基本可以断定主库新加了 8GB 数据文件备库这边没建出对应物理文件于是 Oracle 在控制文件里给它临时编了个UNNAMED00018的名字。此时这个文件处于 OFFLINE 状态MRP 应用归档时一旦碰到需要访问文件 18 的 redo 记录就会立刻报错退出。这里我多解释一句很多人看到 OFFLINE 以为既然离线了跳过它不就行了——在 DG 场景下不行。数据文件 offline 不等于你可以忽略它redo 记录里包含对这个文件的 block change恢复进程必须打开文件才能应用打不开整个 apply 就停下来没有任何讨价还价的余地。2.3 对照主库找出缺失文件对应的真实路径定位到 FILE# 18 之后下一步必须回到主库查出这个文件在端上的真实路径和归属表空间SELECT d.file_id, d.tablespace_name, d.file_name, d.bytes/1024/1024 AS size_mb FROM dba_data_files d WHERE d.file_id 18;我这边的结果是FILE_ID TABLESPACE_NAME FILE_NAME SIZE_MB 18 TS_APP /data/prod/ts_app01.dbf 8192到这里整个故障链路已经清晰得不能再清晰了主库新增数据文件/data/prod/ts_app01.dbf属于TS_APP表空间该文件对应的 redo 记录传到备库备库尝试应用时想把文件创建到/data/standby/ts_app01.dbf但DB_FILE_NAME_CONVERT的映射规则只覆盖了/data/prod-/data/standby这个旧目录而新文件虽然在/data/prod下……等等其实问题并不是映射规则没覆盖而是备库的 standby_file_management 参数当时是 MANUAL导致 Oracle 宁可生成 UNNAMED 占位也不愿意自动帮你把文件建出来这个细节我们放到第 4 节再展开先说排查的最后一步——确认有没有归档断层SELECT * FROM v$archive_gap;如果这里能查出一行THREAD# 1, SEQUENCE# 14235..14258说明主库对应的归档日志还在没有丢失后续修复完文件之后可以无缝接上。如果查出来是 NULL反而说明没有 gap所有日志都还在备库磁盘上修复会更快。3. 修复全流程备库执行CREATE DATAFILE的正确姿势3.1 动手前的最后一件事确认备库目录存在修复命令本身不长但有个前置条件容易被忽略备库上目标目录必须先存在。UNNAMED 文件之所以能生成往往是 Oracle 尝试自动创建文件但发现目录不存在或者参数不允许自动建文件。所以你执行ALTER DATABASE CREATE DATAFILE之前得先在备库服务器上把目录建好mkdir -p /data/standby chown oracle:oinstall /data/standby目录权限也得检查一下DBA 在备库服务器上的 OS 用户通常就是 oracle但保不齐有环境用 grid 用户管理 ASM那就得确认 ASM 磁盘组路径是否可写。路径没准备好命令敲下去会直接报ORA-01119创建数据文件出错白忙活一通。3.2 核心修复命令ALTER DATABASE CREATE DATAFILE一切就绪后在备库执行ALTER DATABASE CREATE DATAFILE /u01/app/oracle/oradata/DRC/UNNAMED00018 AS /data/standby/ts_app01.dbf;注意第一个参数是 V$DATAFILE 里查到的名字必须写全路径包括那个UNNAMED00018的文件名第二个参数是你希望创建的真实文件路径。这里我建议第二个路径跟主库的路径规则保持一致比如主库是/data/prod/ts_app01.dbf备库就老老实实建在/data/standby/ts_app01.dbf不要图省事丢到默认目录去。否则以后数据文件一堆你光靠名字根本对应不上主备关系。执行完这条命令后Oracle 会做一件背后的事它会从主库自动 fetch 这个数据文件的完整内容把它创建出来前提是 DG 主备链路正常、归档传输通道没断。这一步在 11g 以后基本不需要手动干预命令执行完你会看到类似这样的输出Statement processed.看似轻描淡写但实际过程可能持续几分钟取决于主库上文件大小和网络带宽。8GB 的文件千兆内网大概一分钟左右跨公网就得看运气了。那怎么确认文件真的创建好了呢两个验证点SELECT file#, name, status, online_status FROM v$datafile WHERE file# 18;如果状态从OFFLINE变成了ONLINE且NAME一列变成了/data/standby/ts_app01.dbf说明数据文件已经可用。再看 OS 层ls -lh /data/standby/ts_app01.dbf文件大小应该接近 8GB不一定严格等于主库的字节数因为建文件时可能分配了不同的初始 extent但整体量级不会差。3.3 重启恢复进程并验证同步追平数据文件就位之后MRP 还需要重新启动才能继续干活。备库上执行ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;这一条命令会把 MRP 进程拉起来继续从上次中断的归档位置开始应用。启动之后别急着走等两三分钟再查一次V$DATAGUARD_STATSSELECT name, value, unit FROM v$dataguard_stats WHERE name IN (apply lag, transport lag);两个指标都应该从分钟级/小时级往 0 收敛。我记得当时第一次查还是在00:03:21五分钟后再查就是00:00:00。这时候再对比主备库的序列号-- 主库 SELECT thread#, MAX(sequence#) FROM v$archived_log GROUP BY thread#; -- 备库 SELECT thread#, MAX(sequence#) FROM v$archived_log WHERE appliedYES GROUP BY thread#;两者差值归零告警自动恢复这次dg同步停止才算正式画上句号。3.4 一个容易踩的坑UNNAMED文件名写错导致的二次故障我在处理过程中其实还踩过一个附加坑——第一次执行ALTER DATABASE CREATE DATAFILE时把文件名写成了UNNAMED0018少打一个 0。Oracle 报ORA-01189: file is from different incarnation看着很像数据库版本问题其实只是文件名对不上。UNNAMED 文件的数字部分必须跟 V$DATAFILE 里的 FILE# 严格对应18 就是 UNNAMED00018前面补零补到五位不能自己乱拼。这个细节说大不大说小不小浪费了我十分钟查日志。4. 根因复盘备库为什么给你整出个UNNAMED文件4.1 standby_file_management参数的角色定位修复做完只是治标把根因挖出来才是治本。这次事故真正的源头是备库的standby_file_management参数被设置成了MANUAL。这个参数的作用就是决定备库在遇到主库新增数据文件时到底要不要自动帮你把文件建出来。它的两个取值差别巨大参数值行为适用场景AUTO备库自动创建缺失的数据文件推荐生产环境使用MANUAL不创建MRP 报错停止手动维护、特殊演练场景有人可能会问设置成 AUTO 是不是就永远不会出现 UNNAMED 文件了也不是。AUTO 只在路径映射能正确推导时才生效。如果备库侧目录不存在、权限不足、ASM 磁盘组空间不够AUTO 也会建文件失败最终还是可能落到 UNNAMED 的结局。所以参数对路径也得对两者缺一不可。4.2 路径映射与命名规范的连锁反应再挖一层路径映射这块怎么个对法DG 主备库如果目录结构完全一样比如主备都叫/data/app那 AUTO 模式直接用原路径创建即可如果目录不一样就得靠DB_FILE_NAME_CONVERT来定义映射规则。我当时的环境里这个参数原本只配了两对映射-- 主库参数文件里的配置示意 *.db_file_name_convert/data/prod,/data/standby从字面上看/data/prod到/data/standby的映射没问题。但问题恰恰出在主库新增的数据文件路径是/data/prod/ts_app01.dbf备库按规则应该创建/data/standby/ts_app01.dbf这个逻辑本身是对的。可为什么没建出来因为我当时的备库参数是 MANUAL——参数 override 了路径映射的自动行为。也就是说你就算映射规则配得再完美只要 standby_file_management 不是 AUTOOracle 也会按 MANUAL 的规则来发现缺文件直接报错不自动建。这段复盘让我意识到一个经验排查 UNNAMED 问题不要一上来就盯着 DB_FILE_NAME_CONVERT先看 standby_file_management 永远是第一优先级因为它直接决定了后续动作是自动建还是报错停。4.3 还有其他场景会生成UNNAMED文件吗除了这次的主因实际运维中还遇到过这么几种情况一并列出来给大家参考备库做过不完全恢复或控制文件重建控制文件里记录的数据文件和实际磁盘布局不一致扫描时生成了 UNNAMED 条目。快照备库Snapshot Standby转回物理备库快照期间主库新增了数据文件转换回来后部分文件未能同步可能在 V$DATAFILE 留下 UNNAMED。ASM 磁盘组路径不匹配主库用DATA1磁盘组备库只有DATA2又没有配置相应映射规则AUTO 也建不出来。手动更改了主库数据文件名称涉及数据文件 rename 的 redo 信息传到备库后如果备库找不到旧文件也会触发类似问题。以上场景有个共同特征UNNAMED 文件出现的一瞬间DG 同步必然停止。因为 Data Guard 的恢复进程对数据文件一致性要求极严格任何控制文件有而磁盘无的文件都会让 MRP 无法继续。所以看到 UNNAMED别想着要不要忽略它答案永远是不行。5. 后续加固三类配置加上一套巡检避免UNNAMED再犯5.1 参数层面的三条铁律这次事故之后我把 DG 环境的三条参数配置列为硬性检查项第一standby_file_management AUTO必须写进主备库的参数文件并且在例行变更后复查。因为总有人在做测试、做演练的时候把它临时改成 MANUAL改完忘了恢复。我后来在值班文档里加了一条凡是动过这个参数的变更结束后必须执行SHOW PARAMETER STANDBY_FILE_MANAGEMENT确认是 AUTO 才允许关闭工单。第二DB_FILE_NAME_CONVERT的映射规则要覆盖全库所有数据文件路径而不是基于当前有哪些路径来配置。很多库的历史包袱重有/oracle/data01、/data/prod、/u01/app/oracle等各种不同前缀的路径新增表空间时如果没检查映射规则AUTO 也白搭。我后来整理了一张路径规划表把主备库所有数据文件目录的映射关系都列出来每半年对一次新增目录第一时间更新参数。第三备用文件路径要有前瞻性。比如你预计明年要加一套独立存储/data/ssd_fast那就在规划表里提前把映射写进去别等到真要加文件了才改参数——生产环境改参数要停机窗口往往等不起。反正 DB_FILE_NAME_CONVERT 支持多条规则提前配好不犯法。5.2 变更流程里加一道备库体检资深的 DG 运维都知道主库做任何结构变更之前必须先在备库侧做一次环境检查。这个检查不是看备库还活着就行而是具体到目标路径是否存在、权限是否可写、映射规则是否覆盖、空间是否充足。我建议把这个检查固化成一个脚本每次主库建表空间、建数据文件前跑一遍。以一个简单的加数据文件场景为例变更前至少确认这三件事-- 1. 备库目标路径是否存在OS 层面确认 -- 2. 备库剩余空间是否大于新增文件大小 -- 3. DB_FILE_NAME_CONVERT 是否覆盖目标路径 SELECT value FROM v$parameter WHERE name db_file_name_convert;如果这三项都通过大概率不会撞上 UNNAMED 的问题。如果有一项没通过宁可先停下来改参数、建目录、清空间也不要带着隐患直接在主库加文件。5.3 日常巡检脚本的四个关键查询最后把这次排障用到的几个查询整理成一套日常巡检脚本建议放到监控平台或者 cron 里定期执行。四个关键查询-- 1. 查 UNNAMED 文件一旦有输出DG 基本已经出问题了 SELECT file#, name, status FROM v$datafile WHERE name LIKE UNNAMED%; -- 2. 查同步延迟 SELECT name, value FROM v$dataguard_stats WHERE name IN (apply lag, transport lag); -- 3. 查 MRP 进程状态 SELECT process, status FROM v$managed_standby WHERE process MRP0; -- 4. 查归档 gap SELECT * FROM v$archive_gap;这套巡检的价值在于它能让你第一时间发现苗头。打个比方UNNAMED 就像身体里的X光片上的阴影你等到警报响起再去看往往已经痛了很久但定期扫一遍出了问题当场就能按住。我处理完这次故障之后把 UNNAMED 的排查流程写成了一页速查卡出现ORA-01157先查V$DATAFILE里有没有 UNNAMED有就查主库对应 FILE# 的真实路径然后备库建目录、执行ALTER DATABASE CREATE DATAFILE、恢复 MRP。全程十五分钟搞定比摸黑排查舒服太多。Data Guard 故障并不可怕可怕的是你连控制文件里那个幽灵文件叫什么名字都不知道——经历过这次我至少不会再在这上面栽跟头了。
上一篇/下一篇内容由系统自动关联 返回资讯列表 →