Oracle 19c RAC Linux 7.6 安装前置配置与 GNS/SCAN 实战

发布时间:2026/10/31 2:31:33
Oracle 19c RAC Linux 7.6 安装前置配置与 GNS/SCAN 实战

简介:《Oracle 19c RAC on Linux 7.6安装手册》面向Oracle数据库管理员、集群架构师与实施工程师,围绕Red Hat 7.6环境下19c RAC的落地部署,重点处理GNS配置SCAN、Flex ASM使用以及集群模式选择等实际问题,适合具备一定Linux与数据库基础、希望向高级集群运维进阶的读者参考。内容按实施流程组织,覆盖操作系统环境检查、关闭THP并开启Hugepages、Red Hat 7软件包与其他依赖安装、内核参数配置、CVU检查、固定网络与GNS加固定网络两种方案、时钟同步及杂项配置,并说明Standalone Cluster与Domain Service Cluster模式差异、版本变化和常见问题排查思路。压缩包共1个docx文件,约160KB,轻量便于随查随用;已有719人学习下载,说明其在RAC实施场景中具备一定参考价值。读者可据此系统梳理19c RAC安装全链路,理解Flex ASM与集群模式选择,并借鉴问题定位、日志分析、故障处理与复盘方法,减少重复试错。

1. 卡在安装器之前那两天:19c RAC 在 Linux 7.6 上的真实工作量

两台机器、双网卡、三块共享盘,gridSetup.sh的图形界面点完不到四十分钟,而从裸机走到能点那一步,我用了整整两天。Oracle 19c RAC 在 Linux 7.6 上的难点从来不在安装器本身,而在安装器之前的一长串前置条件:THP 有没有真关掉、HugePages 和 memlock 对不对得上、SCAN 的正反解走不走得通、ASM 盘的属主稳不稳定。这份手册把 OS 检查、内核参数、网络(含 GNS 代管 SCAN)、UDEV 绑盘、gridSetup 到 dbca 的整条链路拆成了可执行步骤,也交代了 Flex ASM 以及 Standalone Cluster 与 Domain Service Cluster 两种集群模式的版本背景。第一次上手 19c RAC 的 DBA 能照着走,装过 11g、12c 想搞清楚 19c 变了什么的老手,也能从参数对照表里挑到自己要的那几行。

2. 从 OS 检查到 HugePages:内存、内核参数与 limits 的四个落点

这一章是整份手册里最容易被跳过、也最容易在后面翻车的部分。19c 对操作系统的要求本身不苛刻,麻烦的是这些要求分散在内存、内核、用户限制、大页四个地方,任何一个没对上,症状都不会在检查阶段暴露,而是在gridSetup.sh跑到一半或者实例启动时才炸出来。我的习惯是先把这一章的所有动作做完并留下记录,再去碰安装介质。

2.1 开局先量七个数字

先别急着装包,把机器现状量清楚。手册里列了七项硬性检查,我按可执行顺序整理成下面这张表,两节点都要跑,输出保存成安装记录的一部分。

检查项命令19c 要求
物理内存grep MemTotal /proc/meminfo至少 8G
运行级别runlevel3 或 5
内核与发行版uname -mr、cat /etc/redhat-releaseRHEL 7.4 起,3.10.0-693.5.2.0.1.el7 及以上;OEL 用 UEK4/UEK5
/tmp 空间df -h /tmp至少 1G
Swapgrep SwapTotal /proc/meminfo内存 4~16G 时等于内存;大于 16G 时给 16G;开了 HugePages 要减去分给大页的那部分
/dev/shmdf -h /dev/shm、mount | grep shm挂载类型与权限正常
软件目录df -h /u01Grid 至少 12G、Oracle 至少 10G,实际建议直接给 100G

一次性跑完的写法:

#!/bin/bash # 两个节点各跑一遍,输出重定向到 /root/precheck_$(hostname).log echo "== 内存 ==" ; grep MemTotal /proc/meminfo echo "== Swap ==" ; grep SwapTotal /proc/meminfo echo "== 运行级别 ==" ; runlevel echo "== 内核 ==" ; uname -mr echo "== 发行版 ==" ; cat /etc/redhat-release echo "== /tmp ==" ; df -h /tmp echo "== /dev/shm ==" ; df -h /dev/shm ; mount | grep shm echo "== u01 ==" ; df -h /u01

脚本本身没有技巧,价值在于「一次性留档」。Swap 那条规则要特别注意后半句:如果规划了 32G 大页给 SGA,Swap 的计算基数就不再是物理内存,而是内存减去大页占用后的剩余部分。这一条在手册里写在表格备注里,很容易被当成废话略过,但它直接决定后面的vm.nr_hugepages能开多大。

