聊到 Oracle 19c RAC,很多 DBA 的第一反应是:单机装过那么多次了,RAC 不就是多配两个节点、多挂几块共享盘的事?真到了 Linux 环境里动手,你会发现光是网络解析、集群资源、ASM 磁盘和 root 脚本这四个环节,就足够打掉你一个完整的周末。这篇文章完全从实战角度整理我在 Linux 服务器上完整安装 Oracle Database 19c RAC 的过程,从节点规划、共享存储绑定、Grid Infrastructure 部署、数据库层建库讲到装完之后的资源验证和故障切换测试。如果你正准备在 RHEL 或 Oracle Linux 7/8 环境里搭一套两节点 RAC,或者已经踩在坑里正在排查,这份内容应该能帮你省掉不少绕弯的时间。
我默认你至少对单机 Oracle 安装有基本认知,Linux 基础命令没问题。RAC 的安装其实不是一个"下一步下一步"的流程,而是一连串方案决策的串联:网络怎么分、存储怎么切、集群在哪一层起、数据库资源怎么挂。下面我按自己实测的顺序来写,每个环节都尽量把"为什么要这么做"讲清楚。
1. 装RAC 19c之前,先把这几件"决定成败"的基础事一次性理顺
1.1 网络和DNS:集群能不能起来,一半取决于这里
RAC 对网络的要求比单机严格得多。两节点部署时,每个节点至少规划三块网卡:一块 public 用于业务访问,一块 private 用于心跳和 Cache Fusion,VIP 和 SCAN IP 虽然在逻辑上是独立地址,但 VIP 实际上会绑定在 public 网卡上。我的建议是 private 用独立交换机或独立 VLAN,千万不要跟业务网段路由重叠,否则节点间通信和业务流量互相干扰,later 出现性能问题你很难排查。
hosts 文件建议这样写:
192.168.1.10 rac1 192.168.1.11 rac2 192.168.1.12 rac1-vip 192.168.1.13 rac2-vip 192.168.1.20 rac-scan 10.0.0.1 rac1-priv 10.0.0.2 rac2-priv写完之后,两个节点都要执行hostname -i检查返回值是否正常。很多安装失败都源于/etc/hosts和系统解析顺序冲突,导致hostname -i返回 127.0.0.1,后面的 CVU 检查直接报节点无法通信。另外,SCAN 地址在生产环境强烈建议用 DNS 解析,官方推荐 DNS 至少解析出三个 IP 用于负载均衡。你确实可以在 hosts 里硬写一个 scan 条目绕过检查,但这样做的后果是 SCAN IP 没有真正高可用,后续客户端连接和 GNS 相关功能都会受限。既然都搭 RAC 了,网络这层就别将就。
防火墙和 SELinux 也要在两个节点上统一关闭。命令很简单:
systemctl stop firewalld systemctl disable firewalld sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config setenforce 0还有一个小坑必须提前避掉:如果你的网卡由 NetworkManager 管理,节点重启后网卡名有可能从 ens160 变成 ens192,VIP 绑定就会失败。我在生产服务器上遇到过两次,后来在网卡配置里统一加了NM_CONTROLLED=no,或者在 grub 里加了net.ifnames=0 biosdevname=0固定命名,问题才彻底消失。系统层面这些事如果不在装 GI 前处理好,等到集群起不来再返工,代价翻倍。
1.2 系统参数、用户和目录:统一性比"性能"更重要
RAC 是两个节点的系统环境做"并集",任何一端的差异都可能成为集群不稳定因素。用户和组必须两个节点保持一致 UID/GID,我习惯按官方推荐建这些组:
groupadd -g 54321 oinstall groupadd -g 54322 dba groupadd -g 54323 oper groupadd -g 54324 backupdba groupadd -g 54325 dgdba groupadd -g 54326 kmdba groupadd -g 54327 asmdba groupadd -g 54328 asmoper groupadd -g 54329 asmadmin groupadd -g 54330 racdba useradd -u 54321 -g oinstall -G dba,oper,backupdba,dgdba,kmdba,racdba oracle useradd -u 54322 -g oinstall -G asmadmin,asmdba,asmoper,dba grid目录规划上,Grid 的家目录我用/u01/app/19.0.0/grid,Oracle 的 base 用/u01/app/oracle,软件目录/u01/app/oracle/product/19.0.0/dbhome_1。注意/u01这个文件系统建议单独给 80GB 以上,因为 GI、DB、日志、diag 目录涨起来非常快。目录创建好之后,确认属主:
chown -R grid:oinstall /u01/app/19.0.0 /u01/app/grid chown -R oracle:oinstall /u01/app/oracle内核参数直接贴我的模板,这里不展开每项都解释,但要注意kernel.shmmax建议设成物理内存的一半以上,fs.aio-max-nr至少要 1048576,否则高并发下可能出现aio-max-nr不足的报错:
fs.aio-max-nr = 1048576 fs.file-max = 6815744 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 = 1048576limits.conf 也要同时给 grid 和 oracle 两个用户配置:
grid soft nofile 1024 grid hard nofile 65536 grid soft nproc 2047 grid hard nproc 16384 grid soft stack 10240 grid hard stack 32768 oracle soft nofile 1024 oracle hard nofile 65536 oracle soft nproc 2047 oracle hard nproc 16384 oracle soft stack 10240 oracle hard stack 32768依赖包这块,不同 Linux 发行版差异较大。如果用的是 Oracle Linux,建议直接安装oracle-database-preinstall-19c这个 rpm,它会一次性把大多数依赖和内核参数搞定。如果手动装,至少要保证compat-libcap1、compat-libstdc++、libaio、libnsl、bc、binutils等包都在。可以用rpm -q逐一核对,缺什么补什么。
1.3 时间同步与内核大页:cvu检查最容易卡住的两个点
CVU 检查(Cluster Verification Utility)在安装 Grid 时会自动执行,时间偏差和内核配置是它最喜欢报 warning 的地方。时间同步我推荐用 chronyd,不要再用ntpdate加 cron 的方式,因为时间回跳对 RAC 很致命,可能直接触发集群重连甚至脑裂保护。
配置很简单,指向内部 NTP 服务器:
server 192.168.1.100 iburst allow 0/0 local stratum 10两个节点都配好后,chronyc tracking能看到当前偏移量。CVU 默认对时间偏差比较敏感,如果测试环境没有 NTP 源,至少要保证两个节点时间差在 30 秒以内,最好是毫秒级。
透明大页(Transparent HugePages)在 19c 下必须关闭。不关的话,数据库 SGA 的锁页和 THP 的 khugepaged 线程会互相干扰,严重时出现诡异的性能退化。关闭方法:
grubby --update-kernel=`uname -r` --args="transparent_hugepage=never"然后重启,确认/sys/kernel/mm/transparent_hugepage/enabled输出为never。同时建议检查/dev/shm的大小,默认是物理内存的一半,如果后续数据库 SGA 和 PGA 配得比较大,建议在/etc/fstab里给它单独加size=参数,比如 32GB 内存的机器给 16GB 以上,否则 DBCA 建库时很容易碰到ORA-00845: MEMORY_TARGET not supported on this system。
2. 共享存储规划与udev/多路径绑定:返工率最高的环节没有之一
2.1 存储LUN划分与多路径alias:别用/dev/sdb这种不稳定的设备名
存储这一层是 RAC 和单机最大的区别。两个节点必须看到完全一样的共享 LUN,且 LUN 的 wwid 一致。我见过有人在生产环境直接用/dev/sdb、/dev/sdc给 ASM 用,当时能用,但服务器重启后设备名漂移,ASM 磁盘完全认不到,实例直接起不来。所以一定要用多路径软件把磁盘固定成稳定的 alias。
在/etc/multipath.conf里这样配置:
multipaths { multipath { wwid 3600c0ff0000000000000000000000000 alias OCR01 } multipath { wwid 3600c0ff0000000000000000000000001 alias DATA01 } multipath { wwid 3600c0ff0000000000000000000000002 alias FRA01 } }wwid怎么拿?multipath -ll或者scsi_id -g -u -d /dev/sdb都能看到。配置完成后multipath -r,然后用ls -l /dev/mapper/OCR01确认设备已生成。这里有个容易忽略的点:每个 LUN 对应的 alias 必须在两台节点完全一样,不能节点1叫 DATA01、节点2叫 DATA02,否则 ASM 会发现磁盘路径不一致,crs 资源起不来。
2.2 udev规则与ASM磁盘权限验证
19c 不再强制要求 ASMLib,用 udev 规则把多路径设备授权给 grid 用户就行,这是目前最干净的做法。规则文件写在/etc/udev/rules.d/99-oracle-asm.rules,内容类似:
KERNEL=="dm-*", ENV{DM_UUID}=="mpath-3600c0ff0000000000000000000000000", OWNER="grid", GROUP="asmadmin", MODE="0660" KERNEL=="dm-*", ENV{DM_UUID}=="mpath-3600c0ff0000000000000000000000001", OWNER="grid", GROUP="asmadmin", MODE="0660"这里的DM_UUID可以通过udevadm info --query=all --name=/dev/mapper/OCR01 | grep DM_UUID拿到。注意一定要用dm-*加DM_UUID,不要用KERNEL=="sd*"这种写法,否则同一个盘既会被sdb匹配又会被dm-0匹配,权限乱套。
写完规则后,两个节点都要执行:
udevadm control --reload udevadm trigger然后ls -l /dev/mapper/OCR01确认属主是grid:asmadmin、权限0660。这一步我建议每块盘都验证一遍,不要嫌麻烦。装 GI 时 ASM 磁盘找得到盘但权限不足报ORA-15055的情况,大半都是这里偷懒了。
2.3 ASM磁盘组容量规划:OCR、DATA、FRA和GIMR各留多少
磁盘组规划直接决定后面 DBCA 能不能顺利建库。我的建议如下:
| 磁盘组 | 用途 | 推荐盘数 | 推荐单盘容量 |
|---|---|---|---|
| OCRVT | OCR和Voting Disk | 3块(奇数) | 2-5GB |
| DATA | 数据文件、控制文件 | 至少2-4块 | 按数据量估算 |
| FRA | 归档日志、闪回区 | 至少2块 | 建议与数据量接近 |
| MGMT | GIMR管理仓库 | 至少1块 | 10-30GB |
OCR 和 Voting Disk 为什么要奇数块?因为 Voting Disk 本身靠 quorum 机制做脑裂仲裁,偶数块在丢一块盘的时候容易陷入僵局。OCR 我建议 3 块 2GB 起步,normal 冗余下可以容忍丢一块。DATA 和 FRA 的容量算法要乘冗余因子:如果用 normal 冗余,2TB 裸容量实际上只有 1TB 可用空间,DBCA 阶段千万不要只看裸容量就去填初始化大小。
GIMR 这个磁盘组容易被忽略。19c 的 GI 安装向导会让你选择是否配置 Grid Infrastructure Management Repository,默认会要求给它单独分配磁盘组,名字类似SYSTEMDG或MGMT。如果你测试机空间紧张,可以取消 GIMR;生产环境建议保留,并且给它至少 30GB,因为 MGMTDB 的仓库数据会持续增长。提前规划好这四类磁盘,后面安装会顺畅很多。
3. Grid Infrastructure安装实录:从cvu检查到root.sh的执行细节
3.1 GI软件安装和集群配置界面中的关键选项
安装包解压后,用 grid 用户执行./gridSetup.sh。启动界面里选第一项Configure Oracle Grid Infrastructure for a New Cluster。集群名称可以自定义,SCAN 名称我用的是前面 hosts 里规划好的rac-scan,SCAN 端口默认 1521 就可以。GNS 选项我一般选 No,使用 DNS 解析 SCAN 更符合多数生产环境。
节点列表页面会要求你添加rac1和rac2,SSH 互信可以勾选让 OUI 自动配置。注意给 GI home 目录/u01/app/19.0.0/grid的权限一定要提前处理好,OUI 会把软件解压到本节点,然后通过 SSH 复制到另一个节点,如果另一端目录属主不对,这里会直接失败。
存储选项选择 ASM,先不要建数据库。到了 ASM 磁盘组配置页,把OCR01、OCR02、OCR03选进 OCR/Voting 磁盘组,冗余方式选 Normal;如果有 MGMT 盘,再建一个磁盘组给 GIMR。在这个界面能看到每块盘是否被识别、属主是否正常,这是验证 udev 规则是否正确的最直观方式。最让人头疼的检查阶段马上就来。
3.2 CVU检查典型失败项及处理办法
CVU 检查是 GI 安装的第一个"劝退点"。我把自己遇到过的几类高发问题列个表:
| 报错或现象 | 根因 | 处理方式 |
|---|---|---|
| PRVF-7535 时间偏移过大 | 两个节点 NTP 未同步 | 配置 chrony,chronyc makestep强制校准 |
| PRVF-0002 节点无法通信 | hosts 配置错误,防火墙未关 | 检查/etc/hosts,关 firewalld |
| PRVF-5442 SCAN 解析失败 | DNS 未配置 SCAN 记录 | 在 DNS 添加 A 记录,或用 hosts 临时绕过 |
| PRVG-1101 DNS 超时 | DNS 不可达,解析太慢 | 确认 DNS 服务器连通性,检查/etc/resolv.conf |
| PRVF-7532 包兼容性报错 | 缺 rpm 依赖包 | 用rpm -q核对,安装缺失的包,比如 cvuqdisk |
cvuqdisk 这个 rpm 在 GI 安装介质的rpm/目录下,安装时容易漏掉。报缺失时去安装介质目录里找一下,两个节点都装上,然后重跑检查。很多时候 CVU 报的 warning 可以勾选忽略,但如果报的是 error,我建议还是老老实实修掉,否则 root.sh 阶段大概率会翻车。我踩过一次 SCAN 反解失败导致 listener 起不来,最后还是在 DNS 上补了 PTR 记录才解决。
3.3 root.sh脚本执行的正确顺序与常见故障排查
CVU 通过后,OUI 会让你在两个节点上分别执行脚本。这里有一个非常关键的纪律:节点1 的orainstRoot.sh和root.sh必须完全执行成功,再动节点2。两个节点同时执行 root.sh 抢 OCR 初始化的案例,我见过不止一次,最后全要清掉/etc/oracle/olr.loc、清理集群配置重来,教训很深刻。
节点1 的 root.sh 核心工作是创建本地注册表、启动 CSS/CRS、格式化 OCR/Voting 磁盘,然后拉起集群资源。它成功结束的标志通常是你执行crsctl check crs能看到 CRS、CSS、EVM 几个进程都正常。如果失败,先看两个日志目录:/u01/app/oraInventory/logs/和/u01/app/19.0.0/grid/cfgtoollogs/crsconfig/rootcrs_rac1.log,报错信息基本都写在里面。
常见错误有几种。PROT-30: Failed to initialize Oracle Cluster Registry,十有八九是 OCR 磁盘没有正确授权,ls -l /dev/mapper/OCR01一看属主不是 grid 就明白了。CRS-0184: Cannot communicate with the CRS daemon,可能是 GI home 属主不对,或者/u01空间不足导致日志写满。还有一种比较隐蔽,root.sh 执行到一半进程被杀,多半是/tmp空间耗尽。遇到 root.sh 失败不要急着删文件重来,先看日志定位根因,修复之后再重跑,这个过程的成本最低。
节点2 的 root.sh 执行完后,集群会把节点2 加进来。此时执行crsctl status resource -t,会看到ora.asm、ora.cssd、ora.diskmon、ora.scan1.listener等资源在两边都是 ONLINE 状态,GI 层就算起来了。
4. 数据库软件和DBCA建库:一路踩坑到跑通
4.1 选择"集群数据库"安装模式时要注意的细节
GI 起来后,用 oracle 用户解压数据库软件包,执行runInstaller。这里我建议选Install Database Software Only,先把软件层装干净,再单独用 DBCA 建库。不要一开始就选"创建数据库",否则建库出错时排查范围会变大,软件和数据库问题混在一起很难搞。
安装类型选Oracle Real Application Clusters database installation,它会让你勾选哪些节点安装数据库软件。同样,SSH 互信在前面已经配好,这里直接选中两个节点即可。软件装到/u01/app/oracle/product/19.0.0/dbhome_1,确认 oracle 用户对该目录有写权限。
最后 OUI 同样要求以 root 身份在节点上执行脚本。数据库软件层的 root.sh 比 GI 简单,主要创建一些目录和配置权限,但两个节点都要执行到位,缺一个后面 DBCA 可能报实例或网络配置找不到。还有一个细节:GI 和 DB 的补丁基线尽量一致。如果 GI 已经打了 19.18 RU,数据库软件最好也打到相同 RU,否则后续srvctl管理数据库时容易出现版本不一致的告警。
4.2 DBCA的磁盘组与存储选项怎么选
DBCA 打开后,选择创建 RAC 数据库,两个节点默认都会勾上。数据库名我用的是racdb,SID 前缀会自动变成racdb1和racdb2。存储类型默认就是 Oracle ASM,磁盘组页面会出现你在 GI 阶段建好的DATA和FRA。
数据文件选DATA磁盘组,快速恢复区选FRA并勾上"启用归档"。字符集我统一用AL32UTF8,国家字符集AL16UTF16,除非你明确有特殊需求。高级选项里把PROCESSES从默认 320 改到 500 以上也是常见操作,但如果没有特殊并发需求,保持默认也没问题。
DBCA 建库卡住是最让人焦躁的。我遇到最多的是进度条停在 0% 或者 5% 几分钟不动,然后报ORA-15055,字面意思是无法打开 ASM 磁盘。这个时候不要反复重试,去看日志/u01/app/oracle/cfgtoollogs/dbca/底下最新的日志,多半是磁盘组空间不足,或者 ASM 在某个实例上起不来。用asmcmd lsdg检查一下DATA剩余空间,心里就有数了。
DBCA 还有一个默认行为容易被忽略:它会创建一个UNNAMED的初始数据文件小文件放到某个磁盘组,如果你的磁盘组选项没选对,这个文件可能落到DATA里或者等待你指定位置。实际上只要在磁盘组页面把数据文件位置明确选到DATA,一般不会触发这个问题。
4.3 数据库创建后的状态检查和初始参数调整
数据库建完后,第一件事不是急着连上去跑 SQL,而是确认两边实例状态:
srvctl status database -d racdb正常输出是两个实例 ONLINE。然后用 sqlplus 通过 SCAN 连接一下:
sqlplus sys/password@racdb as sysdba这里用的是racdb服务名,通过 SCAN 负载均衡,会自动连到其中一个实例。接着查视图确认 RAC 层真的通了:
select inst_id, instance_name, status from gv$instance order by inst_id;能看到两个实例输出,数据库层才算真正建立起来。参数方面,我习惯立即检查几条:
- SGA_TARGET、PGA_AGGREGATE_TARGET 是否按内存规划合理设置;
- DB_RECOVERY_FILE_DEST_SIZE 是否与 FRA 磁盘组容量匹配;
- OPEN_CURSORS 默认 300,应用并发高的话改到 1000 以上;
- PROCESSES 是否有余量。
如果建库时选了 AMM 自动内存管理,SGA/PGA 都用 MEMORY_TARGET 控制,那么/dev/shm一定要足够大。两个实例的 SGA 加起来接近物理内存时,启动第二个实例很容易报ORA-00845。到了这一步,我的习惯是直接关闭 MEMORY_TARGET,改成 SGA_TARGET + PGA_AGGREGATE_TARGET 管理,稳定性更好,也方便后面调优。
5. 集群装完不等于完事:资源、故障切换和维护备忘录
5.1 用crsctl和srvctl做一次全面的资源巡检
数据库能查出来不代表集群配置全部正确。接下来我建议按顺序跑一遍巡检:
crsctl stat res -t这句命令能看到集群所有资源的状态,重点关心ora.asm、ora.cssd、ora.diskmon、ora.scan1.listener、ora.racdb.db是否在两个节点都 ONLINE。然后:
srvctl status database -d racdb srvctl status service -d racdb srvctl status scanscan如果有多个 listener,都要处于 ONLINE。接着检查 OCR 自动备份:
ocrconfig -showbackup正常情况下能看到最近几天的自动备份。集群自启动配置也要确认:
crsctl config crs这里会显示自动启动相关的信息。如果集群资源没有设置自动启动,服务器重启后不会自己拉起集群,这是一个很容易被忽视的坑。在实际运维中,我通常还会检查两个节点的asmcmd lsdg,确认DATA和FRA的可用空间比例,并把它作为日常监控的重要内容。
5.2 故障切换测试:service和listener是不是真的在保护你
装完 RAC 不测故障切换等于白装。很多人以为集群资源 ONLINE 就万事大吉,真把实例停了才发现客户端连接直接断掉,原因是 DBCA 默认创建的 service 没有配置透明应用故障转移 TAF。
推荐的做法是自己创建一个带 TAF 属性的 service:
srvctl add service -d racdb -s racdb_svc \ -r "racdb1,racdb2" \ -P BASIC -m BASIC -e SELECT -w 5参数含义:-r定义首选实例列表,-a可以加备选实例;-P是 TAF 的 preconnect 策略这里设为 BASIC 表示按需连接;-m是 failover 模式;-e是 failover 类型,SELECT 表示活动查询可以无缝迁移;-w是 failover 延迟时间。客户端连接串也要对应写成:
DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = rac-scan)(PORT = 1521)) (CONNECT_DATA = (SERVICE_NAME = racdb_svc) (FAILOVER_MODE = (TYPE = SELECT)(METHOD = BASIC)(RETRIES = 5)(DELAY = 5)))然后做一次"破坏性"测试:在节点1 上执行srvctl stop instance -d racdb -i racdb1,观察已有的查询会话是否会切换到节点2。如果连接串或 service 属性配置不对,这时候你会看到 ORA-12571 或连接挂起。只有真正经历过 session 平滑漂移,这套集群才算可用。当然,测试前要在低峰期,并且确认客户端 SQL 里没有依赖单实例的临时状态。
5.3 后续维护最容易被忽视的几个问题
集群搭好只是开始,后续维护里我踩过最深的坑有三个:补丁基线、OCR 备份和 ASM 空间。
19c 每季度都有新的 RU 补丁,GI home 和 DB home 的补丁基线必须保持一致。只给 GI 打补丁不给 DB 打,短期内看起来正常,但srvctl做某些操作时会因为版本不一致触发隐性问题。每次打补丁前,建议先opatch lsinventory记录基线,再按 GI、DB、OJVM 的顺序依次升级。
OCR 备份不用天天手动做,ocrconfig -showbackup能看到自动备份,但我仍然会给它加一个每日导出任务:
ocrconfig -export /backup/ocr_$(date +%Y%m%d).bak原因很简单,自动备份存放在 GI home 所在目录,/u01盘如果挂了,自动备份也跟着没了。定期导出到独立目录,恢复时手里才有牌。另外补丁或更换磁盘导致 OCR 变更后,立即重新导出一份。
ASM 空间监控非常关键。FRA 磁盘组如果写满,归档日志写不进去,数据库会直接 hang 住,这是生产事故级别的故障。我的经验是给 FRA 剩余空间设置一个阈值监控,低于 20% 就要立刻处理。asmcmd lsdg的Pct_Used列要养成每日看的习惯,别等应用报错才去登录服务器。
双节点时间漂移也要定期检查。HTTP 服务或应用稍有异常,可能导致一端的时钟偏移超过集群容忍阈值,随之而来的是节点被驱逐。我用 chrony 后,会在巡检脚本里加上chronyc tracking的记录,确保两边 offset 都在个位数毫秒以内。
最后说一个未来大概率会遇到的操作——扩容节点。正确的顺序是:先给新节点配好系统环境并加好共享存储,然后用grid用户执行 grid 的 addnode,再用oracle用户执行 db 的 addnode,最后srvctl add instance。反着来很容易出现资源注册不全,还要清理重做,浪费时间。整个 RAC 体系最看重的是"顺序感"——安装时有顺序,维护时也有顺序,顺序对了,绝大多数问题都能避开。
我这套流程跑下来,最大的感受是 RAC 本身并不难,难的是对操作系统、网络、存储这些基础设施细节的较真程度。你在/etc/hosts、udev 规则、root.sh 顺序上多花的那两小时,会在后面的补丁、扩容、故障切换里成倍还给你。