
凌晨三点被运维电话吵醒的滋味估计每位DBA都懂。那次是生产单机库宕机两个小时后业务才恢复而旁边另一套跑在Oracle RAC上的核心交易库节点故障后二十几秒应用就自动切走了。从那时候起我就认死一个理企业级数据库要做高可用不能指望硬件不出错得靠架构本身把故障消化掉。在Oracle Linux 8.4上部署Oracle RAC就是这套思路最典型、也最成熟的落地方式——它同时解决两件事数据库节点挂了业务不受影响以及多个节点分摊请求压力实现负载均衡。这篇文章不是贴一遍安装截图就完事而是把我实际部署中走过的完整链路梳理出来版本怎么选、网络怎么规划、存储和ASM磁盘组怎么设计、GI集群层安装时有哪些坑、SCAN监听怎么让负载均衡真正生效、上线前故障演练该怎么做。适合正在做数据库架构升级的DBA、系统架构师以及想把核心业务从单节点赌运气模式迁到多节点分担风险模式的团队。1. 单节点与RAC的本质差异高可用和负载均衡究竟是谁在干活很多第一次接触RAC的人会把它当成双机热备这是个非常危险的误解。RAC不是一台机器闲置等故障而是多个节点同时对外提供服务任何时刻所有节点都在跑业务。能做到这一点靠的是三拨角色各司其职Clusterware负责节点健康和资源拉起Oracle RAC的GES全局排队服务和Cache Fusion机制负责多节点间的数据一致性SCAN监听器和客户端负载均衡配置负责把新连接均匀分散到各个实例。1.1 RAC解决了什么没解决什么高可用性这块RAC解决的是实例级故障。比如node1突然断电、操作系统卡死、实例因为ORA-600异常退出Clusterware检测到之后会把数据库实例、VIP地址、监听器这些资源重新调度到存活节点应用侧只要配了合理的连接串就能在几十秒内恢复。但RAC解决不了双节点同时挂这种极端场景也解决不了数据被误删的故障。所以生产环境通常还会搭配Data Guard做容灾、RMAN做备份形成RAC解决高可用、DG解决容灾、备份解决误操作的三层防线。这块在选型初期就得想清楚别等项目上线后才发现少了一层。我有一次就被问过一个经典问题RAC部署完了机房断电是不是一点没事答案是如果整机房断电两个节点都没了业务照样断。RAC能保证的是单个节点故障、单个网卡故障、单块共享存储路径故障而不是置整个数据中心于死地。这个边界从一开始就要和业务方讲明白。1.2 Oracle Linux 8.4上的版本搭配思路Oracle Linux和Oracle数据库同出自Oracle天然兼容性好很多内核参数、驱动适配都比其他系统省心。8.4这个版本不算老也不算新搭配生产环境最稳妥的是Oracle Database 19c Grid Infrastructure 19cGA时间足够长补丁体系成熟官方支持文档也最全。在Oracle Linux 8.4上装19c有个小前提内核建议用UEKUnbreakable Enterprise Kernel对Oracle的I/O路径和ASM适配更好。如果系统默认是RHCK内核也不是不能用只是需要额外确认一些模块参数我建议直接选UEK省事。版本对应关系大致如下组件推荐版本说明操作系统Oracle Linux 8.4UEK内核官方支持列表内可直接配yum源装依赖Grid Infrastructure19c补丁建议到19.16以上支持OL8ASM与集群件功能稳定Oracle Database19c与GI同版本使用起来最顺共享存储FC/iSCSI multipathASM需要看到同一路径不推荐NFS跑OCR注意数据库和GI的版本号必须一致否则注册资源时会报错。这是我见过的最多的低级翻车点。1.3 别把负载均衡理解成性能翻倍多节点同时读同一份数据时Cache Fusion会把数据块从一个实例的SGA通过私网传到另一个实例热点表上的访问会在节点之间来回搬数据这部分开销是不低的。所以RAC的负载均衡更准确的说法是连接和事务在多个节点上分摊而不是让单条SQL跑得快一倍。实际生产里性能提升主要来自三类场景一是读写混合业务把读请求分散到多节点二是按模块拆分服务一部分应用固定在节点1一部分固定在节点2减少跨节点块传输三是故障切换时不需要等待冷备启动直接由存活节点接管。如果你预期RAC能让原本就要跑10秒的报表变成5秒那大概率会失望。RAC对单条慢SQL没多少帮助它擅长的是释放横向扩展能力、提高整体吞吐和可用性。2. 环境规划比安装命令重要十倍网络、DNS与存储的排兵布阵接触过RAC的人都会有个体会真正耗时间的不是点鼠标装软件而是装之前的环境规划。我接手过一套别人搭到一半的RAC问题全出在主机名解析和存储路径上——SCAN解析不出来客户端连不上ASM看不到全量磁盘OCR装到一半就失败。这些坑如果提前规划其实都能避开。2.1 两套网络怎么划分RAC至少需要两套网络public网络用于业务流量private网络用于节点间心跳和Cache Fusion数据块传输。业务网要求不高带宽够即可私网才是关键它承载着实例间的块传输延迟稍微高一点性能就能感觉出来。生产上通常还会用两块物理网卡做bond或team把私网做成冗余链路。如果只给每个节点配一块网卡负责心跳一旦网卡故障整个集群会立刻脑裂两个节点同时抢占资源后果非常严重。这个钱不能省我见过的最小化方案也是业务双网卡bond 心跳双网卡bond而不是业务一块、心跳一块。私网网段建议和业务网段完全分开IP地址不要放在同一个广播域。心跳协议用的是UDP组播如果中间有交换机记得提前确认组播没有做隔离限制否则节点会发现不了对方导致反复踢出集群。2.2 主机名、DNS与SCAN解析SCANSingle Client Access Name是RAC实现负载均衡的入口。客户端访问数据库时只连接SCAN地址而不是具体某个节点IPSCAN背后的DNS轮询会把请求分发到不同节点的VIP监听器。这样节点故障时客户端无需修改连接串SCAN自动把流量导到存活节点。所以在部署前DNS必须提前配好。以双节点的集群为例大致解析关系node1.example.com 解析到业务IP 192.168.10.11node2.example.com 解析到业务IP 192.168.10.12scan-cluster.example.com 至少要解析出三个地址分别映射到三个SCAN VIP 192.168.10.21/22/23这里强调一下SCAN域名最少配三个解析地址这样才可能利用多个SCAN监听器实现负载均衡和容错。如果只配一个IPSCAN监听全部集中在一个地址上不仅失去负载均衡效果这个IP一旦不可用整个集群对外服务就断了。如果你用的不是DNS而是直接写/etc/hosts那RAC会走GNS或者要求固定IP。我更推荐正经的DNS方案因为/etc/hosts做不了真正意义上的SCAN轮询排查问题也容易绕进去。2.3 共享存储与人机接口RAC是高可用架构数据文件必须放在所有节点都能访问到的共享存储上ASM是Oracle推荐的文件管理方案。存储协议常规选FC或iSCSI两者的共同点是必须以块设备形式呈现给操作系统。OL8.4上建议启用Device Mapper Multipath让多个存储路径合并成一个设备避免路径切换时文件系统错乱。我在测试环境里用的是iSCSI两条网络路径做multipath节点上看到的是/dev/mapper/asm_data1这类设备。这里有个很实用的习惯不要直接用/dev/sdb、/dev/sdc这种设备名因为重启后设备名可能变化ASM就会找不到磁盘。正确的做法是安装device-mapper-multipath并用multipath -ll确认wwid在 /etc/multipath.conf 里给每块盘起别名比如asm_disk_data通过udev规则把设备权限赋予grid用户让ASM能读取用oracleasm configure之后oracleasm scandisks验证磁盘可见ASM对磁盘的权限检查非常严格节点1能看到盘、节点2看不到盘这种情况太常见了。排查顺序永远是共享存储是否同时映射给所有节点 → multipath是否在所有节点都识别成功 → udev规则是否给grid用户授权 → ASM磁盘组能否同时在这几个盘上轮询。2.4 时间同步与操作系统账号RAC的节点间通信极其依赖时间一致性。建议用chronyd和NTP服务器同步所有节点的时间偏差保持在几秒钟之内。时间不一致最直接的后果是集群心跳判断混乱一个节点可能会把另一个节点当成故障节点踢出去。操作系统账号也很容易被忽略。grid和oracle两个用户必须在所有节点上UID一致目录/u01的所有权归grid或oracle/home下用户环境变量保持一致。否则GI安装脚本执行到一半经常出现A节点能跑命令、B节点权限不对的尴尬情况。3. GI集群层安装的关键路径从安装前校验到root.sh后面Grid Infrastructure是整个RAC的地基。地基没打好后面建库、加资源全是白搭。这一层安装的完整链路是环境检查 → 运行安装程序 → 在所有节点执行root.sh → 集群资源自动注册 → ASM磁盘组创建 → 检查集群状态。3.1 安装前校验别省直接决定成功率GI安装包解压后第一步不是急着下一步而是跑一遍安装前置校验。Graphical安装界面里自带CVU校验会检查系统包、内核参数、进程数限制、存储路径、网络互信等几十项。如果某台机器上少装了libaio、libnsl这类依赖包校验阶段就会直接标红比装到一半再报错友好太多。一个容易被忽略的项是SSH互信。安装程序通常会让用root或grid用户配置Oracle Linux节点的SSH等价性建议用非交互的key认证来配置不要用明文密码自动托管。配置完成后再手动跑一下每个节点间的ssh测试确保免密登录畅通。互信配置失败时分布式脚本执行必然中断这是排障中最常见的开头。3.2 root.sh分节点执行时看什么安装程序把二进制文件已经拷贝到GI_HOME之后会要求在所有节点上依次执行root脚本。这步非常关键我见过有人在两个节点同时执行root.sh结果导致集群配置互相覆盖最后只能清盘重来。正确做法是一个节点完全执行完毕、集群资源正常注册后再到第二个节点执行。执行root.sh过程中屏幕上会输出大段CRS注册信息。其中最值得关注的内容包括Adding daemon to crontab和ohasd启动是否成功Oracle Cluster RegistryOCR是否初始化完成Voting Disk是否成功挂载执行完之后不要直接去建库先用下面的命令看看集群服务状态crsctl check cluster -all crsctl status resource -t正常输出里应该看到ora.cssd、ora.diskmon等资源处于ONLINE状态所有节点都显示ONLINE。如果某个节点显示OFFLINE先看/u01/app/grid/diag下的日志别急着重启先把原因找清楚。3.3 ASM磁盘组的规划OCR、DATA、FRA各司其职集群件装完后下一步就是建ASM磁盘组。磁盘组规划直接影响后续的存储利用率和恢复能力我一般这么分磁盘组冗余策略最小大小用途OCRNormal约1GB双份存放OCR和Voting FileDATANormal按数据量估算数据文件、控制文件、日志文件FRANormal建议数据量的1.5~2倍快速恢复区、归档日志、RMAN备份Oracle的Normal冗余并不是双副本那么宽松它要求至少两个故障域通常是两块不同盘写入时自动复制两份。做数据库规划时我习惯把DATA和FRA分到不同的物理盘组上避免底层存储同时损坏。创建磁盘组的命令大致是asmcmd lsdg # 以grid用户执行 sqlplus / as sysasm CREATE DISKGROUP DATA NORMAL REDUNDANCY DISK /dev/mapper/asm_disk1, /dev/mapper/asm_disk2 ATTRIBUTE compatible.asm19.0.0, DG_DISK_POOLSDATA;建完以后用asmcmd lsdg确认所有节点都能看到新磁盘组。如果某个节点执行asmcmd报告磁盘组不存在大多是udev权限或multipath别名不一致返回去查共享存储配置。这里顺带回应一下很多DBA问过的如何清除不用的磁盘组。很多人直接把磁盘组drop掉结果数据库实例起不来原因很常见该磁盘组里还躺着某个数据库的数据文件。正确路径是先确认谁在用再清理# 1. 查看哪些数据库实例挂载了该磁盘组 srvctl status database -d orcl sqlplus / as sysdba SELECT name FROM v$datafile WHERE name LIKE OLD_DG%; # 2. 先将数据文件迁移到其他磁盘组或删除相关数据库服务 ALTER DATABASE MOVE DATAFILE OLD_DG/ORCL/DATAFILE/users.256.1234 TO DATA; # 3. 确认无任何文件使用后再在ASM层面做Drop DROP DISKGROUP OLD_DG INCLUDING CONTENTS;实际上生产环境操作顺序更严格先停应用、做备份、迁移、再删除。但思路不变任何ASM层面的操作都必须先在数据库层确认没有依赖。4. 建库与负载均衡生效的配置逻辑关键在服务和连接串集群层就绪后用DBCA创建RAC数据库过程不复杂。真正决定高可用和负载均衡体验的是建库之后的服务配置和客户端连接方式。很多人建库完成后直接用sys去连节点IP测了半天觉得负载均衡没生效其实是连接方式用得不对。4.1 建库时把服务和TAF一并规划好DBCA创建数据库时会要求指定实例在哪些节点上运行。默认两个节点都是orcl1、orcl2。有个不容易注意到的地方是服务配置Oracle强烈建议为具体业务创建一个Service而不是让客户端直接连数据库名。Service是Oracle实现故障转移和负载均衡的载体。srvctl add service -d orcl -s order_srv \ -r orcl1,orcl2 \ -a orcl2,orcl1 \ -P basic \ -e SELECT \ -m basic \ -w 5这条命令的含义是order_srv这个服务在两实例上都运行任何一边故障时自动failover到另一边采用basic模式连接建立时才知道当前可用实例5秒内完成服务切换。服务建好后再执行srvctl start service -d orcl -s order_srv最后使用这个服务名访问数据库。4.2 连接串写对负载均衡才不是摆设客户端连接RAC最标准的方式是走SCAN地址。比如应用服务器的tnsnames.oraORDER_DB (DESCRIPTION (ADDRESS_LIST (LOAD_BALANCE ON) (ADDRESS (PROTOCOL TCP)(HOST scan-cluster.example.com)(PORT 1521)) ) (CONNECT_DATA (SERVICE_NAME order_srv.example.com) ) )这里有两个细节决定了负载均衡是否真正生效LOAD_BALANCEON让客户端从DNS解析出多个SCAN地址后随机挑选避免所有连接压到同一个地址使用SCAN域名而不是node1/node2的IP。一旦节点发生failoverSCAN会动态把新连接导到存活节点应用不用改配置我实测时的验证方式是写个循环连接脚本不断执行sqlplus -S appuser/apppwdORDER_DB EOF select instance_name from v$instance; EOF正常情况下会看到orcl1和orcl2交替出现说明流量已经分散。如果始终只连到一个实例优先排查DNS是否解析出多个SCAN地址而不是怀疑RAC本身没配好。4.3 应用层负载切割比数据库层配置更有效RAC自带的负载均衡只能做到新连接轮流分配如果你的业务是长连接、大事务、频繁更新热点表那么即使连接平均分配到两个节点实际运行时也可能出现大量Cache Fusion传输。我通常会建议应用架构再往前走一步把不同模块的Service固定到不同节点。比如订单服务优先跑在节点1报表服务优先跑在节点2用服务偏好-p参数或srvctl modify service控制。这样大部分数据块访问在本地完成节点间传输大幅减少。很多RAC性能调优案例最终落点都在这个应用切分上而不是一味增加节点。4.4 建库后的健康检查清单数据库建完我习惯按下面列表过一遍全部通过才敢交给业务方用crsctl status resource -t确认数据库和监听全部ONLINE用srvctl status database -d orcl确认所有实例打开用lsnrctl services检查各节点的监听是否注册了服务用srvctl config scan -d确认SCAN监听器分布在哪些VIP上如果上述任一项不通过不要急着优化先回到日志看报错。RAC部署最大的教训就是基础状态不健康时一切性能优化都是空中楼阁。5. 上线前必须做的故障演练高可用不是配置出来的是验证出来的RAC的高可用能力不是安装完成那一刻就算达成了而是故障发生时系统能不能按预期恢复。我见过太多项目装完RAC就以为自己高可用了结果第一次做故障演练就发现客户端等了十分钟才恢复连接。所以上线前请务必设计几组故障场景把整个切换过程走一遍。5.1 节点级故障拔网线比重启更刺激节点级故障演练有两种做法温和的是在node1上执行crsctl stop crs激烈的是直接模拟掉电或断开所有网络路径。我建议都做先温后冷。执行完crsctl stop crs后node1上的实例、监听、VIP全部漂移到node2。客户端如果配置的是SCAN地址新连接会直接打到node2已建立的连接能否自动续接取决于是否配置了TAF或Application Continuity。这里有个容易被忽视的验证点应用连接的自动恢复时间。我用含TAF的JDBC连接池测试从节点故障到连接重新可用大约5到15秒。如果你的应用连接池不自动重连那RAC再快也没用恢复时间取决于应用侧的超时检测间隔。5.2 实例级故障模拟shutdown abort比重启节点更精细的是只杀实例sqlplus -S / as sysdba EOF shutdown abort; EOF实例abort后Clusterware会在几秒内检测到异常然后自动将实例拉起。用srvctl status database -d orcl观察状态变化正常情况下状态会从INTERMEDIATE短暂切换到ONLINE。服务端配置了TAF的应用正在执行的查询可能会报 ORA-24561然后自动重连到另一个实例继续事务。如果发现实例abort后长期不自动恢复多半是集群资源设置有误例如srvctl config database -d orcl -a的PRIM和PRES参数没写全。演练的价值就在于把这些隐藏配置错误提前暴露出来。5.3 监听故障验证VIP漂移监听器故障演练是最容易被忽略的一环。因为监听通常不是性能瓶颈很多人觉得它不会出问题。但实际生产里内存泄漏、监听日志满、网络配置变更都可能导致监听挂掉。验证思路是找到node1上的监听进程kill掉立即观察crsctl status resource ora.LISTENER_SCAN1.lsnr的状态变化确认VIP是否从node1漂移到node2SCAN监听是否重新注册用客户端连接串反复重连看是否快速恢复演练结果会直接告诉你SCAN地址和VIP的漂移逻辑是否真的像文档描述的那样工作。5.4 把演练结果固化为运维SOP每次故障演练都会发现一些意外情况。比如我在一次演练中看到虽然数据库实例快速切换但应用连接池里的空闲连接要等到TCP超时才能被淘汰导致瞬间出现大量连接错误。后来在应用侧调整了Connection Timeout和Validate Connection参数才把恢复时间压到秒级。所以建议把每次演练的时间戳、恢复时长、异常列表记录成表格建立故障切换SOP后续每次变更都回归一遍。6. 运维中那些冷门的坑与值得抄作业的解法RAC跑起来之后工作并没有结束。日常运维里反而有一堆常年困扰DBA的细节问题看着不起眼碰上就头疼。我把最近被问到最多的几个集中写一下。6.1 sqlplus登录缓慢的背后原因有段时间用户反馈sqlplus连接RAC特别慢能明显卡住几秒才出SQL提示符。排查时先翻$ORACLE_HOME/network/admin/sqlnet.ora常见原因之一是启用了大量诊断追踪每次登录都要写日志文件另一个是SCAN域名解析慢DNS服务器性能差或反向解析失败。我当时的排查链路是time tnsping order_db # 如果tnsping快而sqlplus慢说明问题出在登录认证或权限 # 如果tnsping也慢直接排查DNS和SCAN最后定位到的原因很无语listener.ora里配置了多个静态监听地址每次客户端连接要依次尝试所有IP其中一个IP已不可达导致每次都等到TCP超时。清理掉废弃地址后问题立刻消失。6.2 ASM磁盘组删除的完整安全路径热搜词里oracle rac crs清除不用的磁盘组基本就是运维里常见的感觉磁盘组没用了想删的场景。我再强调一次安全顺序确认没有数据库文件依赖查v$datafile、v$logfile、v$controlfile、RMAN备份集路径迁移依赖文件到其他磁盘组或者删除引用该磁盘组的数据库通过srvctl remove database或ALTER DATABASE MOVE DATAFILE清理引用确认ASM中资源不再占用后再执行DROP DISKGROUP ... INCLUDING CONTENTS我见过有人跳过前两步直接在ASM里删磁盘组结果数据库启动时找不到控制文件整个库变为不可用状态最后只能靠重新创建控制文件来恢复。别为了一时省事把磁盘清理做成灾难演练。6.3 数据库只能使用40个核心的资源限制问题有人反映RAC节点上明明有64核但数据库实例运行时只用了40核。这个不是Oracle License限制而是实例参数cpu_count被显式限制了。检查方法SHOW PARAMETER cpu_count; SHOW PARAMETER parallel_min_servers; SHOW PARAMETER parallel_max_servers;RAC环境下每个节点实例的资源限制是独立的所以cpu_count40意味着单个实例最多用40核两个节点加起来理论上可用80核。但别单纯地认为把参数调大就万事大吉还要检查sga_target、pga_aggregate_target是否配套否则CPU多了内存不足性能反而更差。6.4 FRA磁盘组空间管理和备份策略RMAN备份和归档日志默认写到FRA如果FRA空间规划太小数据库会报ORA-19815归档日志直接停住。我遇到过不止一次根源是FRA规划时只按数据量的0.5倍估算没考虑归档增长速度。建议把DB_RECOVERY_FILE_DEST_SIZE设置为数据量的1.5到2倍并定期用RMAN DELETE EXPIRED BACKUP和归档备份策略清理过期文件。同时在日常巡检里加入一条检查SELECT name, total_mb, free_mb, (total_mb-free_mb)/total_mb*100 AS used_pct FROM v$asm_diskgroup_stat;当FRA使用率超过85%时就要触发告警并安排备份清理别等到数据库性能下降才开始看。6.5 小技巧把CRS日志作为第一排查入口很多RAC问题的根因不在数据库alert日志里而在GI日志目录例如$GI_HOME/log/hostname/下的alerthostname.log。集群资源的启停、节点驱逐原因、网络心跳状态全都记录在这里。遇到RAC相关异常我先翻CRS的alert日志再去看数据库的alert日志顺序反了会浪费大量时间。比如有一次节点被莫名驱逐查CRS日志发现是私网网卡间歇性丢包导致心跳超时。而数据库alert日志只记录了实例终止的结果看不出原因。只有CRS日志能还原完整的事故链条。RAC这套架构部署起来不算难难的是每一步都想明白为什么。从网络规划到存储设计从集群件安装到服务配置环环相扣。我的建议是别急着上线先在测试环境按上面的章节完整操作一遍把节点故障、监听故障、磁盘清理这些场景全部演练熟了再切入生产。等真正出问题时你心里已经有了一条清晰的排查路径那才是RAC带来的最大安全感。