2.2 Preinstall RPM 与手工 sysctl 的两条路

19c 的内核参数有两条路:用预安装包自动配,或者全部手工写。两条路的产物是一样的,区别在于可控性和可审计性。

预安装包这条路最短:

# 挂上发行版官方的预安装源之后,一条命令搞定用户、组、sysctl、limits yum install -y oracle-database-preinstall-19c

它替你做的事包括:创建oracle用户、创建oinstall(oinstall)与dba(OSDBA)组、写/etc/sysctl.conf相关条目、写用户级 hard/soft 资源限制、设置numa=off。省事,但有两个副作用要知道:一是它写的 sysctl 落在/etc/sysctl.d/99-*这类文件里,优先级很高,后面手工加的 drop-in 如果编号更小会被它盖掉;二是numa=off是通用建议,在 NUMA 拓扑比较规整的新机器上是否关闭,建议先跟业务侧确认,别默认接受。

手工这条路适合要把参数纳入配置管理的场景:

# 单独一个 drop-in,编号 97 是为了让它在 99 之前加载,被覆盖时容易发现 cat > /etc/sysctl.d/97-oracledatabase-sysctl.conf <<'EOF' fs.aio-max-nr = 1048576 fs.file-max = 6815744 kernel.shmall = 2097152 kernel.shmmax = 4294967295 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 EOF # 让 drop-in 立即生效,不要用 sysctl -p 只读 /etc/sysctl.conf sysctl --system

参数里真正需要动脑子的是两个:

kernel.shmall的单位是页,按 4K 页算,2097152 页正好是 8G。如果你的 SGA 规划超过 8G,这一项必须同步放大,否则实例启动会报共享内存分配失败。kernel.shmmax的 4294967295 约等于 4G 减 1 字节,是 32 位时代的遗留默认值,64 位机器上物理内存大时按「不小于 SGA 大小」重新给,通常设成物理内存的一半或更大更稳妥。

net.ipv4.ip_local_port_range从默认的 32768 起改成 9000 起,是为了给 Oracle 的本地连接留出低位端口段,避免和监听、集群心跳抢端口。手册里还额外给了直接写/proc再重启网络的写法,那种方式重启即失效,只适合临时验证,不建议留在脚本里。

改完必须验:

sysctl -a | grep -E 'shm|sem|aio|file-max'

2.3 THP 关不掉的根因在 grub2-mkconfig 的路径

透明大页是 19c 安装里最经典的玄学问题。先确认状态:

cat /sys/kernel/mm/transparent_hugepage/enabled cat /sys/kernel/mm/transparent_hugepage/defrag

输出形如[always] madvise never,方括号落在always上,说明开着。两个文件都要看,defrag管的是碎片整理,只关enabled不关defrag,照样会有周期性卡顿。

关闭动作本身只有一行内核参数,但要落到正确的位置:

# 先备份,出事能回滚 cp /etc/default/grub /etc/default/grub.bak.$(date +%F) # 在 GRUB_CMDLINE_LINUX 的引号内最前面插入参数,注意保留原有内容和一个空格 sed -i 's/^GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="transparent_hugepage=never /' /etc/default/grub grep GRUB_CMDLINE_LINUX /etc/default/grub

然后按固件类型重建配置文件,这一步选错路径是最常见的失败原因:

# BIOS 引导 grub2-mkconfig -o /boot/grub2/grub.cfg # UEFI 引导,注意目录随发行版不同可能是 redhat / centos / oracle grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg shutdown -r now

重启后三重验证,少一步都可能骗自己:

cat /proc/cmdline # 能看到 transparent_hugepage=never cat /sys/kernel/mm/transparent_hugepage/enabled # 应为 [never] cat /sys/kernel/mm/transparent_hugepage/defrag # 应为 [never]

sed那一行如果GRUB_CMDLINE_LINUX原本有内容,插入后是"...never rd.lvm.lv=..."的形式,参数之间靠空格分隔,多一个少一个空格都可能让某个参数失效。改完不重启就去看/sys目录是没意义的,那些文件反映的是当前内核的运行时状态,只有/proc/cmdline才代表下次启动生效的配置。手册里提到可以用 grubby 补充完成剩余步骤,grubby --update-kernel=ALL --args="transparent_hugepage=never"是等效做法,适合批量脚本。

2.4 HugePages 数量与 memlock 的联动算式

THP 关掉之后才轮到 HugePages,两者是互斥的:前者是内核自动合页,后者是预分配的固定大页,同时开等于白配。

