1. 项目概述
1.1 这个项目解决什么问题
先直接说结论:Oracle RAC集群解决的是企业级数据库的单点故障和性能天花板问题。单台数据库服务器无论配置堆到多高,都有两个绕不开的瓶颈,一是硬件故障导致业务整体中断,二是最大连接数、并发处理能力受限于单机资源上限。Oracle RAC通过让多台服务器(节点)同时访问同一份数据库数据,实现了任意一台节点宕机不影响整体服务,同时把多台服务器的CPU、内存、IO能力汇聚起来对外提供服务,这就是标题里“高可用性”和“负载均衡”两个词的底层含义。
我所在的团队去年初接手了一套核心业务系统,数据库端原来跑在单实例Oracle 19c上,服务器规格是两台物理机做主备(就是常说的Active-Standby架构)。这种架构存在一个很致命的问题:主库故障时,虽然备用库可以通过Data Guard切换接管,但切换过程通常需要几分钟甚至更长时间,期间业务完全不可用。对于银行核心交易、电商订单、在线支付这类高并发业务来说,几分钟的中断就意味着重大事故。经过架构评估,我们最终决定在Oracle Linux 8.4上构建一套双节点Oracle RAC集群,跑的是Oracle 19c(19.16以上版本)。
这篇文章面向的读者是那些有一定数据库基础、但没实际装过RAC的DBA和系统运维人员。刚开始接触RAC的人最容易被一堆概念劝退:SCAN、VIP、OCR、Voting Disk、ASM、心跳网络……我会从为什么需要这些组件讲起,把整个搭建过程拆开揉碎,让你不仅知道怎么操作,更明白每一步背后的原理。整个项目从环境准备到数据库创建完成,我们团队大概用了6个工作日,其中踩了不少坑,都会在文中逐一说明。
1.2 为什么选择Oracle Linux 8.4作为基础平台
Oracle的数据库产品运行在自己家的Linux发行版上,兼容性和稳定性自然是最优的。这个判断不是玄学,而是有实际工程依据的。Oracle Linux 8.4的Kernel版本是4.18.0-305,Oracle官方对这套内核和glibc组合做了大量数据库适配测试。特别是从Oracle Linux 8开始,系统内置了UEK(Unbreakable Enterprise Kernel)7,这个内核版本对Oracle RAC所需的异步IO、资源调度、内存管理特性支持得比较完善。
可能有人会问,CentOS、RedHat不也行吗?确实可以,但Oracle Linux有个非常实用的优势——它提供了Ksplice在线内核补丁技术,数据库集群在运行期间可以在不重启节点的情况下应用内核安全补丁。RAC集群如果某个节点需要重启做内核更新,整个集群的计算能力会临时降级,如果期间另一台节点也出问题,那就只能干瞪眼了。Ksplice这种不用重启就能打补丁的特性,在核心生产环境中价值巨大。
另外,Oracle Linux 8.4的安装镜像里直接集成了oraclelinux-release-el8仓库,通过yum就能很轻松装上RAC部署所需的全部依赖包,不用像CentOS那样折腾各种第三方源。从我们实际部署的体验来看,Oracle Linux 8.4的环境准备阶段至少节省了半天时间。
2. RAC核心概念与架构设计拆解
2.1 RAC的底层运作机制
RAC(Real Application Clusters)的运作方式用一句话概括:多个无共享(Shared Nothing)的数据库实例,通过高速私有网络互连,共同访问同一份存储在共享存储上的数据库文件。这里的“实例”是内存结构和后台进程的集合,每台服务器上跑一个实例,但所有实例看到的数据文件完全相同。
RAC之所以能让多个实例安全地操作同一份数据,核心机制是Cache Fusion(缓存融合)。当节点A需要读取某个数据块,而该数据块的修改版本正缓存在节点B的SGA中时,节点A不会直接去磁盘读旧版本,而是通过私有网络向节点B发起请求,由节点B把最新的数据块直接传输给节点A。这个过程走的是内存到内存的传输,速度比磁盘IO快几个数量级。
Cache Fusion的协调工作由两个核心组件完成:GCS(Global Cache Service,全局缓存服务)和GES(Global Enqueue Service,全局队列服务)。GCS负责跟踪每个数据块在哪个节点上有缓存、锁的持有状态;GES管理各种排队机制(Enqueue),比如行锁、表锁在不同实例间的协调。这两套服务都运行在每个实例的LMS(Lock Manager Server)进程里,进程数可以通过参数gcs_server_processes配置。
集群还需要一个大脑来协调各节点的状态和资源归属,这就是管理软件Oracle Grid Infrastructure(GI),其中核心组件叫Clusterware(集群件)。Clusterware负责维护集群成员关系(通过心跳机制)、管理VIP、SCAN监听器、ASM实例等集群资源的启停和故障转移。所有集群资源的状态,通过OCR(Oracle Cluster Registry)和Voting Disk两个关键组件来保存和仲裁。OCR记录集群资源的配置信息(相当于集群的注册表),Voting Disk则用于节点间选举仲裁(解决脑裂问题)。
2.2 为什么需要这么多"专用IP":SCAN、VIP和心跳网络
刚开始接触RAC的人,最容易被一长串IP地址搞晕。一个典型的双节点RAC集群,至少需要以下网络地址:
- Public IP:每个节点的公有IP,用于对外提供数据库服务。
- VIP(Virtual IP):每个节点一个虚拟IP,随节点漂移。客户端连接VIP,当节点故障时,VIP自动漂移到存活节点,客户端连接不会断开,这是实现快速连接故障转移(Fast Connection Failover)的基础。
- SCAN IP(Single Client Access Name):整个集群一个域名,对应1到3个IP地址。客户端只需配置SCAN域名,无需关心具体连接哪个节点。SCAN监听器会自动把连接请求转发到负载最低的实例。
- Private IP:节点间的私有IP,用于Cache Fusion和心跳通信。这部分流量很大,建议使用万兆网卡或InfiniBand。
这里要说清楚一个常见误解:既然客户端可以用VIP连接,为什么还要SCAN?SCAN的价值在于连接管理的透明化。传统多节点数据库,客户端需要配置多个IP做负载均衡,一旦节点增减,客户端配置全要改。有了SCAN之后,客户端只需要固定一个域名,后端节点怎么变化,客户端完全无感知。SCAN IP的分配由Grid Infrastructure内部的GNS(Grid Naming Service)管理,生产环境建议用DNS服务器的A记录来做SCAN的解析,这样最稳定。
心跳网络的设计直接决定了集群的故障检测能力。Clusterware通过私有网络每秒钟发送一次心跳包,默认在misscount(丢失心跳次数)达到阈值后触发重新配置。心跳网络必须用直连的独立网段,绝对不能跟业务网络共用 VLAN——我们曾经踩过一次坑,因为网络工程师在交换机上做了VLAN Trunk,广播风暴直接导致两个节点同时误判对方故障,触发了脑裂,这是整个项目中最惊险的一次经历。
2.3 共享存储与ASM的协同工作方式
RAC的底层依赖共享存储,也就是说,所有数据文件、控制文件、在线重做日志必须存放在所有节点都能同时访问到的存储设备上。生产环境优先选择SAN存储(光纤通道、iSCSI)或NFS(网络文件系统)。为了屏蔽不同存储设备的差异,并为数据库提供统一的存储管理能力,Oracle引入了ASM(Automatic Storage Management,自动存储管理)。
ASM本质上是一个内嵌在GI里的轻量级文件系统和卷管理器。它把多块物理磁盘组合成一个磁盘组(Disk Group),数据文件在磁盘组内自动分布(条带化),并自动维护冗余。ASM的条带化机制很有意思,它分为粗粒度(Coarse Striping)和细粒度(Fine Striping)两种。粗粒度条带宽度1MB,适合数据文件;细粒度128KB,适合控制文件和在线日志这种对延迟敏感的文件。这种自动条带化意味着我们不需要像传统的LVM那样手动规划文件系统的布局。
ASM还有一个极其重要的特性:支持动态添加磁盘。当存储空间不足时,在线执行一条ALTER DISKGROUP DATA ADD DISK '/dev/asm-disk5';就能扩容,整个操作无需停库。这种在线扩展能力,在磁盘容量规划吃紧的生产环境中价值极大。
选择ASM而不是传统的文件系统,还有一个性能层面的考量。ASM绕过了操作系统的文件系统缓存,直接使用异步IO(AIO)进行数据传输,减少了数据在内存中的复制次数。对于RAC这种高并发、大量随机读写的场景,这种优化效果非常明显。我们实测对比过,同样负载下,ASM部署的数据库IO延迟比ext4文件系统低约15%到20%。
3. 部署前环境准备:硬件、操作系统与网络规划
3.1 硬件配置与存储划分实操参考
在正式动手安装之前,硬件的选型和规划决定了整个项目的上限。如果硬件资源分配不合理,后面无论软件怎么优化,效果都会打折扣。
我们这套RAC集群使用了2台同样的物理服务器,规格如下:
- CPU:2颗Intel Xeon Silver 4216(每颗16核32线程),关闭超线程
- 内存:128GB DDR4 ECC
- 存储:2块480GB SSD做系统盘RAID1,另外通过光纤HBA卡连接存储阵列
- 网络:板载双口千兆网卡做公有网络绑定,另配2张万兆光口网卡做私有网络(分别连接两台交换机,做冗余)
共享存储划分方式如下:
| 用途 | 大小 | ASM磁盘组 | 冗余策略 |
|---|---|---|---|
| OCR和Voting Disk | 3份,各10GB | CRS | Normal冗余 |
| 数据文件 | 2TB | DATA | Normal冗余 |
| 快速恢复区 | 1TB | FRA | Normal冗余 |
需要注意的一个细节:ASM的Normal冗余要求每个磁盘组至少包含2个故障组(Failgroup),本质上是要求共享存储具备多副本能力。如果底层存储阵列本身已经做了RAID10,可以考虑使用External冗余(外部冗余),ASM不额外做镜像。但核心系统建议保留ASM层的冗余——存储阵列的控制器故障、链路故障,ASM都能感知并自动切换,这是存储阵列内部的RAID无法实现的。
关于OCR和Voting Disk的布局,这里单独多说几句。Voting Disk默认需要3份,放置在CRS磁盘组中。为什么是3份?这是为了在双节点集群中避免平票:当两个节点互相失去联系时,谁能获取多数仲裁盘(至少2份),谁就获胜继续服务,另一个节点被逐出集群。这就是集群脑裂时的防脑裂机制。如果只放2份仲裁盘,节点间通信中断时双方各自拿到1份,形成平票,会导致两个节点同时接管共享存储,数据损坏的风险很大。
3.2 操作系统安装与关键内核参数配置
Oracle Linux 8.4的安装没什么特别之处,标准的服务器安装流程即可,注意选择“Server with GUI”或者最小化安装都可以(我们选的是最小化,节省系统资源)。有几个系统配置需要特别注意:
第一,SELinux必须设置为permissive或disabled。Oracle官方文档说明RAC部署不支持SELinux强制模式。我们第一次装的时候保留了默认的Enforcing,结果Grid Infrastructure安装到一半报了个网卡绑定的权限错误,排查了两个小时才定位到是SELinux拦截了Clusterware对网卡配置的写操作。
第二,防火墙要配置到位。RAC节点间的通信端口很多,包括1521(数据库监听)、1522(ASM监听)、1630(ONS)、6200(GNS)等。生产环境双节点RAC部署在信任的内网区域,最简单稳妥的方案是直接systemctl stop firewalld并禁用它,把安全控制下沉到硬件防火墙。如果强制要求操作系统防火墙开启,就必须手工精确放行Oracle官方文档列出的所有端口,这个选项比较繁琐且容易遗漏,不推荐。
第三,内核参数的调整。Oracle的安装前置检查(cluvfy)会对内核参数做严格检测,主要关注以下几项:
# /etc/sysctl.conf 关键配置 fs.file-max = 6815744 fs.aio-max-nr = 1048576 kernel.shmall = 1073741824 kernel.shmmax = 4398046511104 kernel.shmmni = 4096 kernel.sem = 250 32000 100 128 net.ipv4.ip_local_port_range = 9000 65500 net.core.rmem_default = 262144 net.core.rmem_max = 4194304 net.core.wmem_default = 262144 net.core.wmem_max = 1048576这里着重讲一下kernel.sem参数:四个值分别代表信号量数组最大长度(250)、系统范围内最大信号量数(32000)、每个信号量集合的最大数量(100)、系统范围内最大信号量集合数(128)。RAC各实例间需要通过信号量完成锁协调,如果这个值配置过小,高并发场景下实例会报ORA-27300错误。Oracle官方推荐的最小值是250 32000 100 128,我们生产环境直接按这个配。
再介绍一下内核参数生效的方式:
sysctl -p # 验证是否生效 sysctl kernel.sem内核参数配置完成后建议用root执行sysctl --system来确认所有配置文件中没有冲突项。我遇到过两次因为/etc/sysctl.conf里同一个参数出现在多行而导致后一行覆盖前一行,结果最终生效值和预期不一致的情况,所以查证这一步不可省。
3.3 用户、目录和SSH互信配置细节
RAC需要专用的操作系统用户来运行数据库和集群软件:oracle用户(运行数据库实例)和grid用户(运行Clusterware和ASM)。这两个用户需要分配到相应的用户组,权限分配的逻辑是这样:oinstall组是Oracle软件所有者组,dba组是数据库管理员组,asmadmin组是ASM管理员组,asmdba组是ASM数据库操作员组,asmoper组是ASM操作员组。
多节点RAC部署中有一个特别关键的准备工作:配置oracle用户和grid用户在所有节点间的SSH互信。Grid Infrastructure安装过程会在各节点之间推送文件并远程执行脚本,如果SSH互信没配好,安装会卡在节点配置阶段。配置方法是在第一台节点上生成密钥对,然后分发到所有节点的authorized_keys中:
# 在node1上执行 su - grid mkdir ~/.ssh && chmod 700 ~/.ssh ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa # 将公钥追加到两个节点的authorized_keys(node1 和 node2 都需操作) cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys ssh-copy-id -i ~/.ssh/id_rsa.pub grid@node1 ssh-copy-id -i ~/.ssh/id_rsa.pub grid@node2这里有个工程细节:集群运行时,GI会通过SSH在节点间执行一些维护操作,如果SSH需要密码交互,会导致某些自动操作失败,所以这个步操必须干净无误。
还需要为oracle和grid用户添加环境变量配置。常见的做法是在/home/grid/.bash_profile和/home/oracle/.bash_profile中设置ORACLE_BASE、ORACLE_HOME、PATH等环境变量。注意grid用户和oracle用户的ORACLE_HOME建议分开目录,这样可以独立升级GI和数据库软件,避免互相影响。这一点在生产环境的长期运维中特别重要。
4. 核心实施过程全记录
4.1 共享磁盘配置与ASM磁盘准备
共享存储在第一台节点的操作系统中呈现为多块未分区磁盘(例如/dev/mapper/mpatha、mpathb等)。由于是多路径设备,生产环境强烈建议使用udev绑定固定名称,因为设备名在重启后可能会变化。如果RAC节点重启后ASM磁盘设备名变了,ASM实例可能起不来,这是集群排障的常见问题根源之一。
我们通过multipath -ll命令查看多路径设备,然后编写udev规则,将每个设备绑定到固定符号链接。核心处理方法是这样的:给每块盘打上唯一的WWID(即通用标识符),然后在udev规则文件里面做映射。
比如要为/dev/mapper/mpatha创建固定名称,可以编辑/etc/udev/rules.d/99-oracle-asm.rules文件:
# 先获取磁盘的scsi_id /lib/udev/scsi_id -g -u -d /dev/mapper/mpatha # 假设输出是 3600c0ff0000000000000000000000000 # 编辑 /etc/udev/rules.d/99-oracle-asm.rules KERNEL=="dm-*", ENV{DM_UUID}=="mpath-3600c0ff0000000000000000000000000", SYMLINK+="oracleasm/asm-disk1", OWNER="grid", GROUP="asmadmin", MODE="0660"这里把设备的所有者设置为grid用户、组为asmadmin,这样ASM实例才能以适当权限访问这些存储设备。写好后重载udev规则:
udevadm control --reload-rules udevadm trigger在第二台节点上执行相同的操作(实际上通常是拷贝udev规则文件过去),然后确认两台机器的/dev/oracleasm/asm-disk1等符号链接都存在。
配置完成后,在Grid Infrastructure安装阶段,用asmca工具创建磁盘组时会看到这些磁盘。需要重点强调的是,ASM磁盘组创建时选择的冗余策略会影响条带化布局和镜像分配,普通冗余下,ASM会把数据在磁盘组内做双份镜像,使用的有效空间是总容量的一半。规划分区大小时必须把这一点算进去。
4.2 安装Oracle Grid Infrastructure(集群件)
Grid Infrastructure的安装是整个过程最复杂、最容易出错的环节。我们使用的是Oracle 19c的GI安装包(linuxx64_19c_grid_home.zip)。安装前把GI解压到/grid/app/19c/grid(注意这个路径不能和数据库软件的ORACLE_HOME混淆)。
安装过程的关键选择项包括:
- 安装类型选择“Oracle Grid Infrastructure for a Standalone Cluster”
- 配置SCAN名称(例如scan.rac-cluster.local)
- 配置GNS(如果使用DNS解析SCAN,可以跳过GNS;为了简化管理我们使用了GNS)
- 配置管理网络(Management Network),生产环境可以省略这一步,但如果有独立的ILO管理网络建议加进来
- 指定OCR和Voting Disk的磁盘组(选择之前建好的CRS磁盘组,冗余类型Normal)
一个比较隐蔽的坑:GI安装过程中会在两个节点上执行root.sh脚本。root.sh需要在两个节点上顺序执行,也就是说,先在第一台节点上以root执行root.sh,等它执行完成并显示成功之后,再到第二台节点上执行。如果并行执行,可能会出现集群注册信息不一致的情况。我们第一次安装就是两台节点同时跑root.sh,结果node2的crsd服务一直起不来,折腾了一个多小时才通过crsctl delete crs的方式重置掉重来。
GI安装完成后,用crsctl命令检查集群状态是标准操作:
crsctl status resource -t正常状态应该看到所有资源都是ONLINE,包括ora.cssd、ora.diskmon、ora.evmd、ora.asm等。如果某个资源状态显示OFFLINE,用crsctl start resource来拉起,如果仍然失败,查看对应日志($GRID_HOME/log/ /alert .log)来定位问题。
4.3 配置Oracle ASM磁盘组
GI安装完成后,会自带一个ASM实例(+ASM)。通过asmca图形工具或asmcmd命令行创建额外的磁盘组。生产环境强烈推荐使用asmca,它的界面能够直观展示磁盘状态、冗余策略、可用空间等关键信息。
创建DATA磁盘组的操作步骤是:启动asmca,选择Disk Groups标签页,点击Create,输入磁盘组名称DATA,冗余选择Normal(至少2个故障组),把之前准备好的asm-disk2到asm-disk10拖进磁盘组,点击OK等待ASM重新平衡(Rebalance)。
这里有一个生产环境必须掌握的核心理念:ASM在磁盘组创建或添加磁盘后,会自动执行重新平衡操作,把数据均匀分布到所有磁盘上。这个过程会在后台持续一段时间,期间IO性能可能会受到影响。如果生产环境需要在线扩容,建议把ASM_POWER_LIMIT设为1(最低),让重平衡过程尽量缓慢、减少对业务IO的影响,等空闲时间再调高做完。
我们当时创建完DATA磁盘组后,还创建了FRA(快速恢复区)磁盘组,用于存放归档日志和RMAN备份文件。FRA的设计使得Flash Recovery Area里可以统一管理归档日志、控制文件自动备份、闪回日志等空间,避免了归档日志增长导致磁盘空间耗尽的问题。
4.4 安装Oracle Database软件与创建RAC数据库
GI部署好通过之后,接着安装Oracle Database 19c软件(linuxx64_19c_db_home.zip)。这一步相对简单,跟单实例数据库软件安装类似,唯一需要注意的是在“选择安装类型”那一步,选“Set Up Software Only”——不要在这里创建数据库,稍后用dbca统一创建RAC数据库。
软件安装完成后,运行dbca创建集群数据库。这个过程的几个关键选项:
- 选择“Oracle Real Application Clusters database”而不是“Single instance database”
- 选择所有节点(node1和node2都要勾上)
- 存储类型选择ASM,磁盘组选择DATA
- 内存配置窗口,如果服务器内存足够大,可以把SGA分配为物理内存的60%到70%
- Archive日志模式选择开启(生产环境必开,不然没法做时间点恢复),归档位置指定到FRA磁盘组
- 字符集选择AL32UTF8,国家字符集选AL16UTF16
数据库创建过程会同时启动两个实例(orcl1和orcl2),创建完成后可以通过srvctl查看状态:
srvctl status database -d orcl看到两个实例都显示Online,说明RAC数据库已经正常运行了。
4.5 负载均衡与高可用性验证测试
集群搭好之后不能直接上线,必须做一轮完整的验证。负载均衡测试的典型做法是通过JDBC驱动连接SCAN地址,观察连接被分发到哪个实例。用sqlplus反复连接SCAN地址并查询INSTANCE_NAME:
-- 连接SCAN地址 sqlplus system/password@scan.rac-cluster.local:1521/orcl -- 查询当前连接的实例 SELECT instance_name FROM v$instance;多次连接,观察返回的实例来自orcl1和orcl2的数量基本对半,这是连接级负载均衡生效的正常现象。如果全都是同一个实例,说明SCAN监听器配置有问题,需要检查listener.ora配置及监听注册状态。
高可用性验证是更关键的环节。我们按顺序做了三组故障切换测试:
- 停掉节点1的数据库实例(srvctl stop instance -d orcl -i orcl1),观察节点2是否接管所有连接
- 直接reboot节点1服务器,模拟硬件故障,观察VIP是否漂移到节点2,连接是否中断
- 同时kill掉节点1的crsd进程,观察集群是否触发节点驱逐(Fencing)
第一组和第二组测试都顺利通过,连接在几秒钟内完成切换。第三组测试中,节点1被集群驱逐后自动重启(因为设置了Clusterware自动重启),节点1重新加入集群后,VIP自动回切,整个过程达到了设计的RTO要求。这些测试的实际结果验证了RAC机制的处理流程:GCS通过心跳信息检测到节点故障,报告给Clusterware后,触发资源重新定位,存货节点的LMS接手故障节点的资源协调任务。
这里要特别注意,RAC故障切换不是“事务级”的,它保证的是“连接级”可用——正在执行的事务如果没提交,可能会中断。真正的事务级保护需要依赖应用程序的重连机制,在设计高可用体系时要把这个边界理清楚。
5. 常见问题与故障排查实录
5.1 VIP地址ping不通导致客户端连接间歇性失败
在部署完成后的一周内,业务部门反馈偶尔出现连接超时。查看监听日志,发现SCAN监听器转发连接时,部分连接请求被发送到了一个VIP地址无法访问的节点。
排查过程:在客户端执行nslookup scan.rac-cluster.local,确认SCAN解析的3个IP正常。接着在节点1上ping节点2的VIP,发现不通。登录节点2检查VIP状态:
ip addr show发现VIP没有绑定到网卡。继续检查Clusterware日志,报错信息提示VIP无法启动(Resource 'ora.node2.vip' is OFFLINE)。最终定位到原因:VIP绑定的网卡名称在节点重启后发生了变化(因为网卡设备名从ens192变成了ens224),而Clusterware中记录的网卡信息还是旧的。
解决方案:删除并重新创建VIP资源,让Clusterware重新识别网卡:
srvctl remove vip -vip ora.node2.vip srvctl add vip -node node2 -address 192.168.1.12/255.255.255.0/ens224这个案例提醒我们,生产环境务必为物理机配置网卡绑定(bonding或team),并且尽量通过udev规则固定网卡名称,避免节点重启后网卡名漂移。
5.2 实例启动报ORA-27300信号量错误
RAC数据库创建完成后,在节点2上启动实例时报ORA-27300错误,信息大体是操作系统资源不足以创建信号量。检查/etc/sysctl.conf,发现kernel.sem参数虽然在文件里写了,但加载顺序有问题:rgmanager服务把参数覆盖回了默认值。
处理方式:确认加载顺序并重新写入推荐值。在生产环境,我的习惯是在安装完GI和数据库后,再执行一次sysctl -p并抓取当前的kernel.sem值做校验,遇到这种问题就把参数同时写进/etc/sysctl.conf和/etc/sysconfig/oracle这个配置文件里(Oracle会读取这个文件做运行时调整)。
5.3 心跳网络丢包引发的集群成员反复摇摆
集群上线后运行了一个多月,某天下午突然收到告警:集群成员状态在Online和Offline之间反复变化。查看crsd日志,发现心跳超时的计数不断增加。因为两台节点之间的私有网络连接出现了微小的丢包,导致心跳检测不稳定,集群一直在做重新配置。
最终排查出来,是机房网络运维在核心交换机上修改了生成树协议(STP)配置,心跳网络经过的那条万兆链路出现了短暂中断。解决方式:把心跳网络从共享交换机切换到单独的、不经过核心交换机的直连线缆,从物理层面隔离了干扰。这里给所有准备部署RAC的团队一个建议:心跳网络越“短”越好,最好两根光纤直连两台服务器,不走任何交换机。虽然这种部署方式看起来不够“现代化”,但稳定性是最高的。
6. 性能调优与长期运维心得
6.1 针对负载均衡特性的应用层配置建议
RAC集群的负载均衡既有数据库层面的,也有应用层面的。数据库层面的负载均衡由SCAN监听器自动完成,但应用层是否配合决定了最终的效果。我们团队在业务系统上线时,把应用服务器的数据库连接池配置做了调整:
- JDBC连接串使用
jdbc:oracle:thin:@scan.rac-cluster.local:1521/orcl,这个连接串会自动使用SCAN地址完成多实例间的连接分发 - 连接池的初始化连接数不要只设置在一个节点上,建议所有连接池初始化时都指定到SCAN地址,让连接分布自动均衡
- 会话状态管理要注意:RAC不保证同一个用户后续请求一定落在同一个实例上。如果业务代码依赖数据库会话状态(比如临时表、会话级变量),需要改为使用全局临时表或增加路由标识字段
持久连接方面,RAC的负载均衡在连接级有效,在SQL执行级别还有一层优化。每个实例的SQL执行计划缓存是独立的,同一个SQL在节点1已经解析并缓存了执行计划,到节点2还要重新解析。如果应用对SQL执行计划和响应时间要求比较高,可以开启全局SQL执行计划共享 —— 通过参数cursor_sharing或使用SGA中的shared pool全局缓存,不过这属于数据库内部调优的范畴,后续可以单独写一篇。
6.2 定期巡检与维护命令集锦
RAC集群的日常运维,我整理了一套固定的命令清单:
# 检查集群资源状态 crsctl status resource -t # 检查ASM磁盘组空间和健康状态 asmcmd lsdg asmcmd ls -l DATA # 查看实例运行状态 srvctl status database -d orcl # 检查集群日志(重点看ORA-和CRS-开头的错误) tail -f $GRID_HOME/log/$HOSTNAME/alert$HOSTNAME.log # 检查数据库监听器状态 lsnrctl status # 检查数据库会话分布 sqlplus -S system/password <<EOF SELECT inst_id, count(*) FROM gv$session GROUP BY inst_id; EOF巡检频率方面,每天定时检查集群资源状态和ASM磁盘空间,每周做一次实例会话分布对比,确认负载均衡持续正常。
6.3 备份策略在RAC环境下怎么定
RAC环境下的备份和单实例数据库有本质区别——所有备份操作都必须通过RMAN连接到ASM存储的数据库文件。RMAN在RAC环境下不仅支持传统备份,还特别适合利用多个实例并行执行备份操作,这能大大缩短备份窗口。
我们的备份策略是每天晚上12点做增量备份,每周日凌晨做全量备份,备份文件直接写到FRA磁盘组,然后通过RMAN备份到本地磁带库。具体配置为:
# 每天增量备份(在节点1执行) rman target / <<EOF BACKUP INCREMENTAL LEVEL 1 DATABASE PLUS ARCHIVELOG DELETE INPUT; EOF # 每周全量备份 rman target / <<EOF BACKUP INCREMENTAL LEVEL 0 DATABASE PLUS ARCHIVELOG DELETE INPUT; EOF归档日志管理是RAC特有的重点。两个实例产生的归档日志都写入FRA磁盘组,如果FRA空间不够,会导致归档日志无法写入,数据库实例直接挂起。我们用asmcmd定期检查FRA空间使用率,并配置RMAN的备份命令自动删除已经被备份过的归档日志,确保FRA使用率在八成以内。
我自己跑这套集群到现在已经一年半了,节点切换测试做过十几次,生产系统经历了一次电源故障和两次数次网络抖动,集群的故障转移都比较稳妥。如果要从头捋一遍经验,最值得记住的几条:一是共享存储的规划和网络隔离要做好,这两个基础不牢,后面所有上层配置都是脆弱的;二是RAC并不是万能的,它解决的是计算节点的单点故障和吞吐扩展,存储层面的故障还得靠底层的存储高可用方案兜底;三是任何架构调整上线前,故障演练不能省,多杀几次节点,心里才有底。
最后分享一个小技巧:RAC的集群日志目录$GRID_HOME/log如果长期不清理,会被crsd和alert日志撑爆,建议配置一套日志轮转策略,按文件大小切割并保留最近30天。我们写过一个简单的logrotate配置,每天切割一次,日志文件保留30份,用了一年多,集群根文件系统的使用率一直稳定在合理的水平。