
聊到 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 FusionVIP 和 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.*/SELINUXdisabled/ /etc/selinux/config setenforce 0还有一个小坑必须提前避掉如果你的网卡由 NetworkManager 管理节点重启后网卡名有可能从 ens160 变成 ens192VIP 绑定就会失败。我在生产服务器上遇到过两次后来在网卡配置里统一加了NM_CONTROLLEDno或者在 grub 里加了net.ifnames0 biosdevname0固定命名问题才彻底消失。系统层面这些事如果不在装 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/gridOracle 的 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-kerneluname -r --argstransparent_hugepagenever然后重启确认/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内容类似KERNELdm-*, ENV{DM_UUID}mpath-3600c0ff0000000000000000000000000, OWNERgrid, GROUPasmadmin, MODE0660 KERNELdm-*, ENV{DM_UUID}mpath-3600c0ff0000000000000000000000001, OWNERgrid, GROUPasmadmin, MODE0660这里的DM_UUID可以通过udevadm info --queryall --name/dev/mapper/OCR01 | grep DM_UUID拿到。注意一定要用dm-*加DM_UUID不要用KERNELsd*这种写法否则同一个盘既会被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 能不能顺利建库。我的建议如下磁盘组用途推荐盘数推荐单盘容量OCRVTOCR和Voting Disk3块奇数2-5GBDATA数据文件、控制文件至少2-4块按数据量估算FRA归档日志、闪回区至少2块建议与数据量接近MGMTGIMR管理仓库至少1块10-30GBOCR 和 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-scanSCAN 端口默认 1521 就可以。GNS 选项我一般选 No使用 DNS 解析 SCAN 更符合多数生产环境。节点列表页面会要求你添加rac1和rac2SSH 互信可以勾选让 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 未同步配置 chronychronyc makestep强制校准PRVF-0002 节点无法通信hosts 配置错误防火墙未关检查/etc/hosts关 firewalldPRVF-5442 SCAN 解析失败DNS 未配置 SCAN 记录在 DNS 添加 A 记录或用 hosts 临时绕过PRVG-1101 DNS 超时DNS 不可达解析太慢确认 DNS 服务器连通性检查/etc/resolv.confPRVF-7532 包兼容性报错缺 rpm 依赖包用rpm -q核对安装缺失的包比如 cvuqdiskcvuqdisk 这个 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 数据库两个节点默认都会勾上。数据库名我用的是racdbSID 前缀会自动变成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/passwordracdb 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 属性的 servicesrvctl 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 顺序上多花的那两小时会在后面的补丁、扩容、故障切换里成倍还给你。