数量怎么算,手册给的思路是按 SGA 总量反推,我把它写成可执行的算式:

  • 单节点上所有实例的 SGA 之和,加上 GIMR 占用的部分。19c 的 Standalone Cluster 安装里 GIMR 已经变成可选项,选了就要多算 1G;Domain Service Cluster 必须配 GIMR,这 1G 一定要计进去。
  • 页大小固定 2M,nr_hugepages = ceil(SGA_MB / 2) + 余量,余量一般给 5%~10%。

举例:每节点一个 RAC 实例 SGA 12G,加 GIMR 1G,合计 13G,13000/2 = 6500 页,加 5% 余量取 6900。

# 写入并立即分配 echo "vm.nr_hugepages = 6900" >> /etc/sysctl.conf sysctl -p grep -i huge /proc/meminfo

紧接着是最容易漏的一环——memlock必须跟上。单位是 KB,算式是nr_hugepages * 2048:

cat >> /etc/security/limits.conf <<'EOF' oracle soft memlock 14131200 oracle hard memlock 14131200 grid soft memlock 14131200 grid hard memlock 14131200 EOF

grid那两行经常被漏掉。19c 里 Grid Infrastructure 的属主是grid,ASM 实例的 SGA 同样走大页,只给oracle配 memlock,gridSetup.sh阶段就会因为无法锁定内存而退出。memlock 小于大页总占用时,典型报错是ORA-27102: out of memory或启动时提示无法锁定内存,看到这两个别去查内存够不够,先查这两个数。

还有一个顺序问题:大页需要在物理内存还比较连续的时候分配。装完一堆东西、跑了一堆进程之后再sysctl分配,很可能只拿到一部分。稳妥做法是把vm.nr_hugepages写进配置后重启,重启完立刻看HugePages_Total与HugePages_Free是否等于设定值。

3. GNS 代管 SCAN:bind 正反解域与子域委托的四处关键配置

网络这一章是整份手册里信息密度最高的部分。固定配置人人会做,GNS 托管 VIP 和 SCAN 的配法就不是了——它要求你同时理解 DNS 的区域委托和 19c 集群的地址分配逻辑,少一环就是校验不过或者装完地址乱飘。

3.1 先定网络模型:全固定还是 GNS 加固定

手册给了两种模型,选之前先把下面这几条硬规则对一遍,它们不是建议,是安装器的前置断言:

  • 全 IPv4 或全 IPv6,不能混着来。GNS 可以生成 IPv6 地址,但集群内部不能一半一半。
  • VIP 要么所有节点都配,要么一个都不配。从 18c 起 VIP 对 Clusterware 是可选的,但不支持只给部分节点配 VIP。
  • Private 最多四个物理接口做 HAIP,超过四个的部分自动变成冗余,不做负载。Private 侧可以不配 bond,集群自己会做高可用,这一点跟很多人的直觉相反。
  • Public、VIP 的名字只能用字母、数字和连字符,下划线是不允许的,SCAN 名同理。
  • Public、VIP、SCAN VIP 必须在同一个子网段。

两种模型的差别可以摊开看:

项目全固定配置GNS 加固定配置
Public各节点网卡固定 IP各节点网卡固定 IP
Private手工固定可交给 GNS 分配
VIP安装器里手工指定GNS 动态分配
SCANDNS 三条 A 记录DNS 三条 A 记录,同时把子域委托给 GNS
适用场景节点少、IP 规划稳定节点多、后续频繁扩缩

关键前提在于:GNS 要真正「分配」地址,背后必须有 DHCP。手册里说得很直白,配合 DHCP 才能让 VIP、Private、SCAN 都由 GNS 发地址;没有 DHCP 时,GNS 只能承担解析职责,地址还是得事先规划好。这一点想清楚,就会明白为什么大多数两节点实验环境其实用全固定配置更省事,GNS 更多是为了验证这条路走得通。

3.2 hosts 只写该写的行

/etc/hosts里写什么、不写什么,是 GNS 场景下第一个坑。原则是:交给 GNS 管的地址,一行都不要写进 hosts。

cat >> /etc/hosts <<'EOF' # public,固定配置,必须写 192.168.204.11 pub19-node1.rac.example pub19-node1 192.168.204.12 pub19-node2.rac.example pub19-node2 # private,走固定配置时写;交给 GNS 时删掉 10.10.10.41 priv19-node1.rac.example priv19-node1-priv 10.10.10.42 priv19-node2.rac.example priv19-node2-priv # VIP 与 SCAN,交给 DNS/GNS 时不写 EOF

短名和长名都写在同一行,是因为安装器会用短名做节点间连通性检查,用长名做 SCAN 和 VIP 解析,少一个都可能在校验阶段报名字解析失败。反过来,如果 VIP 也写进 hosts,getent hosts会先命中 hosts 再查 DNS,GNS 分配的地址就形同虚设,后续排查时表现为 VIP 反复漂移或者 ping 到的地址跟srvctl config vip显示的不一致。

