尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Oracle DataGuard备库同步停止?UNNAMED文件成因与完整处理指南

Oracle DataGuard备库同步停止?UNNAMED文件成因与完整处理指南 1. 先说结论UNNAME 文件是什么同步停止和它有什么关系1.1 一次典型的“DG同步停止”事故现场做 DataGuard 运维的朋友应该都经历过半夜被监控电话叫醒的情况备库同步停了。而我遇到的比较典型的一次是备库的 MRP 进程直接挂了v$managed_standby里看不到正常的 APPLYING_LOG 状态主库的归档日志越积越多备库的告警日志里刷了几条ORA-01157、ORA-01110指向一个路径非常奇怪的数据文件。那个路径里带着一个大写的 UNNAMED 字样文件大小看着又不像普通的临时文件第一反应是“这文件是不是中毒了还是谁往库目录里塞了垃圾文件”。先直接说结论这不是病毒也不是运维误操作产生的垃圾文件而是 Oracle 在 DataGuard 场景下的一种“占位文件”机制。当备库的重做应用进程也就是 MRP发现主库传来的日志里包含了一个新数据文件的信息但备库又不知道该把文件放到哪里去时Oracle 就会先创建一个 UNNAMED 数据文件占住位置用来保证控制文件里记录的数据文件数量、文件号与主库一致。听起来很贴心但实际上如果你不及时处理备库的同步就会一直卡在这里甚至 MRP 进程直接终止。所以“dg同步停止”和“UNNAME文件”这两件事本质上是因果关系。UNNAMED 文件是同步停止的表象路径映射配置不完善才是病根。这篇文章我就围绕这个场景把定位思路、处理方法和预防措施完整讲一遍。1.2 为什么 Oracle 会生成 UNNAMED 文件要理解 UNNAMED 文件先要理解 DataGuard 备库怎么知道主库有哪些数据文件。物理备库在应用重做日志时会持续读取自己的控制文件。控制文件里记录了数据库所有数据文件包括文件号、文件路径、大小、检查点信息等。主库正常运行时如果添加了一个表空间或者数据文件主库的控制文件会更新然后通过归档日志或当前日志把相关信息传到备库。备库应用这条日志时发现自己控制文件里没有一个对应的数据文件记录就会尝试创建这个数据文件。问题就出在“尝试创建”这一步。Oracle 需要知道文件应该放在哪个目录它主要靠两个机制来决定一个是db_file_name_convert参数一个是 OMFOracle Managed Files自动文件名管理。如果主备库的路径不一致比如主库数据文件在/u01/app/oracle/oradata/PRI备库目录是/u02/app/oracle/oradata/STDBY而备库又没有配置db_file_name_convert或者转换规则写得不对Oracle 就无法从主库传来的路径推导出备库应该使用的路径。在这种情况下它不会直接报错让你手动处理而是会在一个默认目录下生成一个 UNNAMED 文件先把场景撑住。这个默认目录可能是备库数据文件目录、OMF 目录甚至是某个临时路径具体版本和配置不同会有差异。所以你在备库磁盘上看到的名字通常是UNNAMED....或者包含 UNNAMED 的子目录。还有一个常见场景备库的控制文件相对陈旧主库已经添加过数据文件但备库控制文件还没有更新到那一步。此时如果你使用增量备份或者REFRESH STANDBY之类的操作恢复进程可能会带着旧控制文件信息去创建新文件同样会产生 UNNAMED 文件。2. 同步停止的快速定位不要一上来就找文件遇到同步停止我的习惯是先从数据库层面确认状态再去看告警日志最后才去碰磁盘上的文件。因为如果只是单纯去删 UNNAMED 文件实际上解决不了任何问题甚至会让控制文件和数据文件完全对不上到时候要恢复的难度更大。2.1 三步确认备库当前到底在干嘛第一步看数据库角色和打开模式。用下面的 SQL 查询select database_role, db_unique_name, open_mode, protection_mode, protection_level from v$database;正常情况下一个物理备库应该显示PHYSICAL STANDBY、READ ONLY WITH APPLY保护级别最多是MAXIMUM PERFORMANCE。如果你看到READ ONLY而没有WITH APPLY说明 MRP 没有在跑。如果 open_mode 显示MOUNTED那通常是 MRP 正在执行或者出现了严重错误导致没有打开这种情况要单独分析。第二步看 MRP 进程状态select process, status, client_pid, thread#, sequence# from v$managed_standby order by process;这里重点关注MRP0这行。如果你看到APPLYING_LOG说明正在应用日志同步其实没停只是可能有延迟如果看到WAIT_FOR_LOG表示 MRP 正在等待新日志这通常是正常状态不代表停止但如果看到ABORTED、ERROR那 MRP 已经退出了这才是真正意义上的“同步停止”。第三步查归档缺口。同步停止后最怕出现日志缺失一旦日志真的丢了光靠重启 MRP 是没用的。在备库上执行select * from v$archive_gap;如果查询有返回结果说明备库缺少某些日志序号。这个输出里会告诉你 thread# 和 sequence#比如线程 1、日志序号 100 到 105 缺了。这种情况下就算处理完 UNNAMED 文件也必须先把缺失的日志从主库复制到备库否则 MRP 还是无法继续。没有返回结果才是相对好的消息说明日志没有缺口卡住的原因单纯在应用环节。2.2 告警日志是定位 UNNAMED 的关键线索数据库层面的三张视图能帮你判断“停了”但想知道“为什么停”还得看告警日志。告警日志的位置用下面这个 SQL 可以查到不同版本和 DIAG 环境下路径差异很大我一般直接查字典select value from v$diag_info where name Diag Alert;然后按时间倒着看最后几十行。UNNAMED 文件对应的问题在日志里通常长这样ORA-01157: cannot identify/lock data file 12 - see DBWR trace file ORA-01110: data file 12: /u01/app/oracle/oradata/STDBY/UNNAMED/datafile/o1_mf_users_xxx_.dbf这两行要放到一起看。ORA-01157说的是数据库无法识别或锁定某个数据文件ORA-01110紧接着告诉你具体是哪个文件文件名里带着 UNNAMED。看到这种组合基本可以锁定了备库要应用涉及第 12 号数据文件的日志但这个文件是 UNNAMED 占位文件里面的内容并不是从主库完整复制过来的DBWR 进程无法正常读写它MRP 自然就会终止。还有一种情况备库日志里可能不会直接出现 ORA-01157而是出现类似ORA-01274或ORA-16047之类的错误原因是多种多样的。但如果错误文本里带了数据文件路径且路径中包含 UNNAMED优先级很高先按 UNNAMED 文件去处理。2.3 常见同步停止原因对照表先别急着往下操作我把实战中遇到过的 DataGuard 同步停止原因列个表方便你对照排查。这能帮你判断 UNNAMED 是主因还是次生问题。现象可能原因处理方向MRP 状态 ABORTED告警日志出现 ORA-01157/ORA-01110数据文件无法访问或 UNNAMED 占位文件按本文第 3 节处理v$archive_gap 有返回结果主库日志传输中断归档日志丢失重新传输归档必要时做增量备份MRP 状态正常但 apply lag 不断增长备库性能不足、磁盘 I/O 慢分析备库会话和系统负载主备日志传输目的地产 ERROR网络断、磁盘满、目录权限不对检查 tnsnames、监听、磁盘空间备库磁盘空间不足归档日志或数据文件撑满磁盘清理归档、增加磁盘空间密码文件不一致主备切换后密码不对重建备库密码文件UNNAMED 文件只是这张表里的一个小分支但因为它出现的频率不低而且处理方式和其他问题差异很大所以值得单独拿来说。3. 处理 UNNAMED 文件的完整实操流程处理 UNNAMED 文件的核心思路不是把文件删掉而是把它“替换”成一个路径正确、内容可用的真实数据文件。Oracle 提供了一条命令alter database create datafile ... as ...专门用来解决这类场景。下面我按顺序走一遍。3.1 先找到是哪个文件归属哪个表空间在备库执行以下 SQL把 UNNAMED 文件列表完整捞出来select file_id, tablespace_name, bytes/1024/1024 as size_mb, name from v$datafile where name like %UNNAMED%; select file_id, tablespace_name, bytes/1024/1024 as size_mb, name from v$tempfile where name like %UNNAMED%;v$datafile查的是永久表空间的数据文件v$tempfile查的是临时表空间文件。两段查询如果你都有返回结果说明 permanent 和 temp 两类占位文件都存在处理顺序是先 permanent 后 temp。拿到file_id之后一定要先去主库看一眼同一个文件的真实路径。这个动作很关键因为alter database create datafile ... as ...后面填的路径应该是你希望备库最终使用的路径。如果你连主库文件叫什么名字、表空间是什么都不清楚后面很容易写错目标路径。主库查询语句select file_id, tablespace_name, bytes/1024/1024 as size_mb, name from v$datafile where file_id fileid;假设两边表空间都是USERS主库真实文件路径是/u01/app/oracle/oradata/PRI/users01.dbf备库目标路径建议设置成/u02/app/oracle/oradata/STDBY/users01.dbf避免沿用 UNNAMED 的那个怪异目录。3.2 用 create datafile 重建真正的数据文件确认好路径后在备库执行类似下面的命令alter database create datafile /u01/app/oracle/oradata/STDBY/UNNAMED/datafile/o1_mf_users_xxx_.dbf as /u02/app/oracle/oradata/STDBY/users01.dbf;也可以直接使用文件号alter database create datafile 12 as /u02/app/oracle/oradata/STDBY/users01.dbf;执行之后Oracle 会在指定的新路径下创建一个完整的、可用的数据文件。这里很多人会误解这条命令不是把原来的 UNNAMED 文件重命名也不是简单的文件复制。它会从备库控制文件中读取数据文件相关的元数据然后利用最近的增量备份信息或者重做日志信息把数据文件内容恢复到一致状态。所以命令执行完成后占位文件的内容被替换成了可以参与应用的正常文件。需要注意如果备库当前处于 mount 状态且 MRP 已经启动这条命令通常可以热执行不会影响 MRP。但如果 MRP 正处于错误状态且告警日志还在报错我建议先执行alter database recover managed standby database cancel;把 MRP 停下来然后处理数据文件处理完再重新启动 MRP。这样操作有个好处避免在 Oracle 还在尝试读取坏文件的时候你同时去修改文件两边打架。3.3 临时文件的 UNNAMED 处理临时表空间文件和永久数据文件的处理逻辑不一样。临时文件不需要通过 redo 恢复内容所以不能用alter database create datafile as ...直接重建。处理方式通常是先给临时表空间添加一个正常的新临时文件再删除 UNNAMED 临时文件。在备库执行alter tablespace temp add tempfile /u02/app/oracle/oradata/STDBY/temp02.dbf size 2g; alter tablespace temp drop tempfile /u01/app/oracle/oradata/STDBY/UNNAMED/tempfile/o1_mf_temp_xxx_.dbf;第一句话添加了一个真实可用的临时文件第二句话把不合理的 UNNAMED 临时文件从控制文件中移除。如果你不想指定大小可以用size 2g这种显式方式也可以根据主库原文件大小来设置。要注意的是临时表空间文件数量变多了磁盘空间占用会变大我建议先查主库临时文件总大小再决定备库新文件大小避免备库磁盘被撑爆。如果表空间是默认临时表空间不能先删光所有临时文件再添加因为默认临时表空间至少要有一个可用文件。所以顺序一定是 add 再 drop不是 drop 再 add。3.4 恢复同步并验证结果处理完 UNNAMED 文件后重新启动日志应用进程alter database recover managed standby database using current logfile disconnect from session;然后观察 MRP 状态select process, status, thread#, sequence# from v$managed_standby where process MRP0;如果状态变成APPLYING_LOG说明 MRP 正在追赶日志。再用下面这条语句看同步延迟select name, value, unit, time_computed from v$dataguard_stats where name in (transport lag, apply lag);理想情况下apply lag应该逐步变小最后变成 0 秒。如果apply lag一直不降说明备库在大量追赶日志还没追平可以继续等一会儿。同时再查一次v$archive_gap确保没有新缺口。也可以顺手确认一下 UNNAMED 文件是否已经不在控制文件里了select file_id, name from v$datafile where name like %UNNAMED%; select file_id, name from v$tempfile where name like %UNNAMED%;如果返回空结果说明数据库层面已经清理干净。4. 防止再次踩坑路径转换与文件管理策略处理完一次 UNNAMED 文件如果不去改配置下次主库再加一个数据文件你还会遇到同样的问题。所以这一节非常重要看完可以直接把配置整理到自己的备库里。4.1 db_file_name_convert 参数详解db_file_name_convert是物理备库上解决主备路径不一致最核心的参数。它把主库文件名中的前缀转换为备库路径前缀。格式是一个逗号分隔的“成对”列表奇数位是主库前缀偶数位是备库前缀。例如主库目录是/u01/app/oracle/oradata/PRI备库目录是/u02/app/oracle/oradata/STDBY备库参数可以写成alter system set db_file_name_convert /u01/app/oracle/oradata/PRI, /u02/app/oracle/oradata/STDBY scopespfile;在 RAC 环境下每个节点可能都有自己的路径转换规则也要分别考虑。设置完成后需要重启数据库或至少重启 MRP这里要注意一个细节db_file_name_convert是静态参数修改后需要重启数据库实例才能完全生效。好在一般情况下你已经在处理停机窗口了重启一次备库影响不大。查看当前生效值show parameter db_file_name_convert;如果输出为空说明没有设置转换规则。这时候主备路径如果有差异加载新数据文件时大概率还会继续生成 UNNAMED 文件。4.2 主备文件目录设计和管理策略很多人以为只要db_file_name_convert配了就可以高枕无忧。其实还有一个隐藏杀手是 OMF。OMF 模式下Oracle 会自动生成文件名比如o1_mf_users_abc123_.dbf并且目录结构里通常会带上数据库的db_unique_name。如果主库的db_unique_name是PRI备库是STDBY那么即使你配了路径转换OMF 自动生成的文件名也很可能对不上备库预期导致 UNNAMED 文件再次出现。所以我的建议是生产环境优先保证主备库目录结构高度一致。也就是说主库文件在/u01/app/oracle/oradata/PRI备库也建立同样的目录/u01/app/oracle/oradata/PRI虽然备库的 db_unique_name 不同但数据文件路径保持一致让db_file_name_convert甚至可以不设置。这种方式最简单兼容性也最好。如果无法保持目录一致比如备库磁盘挂载点就是和主库不一样那么一定要同时检查db_file_name_convert和 OMF 相关参数show parameter db_create_file_dest; show parameter db_file_name_convert; show parameter log_file_name_convert;此外log_file_name_convert对应在线日志和备用日志的转换很多人会漏掉。standby redo log 路径不对同样也会导致日志应用异常只是它产生的错误不是 UNNAMED 文件而已。4.3 添加表空间时容易忽略的两个细节主库 DBA 添加表空间时习惯写法往往是create tablespace users02 datafile size 1g;这种写法完全依赖 OMF 生成文件名和数据文件路径。如果在主库这么做且主备库目录不一致备库收到日志时就只能从控制文件里读取一个 OMF 风格路径转换规则没有覆盖到位就很容易卡住。更稳妥的写法是显式指定数据文件路径create tablespace users02 datafile /u01/app/oracle/oradata/PRI/users02.dbf size 1g;这样主备库的转换规则至少能明确匹配到前缀。即便你不想每次写路径也建议至少保证 OMF 使用的路径前缀被db_file_name_convert覆盖。还有一个细节主库删除表空间后备库的 UNNAMED 文件并不会自动消失。如果你在主库执行了drop tablespace ... including contents and datafiles备库控制文件里的对应记录会在应用日志后自动清理但如果当时已经产生了 UNNAMED 占位文件物理磁盘上的文件残留可能还在。数据库层面看不见不代表磁盘上不存在后期运维清理磁盘时要留意。4.4 监控和自动修复建议这节算是我自己的日常防御手段。我会在备库主机上放一个简单的巡检脚本定时查询 UNNAMED 文件是否出现#!/bin/bash ORACLE_SIDSTDBY export ORACLE_SID sqlplus -s / as sysdba EOF set pages 0 set lines 200 select file_id, tablespace_name, name from v$datafile where lower(name) like %unnamed%; select file_id, tablespace_name, name from v$tempfile where lower(name) like %unnamed%; exit EOF只要脚本有输出说明出现了新的 UNNAMED 文件这时候就需要人工介入因为自动执行alter database create datafile as ...存在一定风险尤其是目标路径、空间、主文件信息都需要人工核对。我不建议对这类操作做全自动修复但自动发现并告警非常有价值。同时监控告警里要加入v$dataguard_stats的 apply lag一旦超过阈值比如 5 分钟立刻触发工单。因为等到你人工发现同步停止时往往主库归档日志已经积压很久了。5. 常见问题与排查技巧实录最后整理一些我实际踩过、或者帮别人处理过的问题做成速查表。5.1 高频问题速查表问题原因处理方法UNNAMED 文件能不能直接rm删除不能直接删会让控制文件和数据文件记录失配用alter database create datafile ... as ...替换alter database create datafile报 ORA-01565目标文件路径目录不存在先创建目录再执行命令备库已经有 UNNAMED 文件但 MRP 还在跑该文件可能涉及的表空间未被当前日志使用尽早处理避免后续日志应用再次报错主库删了表空间备库还留着 UNNAMED 文件日志应用被中断或控制文件未同步追日志或重新做主备一致性校验备库磁盘空间不足导致 MRP 终止归档日志过多或数据文件增长超预期清理归档扩充磁盘再启动 MRP处理完 UNNAMED 后 MRP 还是报错可能还有其他未被发现的 UNNAMED 文件重新执行 v$datafile / v$tempfile 查询db_file_name_convert配置后不生效参数是静态参数未重启实例重启备库实例后生效主库和备库文件系统不一致一边 ASM 一边文件系统路径转换规则需覆盖 ASM 磁盘组名配置DATA/PRI到/u02/oradata/STDBY的转换5.2 几条实战建议第一处理 UNNAMED 文件前先备份备库控制文件。这是个非常便宜的操作但是很多人不做。执行alter database backup controlfile to /tmp/stdby_control.ctl;万一你在处理过程中把控制文件搞坏了至少还有一份可以还原的控制文件。文件号如果改来改去控制文件备份的价值会非常大。第二alter database create datafile并不需要你先把 UNNAMED 文件从磁盘删除。如果你手动把磁盘上的 UNNAMED 文件删除再执行命令没问题但如果你不删命令执行也不会受影响因为它会在目标路径创建一份新文件占位文件继续留在磁盘上。但最终要记得确认数据库层面没有指向 UNNAMED 的记录了然后把磁盘残留文件清掉。第三如果备库同时存在多个 UNNAMED 数据文件不要试图一次性把所有文件都改完。建议一次处理一个处理完立即看 MRP 是否继续运行。如果 MRP 已经能够应用日志但后面又遇到下一个 UNNAMED 文件它会再次停下你继续处理下一个即可。一次改多个出问题时不好定位是哪个文件引起的。第四主备库巡检时不仅要看v$datafile还要看dba_temp_files。临时文件的 UNNAMED 可能不直接影响 MRP 应用但会影响备库在只读打开状态下的排序、临时表操作尤其是你用备库做报表查询时临时文件路径不对会直接报错。第五如果主库出现了大量数据文件变更比如批量添加分区、批量重建表空间建议你手动在主库采集一次数据文件清单然后在备库对比一次不要等着报错再查。毕竟 UNNAMED 文件本身并不会导致主库故障但它是个信号说明你的 DataGuard 路径管理已经处于危险边缘。最后再分享一个小习惯每次做完主备文件路径调整我都会在主库和备库上分别执行一遍全量数据文件清单导出然后 diff 一次文件名和文件号。这个操作五分钟内能完成却能帮你把绝大多数路径类问题扼杀在摇篮里。DataGuard 的稳定性从来都不是靠出事后的灵光一现而是靠日常的一次次一致性核对。
返回列表