Oracle Linux 8.4上搭建Oracle RAC集群:高可用与负载均衡实战指南 2020年之后我接手过不少核心业务系统的数据库改造无论客户底子是新上的私有云还是老机房里跑了很多年的集中式架构只要你把“确保数据库高可用”这五个字摆到台面上Oracle RAC一定是那张绕不开的主牌。尤其在Oracle Linux 8.4这套操作系统已经非常成熟的今天RAC从部署到运维的整个链路都比前几年顺滑太多。这篇文章我就结合自己在生产环境里真实搭过的环境把Oracle Linux 8.4上配置Oracle RAC集群这件事从头到尾捋一遍重点讲高可用性和负载均衡这两个目标是怎么落到具体配置上的也算给准备入坑的朋友一份现成的参照。我会尽量说人话把每一步为什么这么做、踩过什么坑、哪些配置一疏忽就出事故都讲清楚。内容按项目落地顺序来走你可以直接当作一份操作前自查清单也可以对照你正在搭的环境逐步核实。1. 为什么企业级数据库要选RAC而不是其他方案1.1 RAC的核心价值不止是故障切换很多刚接触高可用的人会把RAC和Data Guard或者双机热备混在一起其实这是两码事。RAC是Oracle自家的多实例共享存储架构同一份数据文件被多个节点的数据库实例同时打开任何一个实例挂了应用连接会自动切到幸存的节点上数据库服务不停、数据不丢。而Data Guard本质是一套日志复制的备库机制角色切换的过程通常需要几十秒到几分钟应用层往往要改连接串甚至重启中间件。RAC最打动人的地方在于它把高可用和性能横向扩展一起解决了。比如你有两个节点每个节点4路CPU 256GB内存平时两个节点都在干活各自承担一半连接而不是像主备架构那样主节点干活、备节点在旁边干等。对于企业级OLTP业务来说这种“不浪费一台机器”的设计本身就是最大的价值。还有一点容易被忽略RAC天然提供了应用层透明的连接管理。配上SCAN监听器和Service之后客户端只要知道一个固定域名连接请求会在这个域名的所有监听之间自动分发哪台机器参与服务、哪些节点被踢出了集群应用什么都不用感知。1.2 高可用系统选型时要权衡什么很多客户一开始就问“RAC、LVS、中间件集群我到底该上哪一个”。这里我想多讲两句。LVS是网络层的负载均衡方案它解决的是流量分发问题从不关心Oracle实例是不是活着。中间件集群比如WebLogic、Tomcat的集群负责处理应用请求的可用性但数据库一旦瘫痪应用层再高可用也是空中楼阁。真正合理的组合拳是网络层有LVS或者F5这类入口设备做流量入口高可用应用层中间件做业务无状态水平扩展数据库层用RAC保证最终数据服务的连续可用和并发吞吐。三层各干各的职责边界清晰。所以如果你问我企业级数据库的高可用我的答案永远是先把数据库这一层的RAC建立在正确的轨道上再谈上层的东西。2. 准备阶段决定成败环境规划与硬件清单2.1 Oracle Linux 8.4上的安装前置条件Oracle Linux 8.4是RHEL8系的操作系统默认自带UEK R7内核兼容性非常好。装Oracle Grid Infrastructure和数据库软件之前有几个硬性条件必须提前满足少一个后面都会卡住。硬件层面最低要求是节点数量不少于两个、每个节点物理内存不少于8GB、共享存储可用空间不低于100GB。这里的“共享存储”指所有节点能同时看到同样的裸盘或LUN通常靠SAN存储或iSCSI模拟出来。操作系统层面需要注意的点包括所有节点的内核参数、系统包、用户配置完全一致主机名与/etc/hosts里的大小写、IP对应关系不能有差异时间同步必须用NTP或者Oracle自带的CHRONYD服务节点间时间差超过几百毫秒就可能被CSS判定为脑裂所有节点防火墙必须放行特定端口或者直接关闭内网防火墙这里我强烈建议你用rsync或者Ansible把所有节点的/etc/hosts、/etc/sysconfig/network-scripts/的文件、以及用户和组定义一次性铺平。手工逐台敲配置是大忌漏一台就等着后面装GI时通信验证失败。2.2 网络IP规划Public、Private、Virtual、SCAN一个都不能少RAC集群的网络设计常常是初次部署者最容易搞混的地方。每个节点需要四类IP地址公网IPPublic IP节点对外提供服务的日常IP承载客户端的连接私网IPPrivate IP节点与节点之间的专用通信地址承载相关心跳与数据块传输虚拟IPVIP节点故障时自动漂移到存活节点的地址客户端如果直连VIP就能实现秒级感知故障SCAN IP整个集群的统一入口域名地址通常配置三个IP解析到同一个SCAN域名以我经常用的两个节点规划为例节点1公网是192.168.10.21私网是10.0.1.21VIP是192.168.10.22节点2公网是192.168.10.31私网是10.0.1.31VIP是192.168.10.32SCAN域名rac-scan.localdomain解析到192.168.10.51、192.168.10.52、192.168.10.53三个地址。这样从客户端看只需要知道一个SCAN域名连接层的高可用和负载均衡基本就有了一半。有很多人在/etc/hosts里简单地把SCAN域名指向一个IP这是不允许的。SCAN IP要么交给DNS解析要么用Oracle的GNS功能让集群自己管理IP。生产环境里我倾向于GNS加DHCP的方式省去了让网络管理员反复跑流程的时间但前提是网络设备支持DHCP保留地址。2.3 共享存储的规划与UDEV规则绑定RAC的架构模型可以简单理解成“多个脑袋共用一副身躯”这份身躯就是所有节点共享的数据库文件。Oracle RAC的高可用性依赖两个底层组件OCR和Voting Disk。前者保存集群配置信息后者负责任务调度节点成员决策。这两个组件以及全部数据文件都必须存放在共享存储上。通过虚拟机模拟或真实SAN环境最直接的做法是给所有节点挂载同一批共享SCSI磁盘。操作系统启动后不同节点看到同一块盘对应的设备路径可能不一样这就需要通过UDEV规则把磁盘的WWID绑定为统一的设备名和权限。给出一个典型的UDEV规则片段# /etc/udev/rules.d/99-oracle-asm.rules KERNELsd*, SUBSYSTEMblock, ENV{ID_SERIAL}36000c2938e6example1, OWNERgrid, GROUPasmadmin, MODE0660规则里的ID_SERIAL重新写成你真实磁盘的序列号。绑定后重启系统或者手动执行udevadm trigger然后检查ls -l /dev/sd*是否正常。这里最常踩的坑是忘记把grid用户加入asmadmin组导致ASM无法读写磁盘。你还需要规划好ASM磁盘组的冗余策略。生产环境里我一般用正常冗余(Normal Redundancy)也就是三块盘或更多组成一个磁盘组每个区保留两份副本这样单块盘丢失不影响数据可用性。如果预算有限外部冗余也不是不行但就放弃了ASM层对数据的安全保护。3. RAC集群安装过程的实操分解3.1 Grid Infrastructure安装与常见坑位环境准备好了下面就是整个项目最耗时的部分安装Oracle Grid Infrastructure。这套软件就是RAC的架子提供了集群件、ASM、监听器、SCAN监听等服务。安装步骤如下先在第一个节点运行runInstaller选择“设置Oracle Grid Infrastructure”再选“配置Oracle Standalone Cluster”选项。GNS建议启用如果前面规划没有使用独立DNS此时就用固定域名和本机解析模式。安装界面里的网络接口eth0对应公网eth1对应私网一定要准确对应错了后面排障非常痛苦。root脚本执行顺序是先全部节点执行root.sh脚本再回头执行rootupgrade.sh如果安装完毕有提示。这是Oracle官方推荐的套路我自己第一次部署因为贪图省事在某个节点提前跑了root.sh结果导致集群注册不全后来花了一晚上重新配置oifcfg才救回来。核心心法跑root脚本时速度再慢也要按顺序来并且一个节点一个节点确认执行成功后再继续下一个。3.2 数据库软件与ASM磁盘组创建GI装完ASM实例会自动运行此时用grid用户登录环境执行asmca可以图形化创建磁盘组。生产库我习惯建三组磁盘DATA组存数据文件、OCR组专门放OCR和Voting Disk、FRA组放归档日志和RMAN备份。数据量不大的话DATA组也可以是外部冗余以节省空间OCR和FRA建议Normal。数据库软件安装比较简单用oracle用户运行runInstaller选择“仅安装数据库软件”语言选英文选择“Oracle Real Application Clusters”安装类型。等待它把软件同步到其他节点时间取决于节点数和后端存储性能一般在十几分钟到半小时。装好软件后用dbca创建数据库并勾选“配置Oracle RAC”。这里有一步非常关键全局数据库名和SID前缀要一致实例名会自动加数字后缀。比如全局库名是oradb那节点1实例就是oradb1节点2就是oradb2。dbca过程中会让你选磁盘组以及是否启用“归档日志模式”生产库一定勾上不然高可用只能算半吊子。3.3 监听器配置与服务注册负载均衡的地基RAC环境的监听器有别于单机环境SCAN监听器由GI自动配置并托管在所有节点上。安装完成后可以通过这个命令检查crsctl status resource -t正常情况下ora.scan1.vip、ora.scan2.vip、ora.scan3.vip这三个资源都会显示ONLINE监听器ora.LISTENER_SCAN1.lsnr等也都处于运行状态。RAC的负载均衡能力首先体现为连接到SCAN域名时Oracle Net会轮流解析SCAN IP的地址自动将新连接请求分散到不同节点的SCAN监听器。但如果你只配置了SCAN却没有配置服务端负载均衡参数那它还只是最基础的DNS轮询层面。服务端要做两件事一是确保每个实例都把本地监听地址注册到SCAN上这个由REMOTE_LISTENER和LOCAL_LISTENER两个初始参数控制二是为每个服务设置连接负载均衡目标。从Oracle 19c开始最常用的做法是在dbca创建完库之后直接用srvctl命令修改服务属性。一个典型的负载均衡服务配置命令srvctl modify service -db oradb -service ORASVC -clbgoal SHORT -lbgoal LOW -preferred oradb1 -available oradb2这里CLBGOAL表示客户端连接池在服务层运行时负载均衡的时间粒度SHORT适合短连接大量出入的场景LBGOAL表示由RAC内部调度器为每个节点连接分配权重LOW表示尽量平衡节点负载同时兼顾性能。4. 高可用和负载均衡的机制是怎么真正落地的4.1 CSS与OCR保障高可用的神经系统所谓的高可用性在RAC内部说到底是一套“心跳检测 仲裁投票”机制。每个节点的CSS进程会定期通过私网网卡向其他节点发送心跳消息同时每个节点对Voting Disk投票。一旦某个节点的私网心跳中断其他节点会发起重新配置流程决定是把失联节点驱逐出集群还是等待它恢复。OCR相当于整个集群的元数据库记录着每个资源的状态、每张配置参数、每个服务的偏好。RAC高可用能这么稳定OCR的高可用起着定海神针的作用。生产环境里OCR放在ASM磁盘组配合ASM的故障组至少有两份副本即使单块盘出了故障也不会丢失配置。实战中让我印象最深的教训是企业级高可用方案一定不能只靠系统层面自愈还要定期备份OCR和Voting Disk。别问我为什么强调这个2021年有客户升级GI版本时把OCR所在磁盘组误格式化了那一刻我比谁都怀念会自动备份的备存储柜。4.2 服务级别的负载均衡与故障切换的配合负载均衡如果只是把连接平均分发到各节点那还是最浅层的玩法。Oracle RAC真正让人舒服的是在“负载均衡”与“高可用”之间形成的联动。我们来拆一个典型场景应用连接池配置了SCAN地址此时一个中型电商系统白天有2000个活跃连接。在没有故障时这2000个连接会分散在节点1和节点2上各承担1000个。节点1上的服务器CPU突然飙升到95%数据库实例运行变得极其缓慢。此时负载均衡策略会将新的连接请求优先分配给节点2并延迟将节点1的服务标记为“不希望接受新任务”。这是数据库层面的自适应负载均衡不由网络设备决定而是由实例的实际性能驱动。另一个场景是节点2计划维护你执行srvctl stop instance -d oradb -i oradb2Oracle会先进行服务优雅关闭待节点2上已有的连接处理完毕后再将后续连接全部指向节点1整个过程应用侧连接不会中断。这种滚动维护能力在关键业务变更时需要频繁使用。4.3 连接池配置中的负载均衡参数如果你在Java应用中使用UCP或WebLogic的连接池有专门面向RAC的负载均衡优化。JDBC侧Oracle 19c及以上的驱动在连接池创建时建议设置oracle.jdbc.fanEnabled属性。FANFast Application Notification是Oracle高可用与负载均衡很关键的桥梁——在数据库实例晋升、宕机、服务切换时RAC会立即向订阅的客户端发送FAN事件连接池收到事件后主动淘汰坏连接、提前预建新连接避免客户端苦等网络超时。配置文件里我习惯这样配data-source-nameracDS/data-source-name connection-factory-classoracle.jdbc.pool.OracleDataSource/connection-factory-class urljdbc:oracle:thin:(DESCRIPTION(LOAD_BALANCEON)(FAILOVERON)(ADDRESS(PROTOCOLTCP)(HOSTrac-scan.localdomain)(PORT1521))(CONNECT_DATA(SERVICE_NAMEORASVC)))/url property nameconnectionPoolCachingEnabledtrue/property property nameconnectionPoolPingInterval1/property property namefanEnabledtrue/propertyURL里的LOAD_BALANCEON表示连接池在每次创建新连接时会从SCAN域名解析出的三个IP中通过等开销算法选择开销最小的一台服务器FAILOVERON则允许在建立新连接时尝试备选监听地址。这两项分别对应了我们常说的负载均衡和故障转移。需要注意的是等开销负载均衡这个概念其实是Oracle Net Services和连接池共同协作的结果它并非意味每秒连接数严格对半分而是算法倾向于把每个新建连接的服务器负载维持在不同节点相近的水平。在连接池、FAN、服务调度三层配合下整个系统的连接分布会越来越接近理论最优。5. 常见故障排查与我的实操经验5.1 节点被驱逐或集群脑裂的处理RAC部署完成后碰到的第一类故障往往是节点宕机、私网拥塞、时间偏差导致的节点驱逐。节点驱逐的直接表现是一个或多个实例突然被关闭随后Oracle自动重启实例。排障的第一条命令永远是这个crsctl status resource -t如果某个节点处于OFFLINE状态再查集群成员表crsctl status css -f这里可以看出CSS表决是否在进行。如果是两个节点之间私网心跳延迟很高多半是私网交换机端口故障或网卡负载。一个实用的小技巧用ethtool和netstat -i持续监控私网接口的错误包和丢弃包RAC大多故障都能在网卡层面提前发现。时间偏差引发的ORA-29701这类资源争夺往往是因为NTP服务未正常启动导致节点时间漂移超过1000毫秒。Oracle Linux 8.4上我一般用chrony而不是老旧的ntpd配置方式如下chronyc sources -v systemctl status chronyd如果时间差持续增大说明上游时间源不可达需要立即修正服务配置。5.2 磁盘设备在重启后丢失的问题共享存储配置一个很隐蔽的坑服务器重启后UDEV规则可能重新执行但ASM磁盘的设备路径会变。有一次我在客户现场把一台新的数据库节点接入了已有的RAC集群由于UDEV规则写错了ID_SERIAL导致新节点启动后一直没有发现OCR所在的ASM磁盘集群直接把新节点踢出去了。处理办法是先确认所有节点都能看到相同序列号的磁盘然后统一应用UDEV规则并刷新设备管理器。一条命令立即查看udevadm info --queryall --name/dev/sdb | grep ID_SERIAL将返回的序列号复制进规则文件后重启udev服务udevadm control --reload-rules udevadm trigger5.3 关于安装和日常维护的几条经验这么多年搭过的RAC环境多了有几个原则我一再给团队强调现在也写在这里供参考。第一节点间所有配置必须一致性包括时间、内核参数、环境变量、目录权限。任何一条不一致排查时长都以小时起步。我最常用的自查手段是写一个循环脚本对集群所有节点执行相同命令然后对比输出比如sar、df、free、uname以及crsctl stat res的输出。第二高可用方案中要留出足够的“恢复窗口”。RAC虽然有自动重派功能但它不会帮你解决冗余存储损坏和备份失效的问题。ASM磁盘组、OCR自动备份、归档日志备份这三件事必须纳入日常巡检。第三使用SCAN域名时如果企业内部DNS支持配置好轮询A记录后务必检查SCAN解析时间不能让SCAN解析指向一个已经失效的IP。FAN事件和连接池之间如果没有配合好应用报错可能要比手动切换多十几分钟。第四负载均衡不是一劳永逸的功能需要你定期观察每个节点的AWR报告。如果两个节点实例负载差异较大先别急着调整LBGOAL可能是某条业务SQL存在热块冲突那属于SQL调优的范畴了。还有一点也是我个人很感慨的一点RAC环境的高可用性说到底是靠运维纪律支撑的。软件本身的自愈能力再强也抵不过你几个月不做一次恢复演练。每次新上一套RAC我都会在项目交付前安排一次拔卡测试把其中一个节点的私网线直接拔掉观察整个集群在无人干预的情况下能否自动恢复。这才是检验高可用最真实的方式。