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

资讯详情

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

Oracle RAC 到单实例 Data Guard 搭建:RMAN 备份恢复与日志同步实战

Oracle RAC 到单实例 Data Guard 搭建:RMAN 备份恢复与日志同步实战 去年年底我接手了一套 Oracle 11g R2 RAC 环境生产集群两个节点跑得稳稳当当可一提到容灾和报表库问题就来了再上一套 RAC 备库硬件和授权成本直接翻倍领导不批。几轮方案比对下来最后落地成了 RAC 到单实例的 Data Guard主库继续双节点对外服务备库用一台还不错的物理机撑着成本降了一截日常备份压力也小了很多。搭建方式选择的是 RMAN 备份恢复这也是我这些年用下来最稳妥、最可控的一套流程。网上关于这个场景的文档零零散散多数是单实例到单实例的 DG 搭建真正说清楚 RAC 到单实例差异的并不多。所以我把这次实施过程完整梳理了一遍包括参数配置、备份恢复、日志同步验证和几类典型故障给后面要做同场景的人一份能直接照着干的记录。内容比较细适合已经具备一定 Oracle 基础、想独立完成 DG 搭建的运维或 DBA 同学参考。1. 方案背景与整体思路为什么 RAC 到单实例偏偏要这么搭1.1 什么样的场景需要这种“不对称”容灾RAC 解决的是单点故障和横向扩展但它在容灾层面并不能替代 Data Guard。生产库如果只有一套 RAC一旦机房级别故障或者存储整体损坏再好的集群架构也是白搭。所以只要预算稍微宽裕一点DBA 第一反应基本都是“给 RAC 加一套备库”。备库一定要同样规格的 RAC 吗未必。备库不承担生产写负载主要任务是日志应用和只读查询单实例数据库完全可以胜任。用单一台性能还不错的服务器配上和主库同版本的 Oracle 软件就能通过 Data Guard 把 RAC 的所有 redo 数据传输过去持续应用。这种不对称架构最大的好处有三个成本低、管理简单、对机房空间和存储的要求大幅下降。1.2 为什么选 RMAN 备份恢复而不是直接复制数据库搭建备库的思路大致有两条一条是直接对生产库做文件级复制另一条就是走 RMAN 备份恢复。文件级复制听起来快但操作窗口很难控制尤其 RAC 环境涉及 ASM 磁盘组、多个节点的在线日志稍不留神就把一组还没归档的 redo 目录一起拷了备库起来后根本无法一致恢复。RMAN 方式的好处在于它天然具备一致性保证。backup database plus archivelog会自动把备份开始前和结束后的归档日志全部纳入备份集恢复时再用 standb y controlfile 把数据库拉起能精准恢复到备份结束的那个 SCN之后直接交给 Data Guard 的日志应用进程接管几乎不会出现数据断层。整个过程对生产影响很小基本可以放在业务低峰期在线完成也不需要停库。1.3 架构拓扑与关键点RAC 多 Thread 的特殊性RAC 和单实例在 DG 层面最大的区别就是 redo thread。单实例只有一个日志线程而 RAC 每个实例都有独立的 redo thread日志序列号按 thread 独立递增。这意味着备库必须能同时接收并应用多个 thread 的日志需要为每个 thread 都准备至少一组 standby redo log否则某个节点的日志到了备库却没有对应的接收文件就会一直卡住。另一个关键点是主库所有节点的 DG 参数必须保持一致特别是LOG_ARCHIVE_CONFIG、LOG_ARCHIVE_DEST_n这类参数不能只在某一个实例上设置。实际环境中很多人在这上面翻车明明参数已经改了另一个实例却不生效导致日志传输间歇性失败。所以实施时建议所有 DG 相关参数都通过SID*写入 spfile让整个集群统一生效。2. 环境规划与前置检查开工前把这些事做明白2.1 主机与实例命名规划命名规划是这一整套操作的地基尤其是DB_UNIQUE_NAME它必须和 TNSNAMES 里的 service name 清晰对应后面所有配置都要围绕这几个名字转。我这边的规划如下你可以按自己的环境替换。角色主机名实例名DB_UNIQUE_NAME平台主库节点1rac1orcl1orclOracle Linux 7, x86_64主库节点2rac2orcl2orclOracle Linux 7, x86_64备库stbyorcl_stborcl_stbOracle Linux 7, x86_64这里要特别注意DB_NAME主备都是orclDB_UNIQUE_NAME必须不同。DG 判断主备身份、校验日志归属靠的正是DB_UNIQUE_NAME。如果两边设置成一样的日志传输会直接报错最常见的错误就是 ORA-16047。2.2 版本一致性与补丁检查Data Guard 对主备库的版本兼容性要求很严格。最好的实践是主备软件版本和补丁完全一致至少也要满足 Oracle 官方支持的组合关系。我这次主库跑的是 11.2.0.4备库也装相同版本小版本补丁尽量对齐避免日志传输或者角色切换时出现不可预知的内部错误。检查版本的命令很简单SQL SELECT * FROM V$VERSION; SQL SELECT COMP_ID, VERSION, STATUS FROM DBA_REGISTRY;如果发现主库打了额外的 PSU备库也建议打上同样的补丁。Oracle 的 DG 在跨 PSU 场景下大部分时间没问题但真碰上内部 bug 修复涉及的场景排查起来会非常痛苦。版本一致性在 DG 建设里属于“少踩一个坑就少熬一个夜”的关键项。2.3 主库基线检查归档、强制日志、密码文件主库需要提前确认几个基础条件每一项都会直接影响后续同步能否跑通。最核心的是归档模式和强制日志命令如下SQL ARCHIVE LOG LIST; SQL SELECT FORCE_LOGGING, SUPPLEMENTAL_LOG_DATA_MIN FROM V$DATABASE; SQL ALTER DATABASE FORCE LOGGING; SQL ALTER DATABASE ADD SUPPLEMENTAL LOG DATA;强制日志不是必选项但建议开启。如果生产库里存在 nologging 操作备库在应用这些数据块时会直接报错哪怕是 DG 也无法绕开。既然要做备库就尽量把FORCE LOGGING打开一劳永逸。密码文件也是很容易被忽略的点。DG 日志传输本质是备库通过主库的 sys 权限去远程接收 redo双方密码文件不一致时最常见报错是 ORA-16191。建议在实施前就把主库的$ORACLE_HOME/dbs/orapwsid直接复制到备库并重命名保证 sys 密码完全一致省去后续一堆麻烦。2.4 备库软件安装与目录准备备库不需要装 Grid但需要和主库完全相同的 Oracle Database 软件版本。安装时选择“仅安装数据库软件”不要建库。装完以后要手工创建备库的目录结构尤其是数据文件目录、控制文件目录、监听目录、归档目录这些路径会写进 pfile 和后续恢复命令里提前规划好可以避免恢复时临时改路径。目录规划示例mkdir -p /data/orcl_stb/datafile mkdir -p /data/orcl_stb/onlinelog mkdir -p /u01/arch/orcl_stb mkdir -p /u01/app/oracle/admin/orcl_stb/adump mkdir -p /u01/app/oracle/admin/orcl_stb/dpdump备库的监听器也要先启动起来并确保主库节点能够通过 TNSNAMES 访问到备库的 service name。DG 日志传输对网络稳定性要求不低如果中间有防火墙记得放通 1521 端口否则后面会频繁出现 ORA-16009 之类的传输失败。3. 参数配置、Standby Redo Log 与主库备份把地基打好3.1 主库 DG 相关参数设置主库参数是 DG 的心脏。在 RAC 环境下所有 DG 参数都建议用SID*写入 spfile确保每个实例的配置完全一致。核心参数如下ALTER SYSTEM SET LOG_ARCHIVE_CONFIGDG_CONFIG(orcl,orcl_stb) SCOPESPFILE SID*; ALTER SYSTEM SET LOG_ARCHIVE_DEST_1LOCATIONUSE_DB_RECOVERY_FILE_DEST VALID_FOR(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAMEorcl SCOPESPFILE SID*; ALTER SYSTEM SET LOG_ARCHIVE_DEST_2SERVICEorcl_stb LGWR SYNC VALID_FOR(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAMEorcl_stb SCOPESPFILE SID*; ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_1ENABLE SCOPESPFILE SID*; ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2ENABLE SCOPESPFILE SID*; ALTER SYSTEM SET FAL_SERVERorcl_stb SCOPESPFILE SID*; ALTER SYSTEM SET FAL_CLIENTorcl SCOPESPFILE SID*; ALTER SYSTEM SET STANDBY_FILE_MANAGEMENTAUTO SCOPEBOTH SID*;简单解释几个关键点。LOG_ARCHIVE_DEST_1是本地归档我用了快闪恢复区USE_DB_RECOVERY_FILE_DEST前提是主库已经配置了DB_RECOVERY_FILE_DEST你也可以改成实际路径只要确保两个 RAC 节点都能写入。LOG_ARCHIVE_DEST_2指向备库用了LGWR SYNC这是保护级别最高的同步模式能保证主库 redo 写出的同时同步传到备库。如果对延迟敏感可以考虑ASYNC保护级别会降一级需要根据业务场景权衡。这里还要提醒一下修改这些参数后需要重启所有实例才能完全生效。部分参数如STANDBY_FILE_MANAGEMENT用SCOPEBOTH可以立即生效但像LOG_ARCHIVE_CONFIG这类稳妥起见还是安排一个维护窗口把整个集群重启一遍。3.2 Standby Redo Log 创建方案Standby Redo Log 是备库接收主库 redo 的专用日志文件和普通的 online redo log 是两回事。RAC 主库有几个线程备库就必须为每个 thread 配置足够的 SRL否则对应节点的日志就无法顺利接收和应用。建议主库和备库都创建 SRL。主库创建的 SRL 是为了将来执行 switchover 时主库切换成备库角色后能正常接收新主库发来的日志备库的 SRL 则是本次搭建的核心直接决定日志能否应用。SRL 大小最好与主库 online redo log 保持一致或者取所有节点 redo log 的最大值。我这边主库每组 redo 是 200M每个节点 4 组备库 SRL 也按 200M 创建每个 thread 至少 2 组-- 主库执行每个节点至少2组SRL ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 21 (DATA/orcl/onlinelog/std_1_21.log) SIZE 200M; ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 22 (DATA/orcl/onlinelog/std_1_22.log) SIZE 200M; ALTER DATABASE ADD STANDBY LOGFILE THREAD 2 GROUP 23 (DATA/orcl/onlinelog/std_2_23.log) SIZE 200M; ALTER DATABASE ADD STANDBY LOGFILE THREAD 2 GROUP 24 (DATA/orcl/onlinelog/std_2_24.log) SIZE 200M;备库因为用的是文件系统路径就直接指向/data/orcl_stb/onlineloggroup 号码可以重新排避免和 online redo log 冲突。后面恢复完成后在备库执行同样结构的建 SRL 语句即可。3.3 RMAN 全库备份与归档日志备份主库一切就绪后就可以开始备份了。建议在其中一个节点执行不需要两个节点都跑。我习惯先把备份目录准备好再写一个带上次备份归档的完整备份命令mkdir -p /backup/orcl_full rman target / RMAN BACKUP DATABASE PLUS ARCHIVELOG DELETE INPUT FORMAT /backup/orcl_full/full_%d_%T_%s_%p.bak; RMAN BACKUP CURRENT CONTROLFILE FORMAT /backup/orcl_full/ctrl_%d_%T_%s_%p.bak;PLUS ARCHIVELOG这个关键字很关键它会自动把备份开始前的未备份归档、备份过程中产生的增量归档都纳入同一个备份集确保数据库备份是一致性恢复点。加DELETE INPUT可以顺便清理已经备份过的归档日志减少主库 FRA 和归档目录的空间压力。RMAN 备份在 RAC 节点上执行时备份进程会自动读取共享存储上的数据文件所有节点的归档日志也能被扫描到不需要特殊处理。唯一要注意的是备份目录必须放在所有节点都能访问的位置如果放节点本地磁盘RMAN 只会从当前节点读不到别的节点产生的归档这个坑我后面会细说。3.4 生成备库控制文件与参数文件备份完成后还需要两张“入场券”备库控制文件和参数文件。备库控制文件要单独生成不能用普通备份里的控制文件必须用 standby controlfile 格式。SQL ALTER DATABASE CREATE STANDBY CONTROLFILE AS /backup/orcl_full/standby_control.ctl;参数文件方面我是直接从主库 spfile 生成一个 pfile再手工修改备库差异项SQL CREATE PFILE/backup/orcl_full/init_orcl_stb.ora FROM SPFILE;生成的 pfile 需要重点修改的内容包括db_unique_name、control_files、fal_server、fal_client、归档路径、临时文件路径等。这个文件后面会被拷到备库作为备库的启动参数文件所以里面的每一项都要仔细核对尤其是路径转换规则。4. 备库恢复把备份变成可接管的备用库4.1 备库启动与恢复控制文件备份文件、standby controlfile、pfile 都准备好后接下来就是备库侧的重头戏。先把主库上的备份集和 pfile 安全拷到备机注意目录结构要保持一致或者在 pfile 里同步修改路径。备库首次启动要用 nomount 模式这个时候还没有控制文件。先根据修改好的 pfile 启动实例再用 RMAN 恢复 standby controlfilescp oraclerac1:/backup/orcl_full/* stby:/backup/orcl_stb/备库上执行export ORACLE_SIDorcl_stb sqlplus / as sysdba SQL STARTUP NOMOUNT PFILE/u01/app/oracle/product/11.2.0/dbhome_1/dbs/init_orcl_stb.ora;然后进入 RMANrman target / RMAN RESTORE STANDBY CONTROLFILE FROM /backup/orcl_stb/standby_control.ctl; RMAN ALTER DATABASE MOUNT STANDBY DATABASE;恢复控制文件后立刻以MOUNT STANDBY的方式挂载数据库这个状态会一直保持到日志应用进程启动。如果你发现控制文件恢复时报路径相关错误先检查 pfile 里control_files的路径是否存在、权限是否正确。4.2 数据文件恢复与日志应用控制文件就位后数据库已经知道自己的文件清单了。接下来用 RMAN 恢复数据文件。恢复前最关键的一步是确认路径转换规则。我这次备库没有用 ASM全部放到文件系统需要在 pfile 里配置两个参数db_file_name_convertDATA/orcl/datafile,/data/orcl_stb/datafile log_file_name_convertDATA/orcl/onlinelog,/data/orcl_stb/onlinelog这组参数的作用是把主库的 ASM 路径自动替换成备库的文件系统路径。如果路径比较复杂也可以不用参数改在 RMAN 里用SET NEWNAME配合SWITCH DATAFILE ALL手动指定但这个方案对文件数量多的情况更繁琐容易遗漏我个人更推荐参数自动转换。确认参数无误后直接恢复RMAN RESTORE DATABASE; RMAN RECOVER DATABASE UNTIL CANCEL; RMAN CANCEL;这里的RECOVER DATABASE UNTIL CANCEL会把备份集里包含的归档日志全部应用完然后遇到“需要下一份日志”时暂停。此时备库已经追平到备份结束时刻可以退出 RMAN 去启动 MRP 进程进行实时应用了。4.3 备库参数再确认与路径细节数据文件恢复完成后先别急着开 MRP回到 SQLPLUS 检查一遍关键参数这一步能提前暴露大量问题。重点检查DB_UNIQUE_NAME是否还是orcl_stbLOG_ARCHIVE_CONFIG是否包含主备两个名字FAL_SERVER是否指向主库的 service nameSTANDBY_FILE_MANAGEMENT是否为 AUTO。还要确认备库的 TNSNAMES 配置完整至少要有两个条目主库的 service name 和备库自己的 service name。备库FAL_SERVER在 RAC 环境下建议写成两个节点的 service name用逗号分隔FAL_SERVER (orcl1,orcl2) FAL_CLIENT orcl_stb这样即使主库某一个节点因为维护重启备库也能通过另一个节点继续请求缺失的日志降低 gap 出现的概率。日志传输方向一旦恢复正常MRP 进程会自动补齐中间产生的日志。4.4 开启实时应用与首次验证在备库执行实时日志应用让日志一到备库就能立刻应用而不是等归档文件落地后再应用SQL ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;执行后备库会启动 MRP 进程持续从主库接收并应用 redo。首次验证建议看两个方向备库的 MRP 状态以及主库侧的日志传输状态。备库侧检查SQL SELECT PROCESS, STATUS, CLIENT_PROCESS, THREAD#, SEQUENCE# FROM V$MANAGED_STANDBY;如果能查到MRP0进程且状态为APPLYING_LOG说明日志应用已经在跑。主库侧再确认传输无报错SQL SELECT DEST_ID, DEST_NAME, STATUS, ERROR, DATABASE_MODE, DB_UNIQUE_NAME FROM V$ARCHIVE_DEST_STATUS;传输状态为VALID、没有 ERROR 列输出就是一个非常健康的开始。到这里整套 DG 架构已经算真正跑通了后续就是持续观察日志应用延迟和 gap 情况。5. 日志同步验证与日常监控别搭完就撒手5.1 主库归档传输状态核查DG 搭完只是第一步运行稳定才是目标。我最常用的一套核查命令就是围绕V$ARCHIVE_DEST_STATUS和V$ARCHIVED_LOG展开的。主库侧要确认每个节点的 redo 都能送到备库而不是只有一个节点能传。SELECT THREAD#, SEQUENCE#, DEST_ID, STATUS, ARCHIVED, APPLIED FROM V$ARCHIVED_LOG WHERE SEQUENCE# (SELECT MAX(SEQUENCE#) - 5 FROM V$ARCHIVED_LOG) ORDER BY THREAD#, SEQUENCE# DESC;一个值得注意的细节是RAC 环境下主库两个节点的日志是分开计数的查询时最好按 thread 分组看。如果发现某个 thread 的最新 sequence 明显落后说明该节点的日志传输可能有问题需要优先排查网络、监听和归档目录权限。5.2 备库应用状态核查备库侧主要看日志应用是否在追有没有产生 gap。我常用的两条 SQL 如下SELECT NAME, VALUE, UNIT FROM V$DATAGUARD_STATS WHERE NAME LIKE %apply lag% OR NAME LIKE %transport lag%; SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;正常情况下apply lag应该在秒级或分钟级如果持续增长说明备库在 IO 或归档应用上卡住了。V$ARCHIVE_GAP如果有返回结果说明主备之间存在日志缺口需要尽快处理。这个视图在 11g 里非常有用是判断 DG 健康度的核心指标。5.3 角色切换演练与回退建议搭建完成后建议在测试窗口内做一次 switchover 演练验证备库能否真正接管。虽然说搭建阶段不一定强制做但既然花了大精力部署 DG不演练一次总归不放心。switchover 的命令是ALTER DATABASE COMMIT TO SWITCHOVER TO STANDBY和ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY这里不展开完整过程只说一个核心建议演练前务必确认主备两侧STATUS都已从TO STANDBY或TO PRIMARY变成正常并且全程保留完整的告警日志。如果演练后要回退到原主库同样要再执行一次 switchover 切回来整个过程对停机时间要求并不高但操作顺序绝对不能乱。6. 常见问题排查实战几类坑与解法6.1 ORA-16191密码文件不匹配这个错误几乎每个 DG 搭建者都会遇到报错信息是ORA-16191: Primary log archival and data destination standby database is not in ARCHIVELOG mode但实际上备库归档模式往往没问题真正原因是主备库密码文件不一致。解决办法很简单把主库任意节点的orapwsid文件复制到备库重命名为orapworcl_stb然后重启备库。注意如果主库 RAC 各节点密码文件不一致建议先统一主库节点间密码文件再同步到备库避免后续出现“有的节点能传、有的节点传不了”的诡异现象。6.2 ORA-16047 / ORA-16009配置与网络问题ORA-16047: DGID mismatch的本质是主备库DB_UNIQUE_NAME与LOG_ARCHIVE_CONFIG中声明的名称不匹配。排查思路很明确核对主备库的DB_UNIQUE_NAME确认LOG_ARCHIVE_CONFIGDG_CONFIG(主库名,备库名)两边完全一致两边的顺序不同没关系但名字必须对得上。ORA-16009则是典型的网络或监听问题。遇到先tnsping备库 service name再检查监听状态最后确认防火墙策略。有时候主库两个节点里只有一个节点能 ping 通备库这个问题尤其隐蔽往往是节点的 hosts 文件里没有写备库的解析记录导致。6.3 日志 Gap 排查与手工补归档日志 gap 在 DG 运行中是必须高度重视的警报。当V$ARCHIVE_GAP有数据时MRP 进程会停下来等待缺失的日志应用延迟会急剧增大。标准处理流程是先查出缺哪些 thread 的哪些 sequence再到主库找到对应的归档日志手动拷贝到备库然后注册SQL ALTER DATABASE REGISTER OR REPLACE LOGFILE /u01/arch/orcl_stb/1_3456_987654321.arc; SQL ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;注册完成后 MRP 会继续应用之后观察V$ARCHIVE_GAP是否已经清空。如果 gap 频繁出现建议检查主库归档目录的清理策略防止归档被过早删除导致无法补传。6.4 RAC 多实例归档路径与权限问题最后一个常见问题是 RAC 环境的归档路径和权限。主库多个节点各自产生归档如果归档目录不是共享位置RMAN 在某个节点执行备份时可能读不到另一个节点产生的归档导致备份不完整进而影响备库恢复。解决办法是让 RAC 的归档写到共享存储比如 ASM 磁盘组或者 NFS 共享目录这样任意节点都能访问全部归档。备库恢复时也要确保对备份目录有读取权限如果提示权限拒绝先看 oracle 用户是否有对应目录的访问权。最后一个实操体会整套流程走下来我的体会是 RAC 到单实例 DG 的难点不在命令而在对“多 thread 日志同步”这件事的理解。只要抓住三个本质每个节点的日志都要能送出去备库要为每个 thread 准备 SRL路径转换要彻底一致大概率一次就能跑通。最后再分享一个小技巧搭建完成后把主备两侧的告警日志关键节点都截个图存档后续无论是排查性能问题还是做季度巡检都能省下大量回溯时间。
返回列表