3.3 named.conf 的三个 zone

DNS 服务端用 bind,装包和启动没什么好说的:

yum install -y bind chroot systemctl enable --now named

配置的重点是三个区域:一个正解域,两个反解域(公网段一个、私网段一个):

options { directory "/var/named"; allow-query { any; }; # 测试期放开,生产建议限定网段 recursion yes; allow-transfer { none; }; # 禁止区域传送 }; zone "rac.example" IN { type master; file "named.rac.example"; }; zone "204.168.192.in-addr.arpa" IN { # 192.168.204.0/24 的反解 type master; file "named.192.168.204"; }; zone "10.10.10.in-addr.arpa" IN { # 10.10.10.0/24 的反解 type master; file "named.10.10.10"; };

正解文件里,SCAN 要三条 A 记录指向三个不同地址,这是 SCAN 能轮询的前提:

$TTL 600 @ IN SOA rac.example. admin.rac.example. ( 2024061201 ; serial,每次改动必须加一 1D ; refresh 1H ; retry 1W ; expire 3H ) ; minimum @ IN NS master master IN A 192.168.204.12 pub19-node1 IN A 192.168.204.11 pub19-node2 IN A 192.168.204.12 scan19.vip.rac.example. IN A 192.168.204.162 scan19.vip.rac.example. IN A 192.168.204.163 scan19.vip.rac.example. IN A 192.168.204.164 ; 子域委托:vip.rac.example 的解析权交给 GNS vip.rac.example. IN NS gns.rac.example. gns.rac.example. IN A 192.168.204.10

反解文件同样不能省,CVU 校验会正反双向查询,只配正解不配反解,典型报错是PRVF-4656或PRVG-1101,提示 SCAN 名称解析失败,但正解明明是通的,人很容易卡在这里:

$TTL 600 @ IN SOA rac.example. admin.rac.example. ( 2024061201 1D 1H 1W 3H ) @ IN NS master.rac.example. 11 IN PTR pub19-node1.rac.example. 12 IN PTR pub19-node2.rac.example. 162 IN PTR scan19.vip.rac.example. 163 IN PTR scan19.vip.rac.example. 164 IN PTR scan19.vip.rac.example. 10 IN PTR gns.rac.example.

改完不要急着重启,先用语法检查挡住低级错误,再验证正反解:

named-checkconf /etc/named.conf named-checkzone rac.example /var/named/named.rac.example named-checkzone 204.168.192.in-addr.arpa /var/named/named.192.168.204 systemctl restart named # 从集群节点上验证,一定要在客户端节点验证,本机测试会绕过网络路径 dig +short scan19.vip.rac.example A dig +short -x 192.168.204.162 getent hosts scan19.vip.rac.example

getent hosts这一步特别值得单独跑,它走的是 glibc 的解析顺序,跟 Oracle 实际用的路径一致。dig通而getent不通,说明问题在/etc/nsswitch.conf或 hosts 文件,不在 DNS。

3.4 子域委托与 gridSetup 里的三个填空

子域委托的作用是:主 DNS 只负责rac.example这一层,凡是*.vip.rac.example的查询,一律转给 GNS 那个地址去答。这样 GNS 就能在不改动主区域的前提下,动态地给 VIP 分配名字。

委托要生效,需要两处对齐:

第一处是正解文件里那两行,vip.rac.example. IN NS gns.rac.example.声明委托,gns.rac.example. IN A 192.168.204.10给出 GNS 的地址。这两行缺任何一行,委托链就断了。

第二处是gridSetup.sh里的三个填空,必须跟 DNS 侧严丝合缝:

  • SCAN 名称:必须是scan19.vip.rac.example,也就是必须落在被委托出去的那个子域之下。写成scan19.rac.example就跑到主区域去了,GNS 管不到。
  • GNS VIP:192.168.204.10,跟正解文件里gns.rac.example的 A 记录一致。
  • GNS 子域:vip.rac.example,不带末尾的点,也不带前面的星号。

这三处任何一个写错,安装器会在网络校验那一屏卡住,报 GNS 相关校验失败,但错误信息往往只说「无法验证」,不会直接告诉你哪个字段错了。我的做法是先把dig和getent的结果留档,再回去比对这三个字段,比反复重跑安装器快得多。

另外一个容易忽略的细节:DNS 和 GNS 所在节点的时间必须跟集群节点一致。时间偏差过大时,named的日志里会出现跟签名、缓存相关的告警,间接影响解析稳定性。下一章会把时间同步的配法一起讲掉。

4. 存储与

本文还有配套的精品资源,点击获取