Oracle 19c RAC Linux 7.6安装配置与避坑指南
简介:《Oracle 19c RAC on Linux 7.6安装手册》面向需要在 Red Hat Enterprise Linux 7.6 上部署 Oracle 19c RAC 的数据库管理员与运维工程师,重点解决集群安装、GNS 配置 SCAN、Flex ASM 使用及故障分析等实际问题。文档为 1 个 docx 文件,压缩包约 160KB,篇幅集中,便于随查随用。内容从 OS 环境检查入手,覆盖关闭 THP 与开启 Hugepages、软件包安装、内核参数配置、CVU 检查、固定网络与 GNS 结合配置、时钟同步等环节,并梳理 12.2 之后 Standalone Cluster 与 Domain Service Cluster 两种集群模式的差异,兼及版本变化和配置遇阻时的排查思路。已有 719 人学习,适合希望系统掌握 19c RAC 在 Linux 7.6 上落地方法、对照实验环境查漏补缺的读者。
1. 装 19c RAC Linux 7.6 前,先把三件小事确认掉
上个月收拾一套 19c RAC Linux 7.6 的现场,Grid 安装跑到七成多卡死,日志里全是 ASM 磁盘发现超时。翻回去看:THP 开着,hugepages 给了但 memlock 还是默认 64K,重启过一次却没看 /proc/cmdline。这套组合我装过很多遍,版本卡得很死——Oracle Linux 7.4 起(UEK4 4.1.12 或 UEK5 4.14.35),或者 RHEL 7.4 起(3.10.0-693.5.2.0.1.el7 以上),项目里落的是 Red Hat 7.6。往下读能拿到环境核对表、软件包与内核参数两条配置路线、THP 与大页、四个网段的 DNS 与 GNS 委托、UDEV 绑盘,以及装崩之后的排查顺序。第一次搭两节点集群的人能用,从 11g 迁到 19c、被 Standalone Cluster 和 Domain Service Cluster 绕晕的人也能用。
2. 系统底座:Linux 7.6 上的软件包、内核参数与 CVU 自检
底座这一段最枯燥,也最容易被跳过。很多人拿到介质就直接./gridSetup.sh,跑到 ASM 那一步报磁盘发现失败,再回头补内核参数,补完不重启,重跑一遍还是失败。系统底座其实就四件事:装包、调参、关 THP 开大页、用 CVU 自检。四件事做完再碰图形界面,后面能省掉大量来回。这一章按顺序把这四步走完,每一步都给可抄的命令和参数解释。
2.1 开工前的七项核对
先把机器的底子摸清楚,别等装到一半才发现内存不够或者内核版本偏低。19c 对两节点的最低要求不算高,但要求踩线的地方特别多,差一点就是安装程序中途退出。
| 检查项 | 要求 | 检查命令 |
|---|---|---|
| 内存 | 至少 8G | grep MemTotal /proc/meminfo |
| 运行级别 | 3 或 5 | runlevel |
| 内核版本 | RHEL 7.4 起 3.10.0-693.5.2.0.1.el7 以上;OL7 用 UEK4 4.1.12-112.16.7 或 UEK5 4.14.35-1818.1.6 | uname -mr |
| /tmp | 至少 1G | df -h /tmp |
| SWAP | 4G~16G 之间等于 RAM;超过 16G 给 16G;开了大页要减掉分给大页的那部分 | grep SwapTotal /proc/meminfo |
| /dev/shm | tmpfs 挂载,权限正常 | df -h /dev/shm |
| 软件空间 | grid 至少 12G,Oracle 至少 10G,实际按 100G 预留 | df -h /u01 |
# 内存和 swap 一次看全,单位 kB,换算成 G 再对照上表 grep -E 'MemTotal|SwapTotal' /proc/meminfo # 运行级别,3 和 5 都行,别停在 4 runlevel # 内核版本与发行版,两个都要看,RHEL 和 OL 的判断路径不一样 uname -mr cat /etc/redhat-release # /tmp 和 /dev/shm,后者要注意挂载类型必须是 tmpfs,权限不能是 700 df -h /tmp /dev/shm # 软件安装目录,十九八稳地给到 100G,19c 的 GI 家目录本身就不小 df -h /u01swap 这条规则有个反直觉的地方:开了 HugePages 之后,swap 的计算基数要减去大页占掉的内存。比如 32G 内存、划了 16G 给大页,剩下的部分按 16G 那条规则走,实际 swap 给到 16G 就够了,不必按 32G 再往上堆。
提示:
/dev/shm的大小在 dbca 建库阶段很关键,小于 1G 时建库容易在中途失败。RHEL 7 默认给的是内存的一半,一般够用,但容器里或者被人手工改过就要单独确认。
2.2 软件包:preinstall RPM 与 RHEL 7 必需清单
装包有两条路。第一条是用 Oracle 提供的 preinstall RPM,一条命令把用户、组、内核参数、资源限制全带出来;第二条是全手工,适合不能连外网、或者对系统参数有自己一套标准的场景。两条路的最终结果要一致,别混着来。
# 配好源之后直接装 preinstall 包,RHEL 上找不到就换成对应的等效包 cd /etc/yum.repos.d/ wget http://yum.oracle.com/public-yum-ol7.repo yum repolist yum install -y oracle-database-preinstall-19c这个包做的事情有五项:创建 oracle 用户;创建 oraInventory 对应的 oinstall 组和 OSDBA 对应的 dba 组;写 sysctl 建议值;写 hard/soft 资源限制;顺手把 numa 关掉。它省事,但不是万能的——装完之后还要自己核对一遍,尤其是已经存在的 oracle 用户它不会改属性,/etc/security/limits.conf里已有的同名条目也可能打架。
如果走手工路线,下面这份 RHEL 7 的包清单一个都不能少。漏掉compat-libcap1或ksh,后面 root.sh 执行到一半会报错退出;漏掉libaio-devel,ASM 那一步直接起不来。
| 分类 | 包名 |
|---|---|
| 基础工具 | openssh、bc、binutils、make、ksh、smartmontools、sysstat |
| 兼容库 | compat-libcap1、compat-libstdc++、libgcc、libstdc++、libstdc++-devel |
| 系统库 | glibc、glibc-devel、libaio、libaio-devel、elfutils-libelf、elfutils-libelf-devel |
| 图形库 | libX11、libXau、libXi、libXtst、libXrender、libXrender-devel、libxcb、fontconfig-devel |
| 网络与存储 | net-tools(RAC 与 Clusterware 需要)、nfs-utils(ACFS 需要)、librdmacm-devel |
| ACFS Remote | python、python-configshell、python-rtslib、python-six、targetcli |
# 一次性装齐,缺哪个补哪个,rpm -q 逐个确认比事后看日志快得多 yum install -y openssh bc binutils compat-libcap1 compat-libstdc++ \ elfutils-libelf elfutils-libelf-devel fontconfig-devel glibc glibc-devel \ ksh libaio libaio-devel libX11 libXau libXi libXtst libXrender \ libXrender-devel libgcc librdmacm-devel libstdc++ libstdc++-devel \ libxcb make net-tools nfs-utils smartmontools sysstat # ACFS Remote 用到的三个 python 包,不做 ACFS 可以不装 yum install -y python python-configshell python-rtslib python-six targetcli # 装完扫一遍,任何一个 missing 都要处理掉再往下走 for p in bc binutils compat-libcap1 ksh libaio-devel net-tools nfs-utils; do rpm -q $p >/dev/null 2>&1 || echo "missing: $p" done除了这份清单,还有几个可选组件按需装:PAM、OCFS2、ODBC、LDAP。不用就别装,装了反而会引入额外的依赖链,出问题时排查面变大。
2.3 手工写 97-oracledatabase-sysctl.conf:每个值在管什么
preinstall 包会写一份 sysctl 配置,但如果机器上已经有别的服务在跑,最好把 Oracle 相关的参数单独落到一个文件里,文件名带排序前缀,避免被后面的文件覆盖。/etc/sysctl.d/下的文件按名字排序加载,97-这个前缀就是为了排在系统默认配置之后。
vi /etc/sysctl.d/97-oracledatabase-sysctl.conf 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逐个说清楚这几个值在管什么,改的时候才知道能不能动:
fs.aio-max-nr:异步 IO 请求上限。ASM 和数据库都吃这个,1048576 是给的推荐值,改小会在高并发下报 IO 错误。fs.file-max:系统级文件句柄上限。这个值是全局的,进程级的要在 limits.conf 里单独给。kernel.shmall、kernel.shmmax、kernel.shmmni:共享内存的总页数、单段最大值、段数上限。shmmax这个 4294967295 是 32 位时代留下的经典值,64 位机器上实际可以按内存的一半给,但没有特殊需求就别改,改了要连带核对 shmall。kernel.sem:信号量,四个数分别是 SEMMSL、SEMMNS、SEMOPM、SEMMNI。这个值给少了,数据库起实例时会报ORA-27154,是典型的血泪经验。net.ipv4.ip_local_port_range:本地端口范围 9000~65500。把低端口段让出来,避免和监听器抢端口,也让 SCAN 的端口分配有空间。net.core.rmem/wmem四项:网络收发缓冲区。RAC 的节点间心跳走私有网络,缓冲区给够能减少 Cache Fusion 的抖动。
# 让上面这份配置立刻生效,注意是 --system 不是 -p,前者会扫描整个目录 /sbin/sysctl --system # 验证,重点看 shmmax 和 sem 有没有被别的文件覆盖回去 /sbin/sysctl -a | grep -E 'shmmax|shmall|sem|aio-max-nr' # 端口范围单独确认一次,这个值被改回去的情况最多 cat /proc/sys/net/ipv4/ip_local_port_range注意:如果 preinstall RPM 已经写过一份 sysctl 配置,手工这份会覆盖它。两边同时改的时候,加载顺序决定最终值,用
sysctl -a逐项核对比看文件可靠。
2.4 一次重启才生效的 THP 与大页
透明大页在现代数据库上基本是负收益,RAC 场景尤其明显——它会在运行时整理内存碎片,引发不可预测的停顿,而这类停顿在集群环境里会被放大成节点驱逐。关掉它需要改内核启动参数,意味着必须重启。
# 看当前状态,方括号在哪个值上就是当前值 cat /sys/kernel/mm/transparent_hugepage/enabled cat /sys/kernel/mm/transparent_hugepage/defrag # 备份一份,改坏了能退回去 cp /etc/default/grub /etc/default/grub.bak # 在 GRUB_CMDLINE_LINUX 末尾追加参数,注意保留原有的内容 vi /etc/default/grub # GRUB_CMDLINE_LINUX="rd.lvm.lv=rhel/root rd.lvm.lv=rhel/swap ... transparent_hugepage=never" # 重建引导配置,BIOS 和 UEFI 的路径不一样,这条最容易写错 grub2-mkconfig -o /boot/grub2/grub.cfg # BIOS 机器 grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg # UEFI 机器 # 重启之后必须验证,这一步跳过就等于没做 shutdown -r now cat /proc/cmdline/proc/cmdline里能看到transparent_hugepage=never才算真正生效。UEFI 机器上如果只重建了/boot/grub2/grub.cfg,重启后参数不会出现在 cmdline 里,这是最常见的翻车点之一——文件重建成功了,但引导读的是另一个。
大页单独配置,跟 THP 是两回事。计算方式是:先确定 SGA 大小,按 2M 一个页向上取整,再加上 GIMR 的部分。19c Standalone Cluster 里 GIMR 变成了可选项,如果选择配置,它自己要吃掉 1G 左右的大页;Domain Service Cluster 模式下 GIMR 是必须的,这 1G 躲不掉。
# 假设 SGA 24G,2048 个 2M 页是 4G,明显不够,要按 SGA + GIMR 算 vi /etc/sysctl.conf vm.nr_hugepages = 13056 sysctl -p # memlock 给到足量,单位是 KB,要比大页总量大 vi /etc/security/limits.conf oracle soft memlock 26738688 oracle hard memlock 26738688 # 验证大页分配情况,HugePages_Total 和 Free 要接近 grep Huge /proc/meminfomemlock 给少了的表现很隐蔽:数据库能起来,但 SGA 只能用普通页,性能测试跑出来的数字怎么看都不对。查ipcs -m里段的属性,或者直接看/proc/meminfo的 HugePages_Free 有没有下降,能确认大页到底有没有被用上。
2.5 cvuqdisk 与 runcluvfy:装之前先让工具挑刺
CVU 是集群验证工具,能在正式安装前把不满足的条件列出来。它依赖一个叫 cvuqdisk 的 RPM,这个包不在系统源里,在 Grid 安装介质的cv/rpm目录下。
# 先看有没有旧版本,有就卸掉,版本不匹配会导致校验结果失真 rpm -qi cvuqdisk rpm -e cvuqdisk # 指定包属组,通常是 oinstall export CVUQDISK_GRP=oinstall # 每个节点都要装,版本必须一致 rpm -iv cvuqdisk-1.0.10-1.rpm # 跑预检查,-fixup 会尝试自动修复能修的部分 ./runcluvfy.sh stage -pre crsinst -fixup -n node1,node2,node3-pre crsinst指定的检查阶段是集群软件安装前,-fixup让工具对可修复项直接动手,-n后面跟节点名,用逗号分隔。这条命令跑完,输出里会分条列出通过和失败项,失败项里有一部分是误报——比如它检测到某些包版本比预期新,实际不影响。真正要处理的是内存、swap、内核参数、包缺失、DNS 解析这几类,剩下的可以先记下来,等安装过程中真报错了再回头看。
提示:cvuqdisk 装完之后,同一个集群的所有节点版本必须完全一致。曾经过一次只在一个节点升级了 cvuqdisk,runcluvfy 在两节点对比阶段报了一堆莫名其妙的错,查了半天才发现是包版本不一致。
3. 网络与 DNS:Public/VIP/Private/SCAN 四个地址段与 GNS 委托
RAC 装不上,网络问题占的比例比内核参数还高。19c 的网络配置有几条硬规则,违反了安装程序不会给你解释,只会告诉你某个校验失败。这一章先把地址段分清楚,再把 bind 的正解反解读写明白,最后处理 GNS 的子域委托——那两行 NS 记录是整套配置里最容易被忽略、也最容易出错的地方。
3.1 四个地址段先分清楚
19c 要求要么全 IPv4,要么全 IPv6,不能混着来。GNS 能生成 IPv6 地址,但混合环境在很多环节会出问题,没有特殊需求就用纯 IPv4。
| 地址类型 | 数量 | 配置方式 | 备注 |
|---|---|---|---|
| Public | 每节点一个 | 固定在物理网卡 | 名称只允许字母数字和-,不允许下划线 |
| Private | 每节点一个或多个 | 固定或 GNS 分配 | 最多四个 interface 参与 HAIP,超出的自动作为冗余 |
| VIP | 每节点一个 | 固定解析或 GNS 分配 | 18c 起可选,但要么全配要么全不配 |
| SCAN VIP | 三个 | DNS 轮询解析 | 必须和 Public/VIP 在同一子网 |
| GNS VIP | 一个 | 固定 | 只有用 GNS 托管时才需要 |
几条容易踩的规则单独拎出来:VIP 从 18c 开始可以不给,但只给部分节点配 VIP 是不支持的,要么全给要么全不给;Private 网络不需要做 bond 绑定,集群自己会做高可用;Public、VIP、SCAN VIP 必须在同一个子网段,跨网段安装程序直接拒绝。
# /etc/hosts 示例,域名用 rac.lab,实际替换成自己的 vi /etc/hosts 192.168.204.11 pub19-node1.rac.lab 192.168.204.12 pub19-node2.rac.lab # private 40.40.40.41 priv19-node1.rac.lab 40.40.40.42 priv19-node2.rac.lab # vip 192.168.204.21 vip19-node1.rac.lab 192.168.204.22 vip19-node2.rac.lab # gns vip,只有用 GNS 托管时才需要 192.168.204.10 gns19-vip.rac.labSCAN 的三个地址不要写进 hosts,它必须通过 DNS 轮询解析出来,写死在 hosts 里就失去了 SCAN 的意义,客户端也没法做负载均衡。这一点在装完之后用nslookup验证,能连续返回三个不同地址才算对。
3.2 bind 正解反解:named.conf 与两个 zone 文件
DNS 服务用 bind 就够,装包很简单,配置要仔细。正解负责域名到 IP,反解负责 IP 到域名,两个都要,缺一个安装程序会在 SCAN 校验那一关卡住。
yum install -y bind chroot vi /etc/named.conf options { directory "/var/named"; dump-file "/var/named/data/cache_dump.db"; statistics-file "/var/named/data/named_stats.txt"; memstatistics-file "/var/named/data/named_mem_stats.txt"; allow-query { any; }; # 生产上收窄到一个网段,别真的 any recursion yes; allow-transfer { none; }; # 不允许区域传送 }; zone "." IN { type hint; file "named.ca"; }; zone "rac.lab" IN { # 正解域 type master; file "named.rac.lab"; }; zone "204.168.192.in-addr.arpa" IN { # 公网段反解,注意网段倒着写 type master; file "named.192.168.204"; }; zone "40.40.40.in-addr.arpa" IN { # 私有网段反解 type master; file "named.40.40.40"; };反解 zone 的名字是把 IP 段倒过来写再拼.in-addr.arpa,192.168.204 这个段就写成204.168.192.in-addr.arpa。这个顺序写反了 bind 起不来,日志里报 zone not loaded,看着像文件问题,实际是 zone 名错了。
正解域文件里除了常规的 A 记录,还要有两行给 GNS 用的 NS 记录,这个下面单独讲。
vi /var/named/named.rac.lab $TTL 600 @ IN SOA rac.lab. admin.rac.lab. ( 0 ; serial 1D ; refresh 1H ; retry 1W ; expire 3H ) ; minimum @ IN NS master master IN A 192.168.204.12 scan19.vip.rac.lab. IN A 192.168.204.162 scan19.vip.rac.lab. IN A 192.168.204.163 scan19.vip.rac.lab. IN A 192.168.204.164 priv19-node1.rac.lab. IN A 40.40.40.41 priv19-node2.rac.lab. IN A 40.40.40.42 vip19-node1.rac.lab. IN A 192.168.204.21 vip19-node2.rac.lab. IN A 192.168.204.22 pub19-node1.rac.lab. IN A 192.168.204.11 pub19-node2.rac.lab. IN A 192.168.204.12 vip.rac.lab. IN NS gns.rac.lab. gns.rac.lab. IN A 192.168.204.10反解文件相对简单,每个 IP 一条 PTR 记录,公网段和私有段各写一份:
vi /var/named/named.192.168.204 $TTL 600 @ IN SOA rac.lab. admin.rac.lab. ( 10 ; serial 3H ; refresh 15M ; retry 1W ; expire 1D ) ; minimum @ IN NS master.rac.lab. 12 IN PTR master.rac.lab. 33 IN PTR scan19-vip.rac.lab. 34 IN PTR scan19-vip.rac.lab. 35 IN PTR scan19-vip.rac.lab. 21 IN PTR vip19-node1.rac.lab. 22 IN PTR vip19-node2.rac.lab. 11 IN PTR pub19-node1.rac.lab. 12 IN PTR pub19-node2.rac.lab.写完之后/etc/resolv.conf指向本机,named-checkzone校验两个文件,systemctl restart named重启,再用nslookup正查反查各来一次。反查失败不影响安装,但会影响后面集群日志的可读性,出问题时全是一堆 IP 没有主机名,排查成本陡增。
3.3 GNS 委托:最后两行 NS 记录决定成败
GNS 是 Grid Naming Service,它接管一个子域的解析,VIP、Private IP、SCAN 都可以交给它分配。要用它,DNS 这边必须做一件事:把某个子域委托给 GNS 服务器。这两行就是上一节正解文件末尾的:
vip.rac.lab. IN NS gns.rac.lab. # 子域 vip.rac.lab 的解析交给 gns.rac.lab gns.rac.lab. IN A 192.168.204.10 # gns.rac.lab 自己的地址意思很直白:凡是xxx.vip.rac.lab的查询,都转给 192.168.204.10 这台机器处理。所以 SCAN 的名字必须落在这个被委托的子域下面——scan19.vip.rac.lab里包含vip.rac.lab,符合要求;如果写成scan19.rac.lab,就在父域里,GNS 管不到,安装时 SCAN 校验会失败。
gridSetup 图形界面走到 GNS 那一步,要填两个值:GNS 的 VIP 地址填192.168.204.10,子域填vip.rac.lab。这两个值和 DNS 里的 NS 记录必须严格对应,错一个字符都不会生效。如果同时配了 DHCP,VIP、Private、SCAN 的地址分配可以全部交给 GNS 完成,节点上只需要固定 Public IP。
注意:不动 GNS、只做固定配置的时候,
/etc/hosts和 DNS 里都别留那两行 NS 记录,否则解析会绕道去一个不存在的 GNS 服务,表现是 SCAN 时好时坏地解析失败,排查起来非常费劲。
3.4 固定解析还是 GNS 托管:一张取舍表
两种方案都能跑通,选哪个取决于环境里有没有 DHCP、节点规模会不会变。
| 对比项 | 固定配置 | GNS + 固定配置 |
|---|---|---|
| 配置复杂度 | 低,全在 hosts 和 DNS 里 | 高,多一层子域委托 |
| 扩容时改什么 | 手工加 hosts 和 DNS 记录 | GNS 自动分配,改得少 |
| 故障排查 | 直接看 hosts 和 zone 文件 | 多一个 GNS 服务要查 |
| 适合场景 | 节点数固定、没有 DHCP | 节点多、频繁扩缩容 |
两节点的环境我一般选固定配置,简单直接,出问题一眼能看到根上。要上三节点以上、还打算做后续扩容,GNS 的价值才体现出来。
4. 装到图形界面之前:时钟、limits、UDEV 与 gridSetup 的执行顺序
系统参数和网络都通了,接下来是那些「不做也能装,装完出问题很难查」的杂项。这一章把它们一次处理干净,然后按顺序走完 gridSetup、root.sh、runInstaller 和 dbca。
4.1 时钟同步、SSH 超时与 IO 调度
集群节点之间的时间差不能大,否则 OCR 写入和各种心跳判断都会出问题。RHEL 7 上直接用 chrony,两个节点都指向同一个时间源。
# 两个节点都装,都配同一个上游 yum install -y chrony vi /etc/chrony.conf # server <时间源地址> iburst systemctl enable chronyd systemctl start chronyd # 确认同步状态,Leap status 要是 Normal chronyc trackingSSH 超时限制是另一个容易被忽略的点。安装过程中有大量节点间的 SSH 调用,如果服务端的 ClientAliveInterval 设得比较激进,长时间操作会被中断,报出来的错误和实际原因对不上。
vi /etc/ssh/sshd_config # ClientAliveInterval 300 # ClientAliveCountMax 3 systemctl restart sshdIO 调度器按存储介质选:SSD 上用none或noop,机械盘上用deadline。这个设置不改也能装,但 ASM 的响应延迟会有差异,性能测试时会体现出来。临时改用/sys/block/<盘>/queue/scheduler,永久生效要写 udev 规则或 tuned profile。
4.2 用户、组、目录与 limits.conf
如果用了 preinstall RPM,用户和组已经建好了,这里只需要核对。手工路线的话,组要建全:oinstall、dba、asmadmin、asmdba、asmoper、oper 这几个,缺了后面安装程序会让你现补。
# 核对组和用户 id oracle grep -E 'oinstall|dba|asmadmin|asmdba|asmoper' /etc/group # 目录和权限,grid 和 oracle 的家目录都放在 /u01 下 mkdir -p /u01/app/grid /u01/app/oracle /u01/app/oraInventory chown -R grid:oinstall /u01/app/grid chown -R oracle:oinstall /u01/app/oracle chown -R grid:oinstall /u01/app/oraInventory chmod -R 775 /u01/applimits.conf里除了 memlock,还要给 nproc 和 nofile。nofile 给到 65536 起步,nproc 给 16384,这两个值给小了,集群起来之后进程数一多就开始报错,而且报错信息不会指向 limits。
vi /etc/security/limits.conf oracle soft nproc 16384 oracle hard nproc 16384 oracle soft nofile 65536 oracle hard nofile 65536 oracle soft memlock 26738688 oracle hard memlock 26738688 grid soft nproc 16384 grid hard nproc 16384 grid soft nofile 65536 grid hard nofile 65536 grid soft memlock 26738688 grid hard memlock 26738688提示:改完 limits 要用 oracle 或 grid 用户重新登录再
ulimit -a验证,su 过去不算,会话没重建的话读到的还是旧值。
4.3 UDEV 固定 ASM 磁盘名
ASM 磁盘的设备名必须稳定,/dev/sdb这种名字重启一次就可能变。用 UDEV 按磁盘 WWID 绑一个固定名字,是 19c 环境里最省心的做法。
# 取磁盘 WWID,每块盘都要取,记下来 /sbin/scsi_id -g -u -d /dev/sdb # 写规则文件,RESULT 里填上面取到的 WWID vi /etc/udev/rules.d/99-oracle-asmdevices.rules KERNEL=="sd*", SUBSYSTEM=="block", PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/$name", RESULT=="36000c29a1b3f4e5d8c7a6b5e4d3c2b1a", SYMLINK+="asm-disk1", OWNER="grid", GROUP="asmadmin", MODE="0660" # 重新加载规则并触发 udevadm control --reload-rules udevadm trigger --type=devices --action=change # 验证,权限要是 brw-rw---- grid asmadmin ls -l /dev/asm-disk*PROGRAM那一段在不同发行版上路径略有差别,RHEL 7 是/usr/lib/udev/scsi_id,老版本在/sbin。路径写错的表现是软链接根本不生成,规则文件本身看不出问题。每块盘一条规则,WWID 和软链接名一一对应,别复制粘贴之后忘了改。
4.4 gridSetup.sh、runInstaller 与 dbca 的先后
顺序不能乱:先 Grid Infrastructure,两个节点都跑完 root.sh,再装数据库软件,最后建库。
# 用 grid 用户执行,图形界面下跑 # RHEL 上偶尔遇到发行版识别问题,常见做法是先设这个环境变量 export CV_ASSUME_DISTID=OEL7.6 ./gridSetup.shgridSetup 走完配置摘要,会在最后提示在两个节点上分别执行 root.sh。第一个节点执行完再执行第二个,顺序反了会出现节点注册不一致。root.sh 输出很长,重点看最后几行有没有报错,中间的警告大部分可以忽略。
数据库软件用 oracle 用户跑runInstaller,装完同样要执行 root.sh。建库用dbca,RAC 模式选「Oracle Real Application Clusters」,实例数按节点数给。建库这一步耗时最长,中途别去动网络配置,否则会卡在实例注册阶段。
5. 避坑与排查:19c RAC 装到一半卡住的五个现场
装集群这件事,报错信息经常指向一个和真正原因隔了两层的地方。这一章记录五个实际遇到过的现场,按现象、原因、解决的顺序写,看到类似报错可以先对一遍。
5.1 THP 明明关了,cmdline 里却没有
现象:改完/etc/default/grub追加了transparent_hugepage=never,grub2-mkconfig也执行成功没有报错,重启之后cat /proc/cmdline里找不到这个参数,/sys/kernel/mm/transparent_hugepage/enabled还是[always]。
原因:机器是 UEFI 引导,但重建的是 BIOS 路径的/boot/grub2/grub.cfg。grub2-mkconfig 对不存在的输出路径不一定报错,命令看着成功,实际引导读的文件根本没更新。
解决:先用ls /sys/firmware/efi判断是不是 UEFI,目录存在就走/boot/efi/EFI/redhat/grub.cfg。改之前把原文件备份一份,重建之后用grep transparent /boot/grub2/grub.cfg或对应路径确认参数真的写进去了,再重启。
5.2 大页给了,SGA 还是走普通内存
现象:vm.nr_hugepages设了,/proc/meminfo里 HugePages_Total 也对,但数据库起来之后 HugePages_Free 几乎没降,性能测试的延迟比预期高一截。
原因:只配了vm.nr_hugepages,没配limits.conf里的 memlock。Oracle 进程拿不到锁定内存的权限,大页分配了但用不上,自动退回普通页。另一种情况是数值算少了,把 GIMR 那 1G 忘了算进去,19c 配了 GIMR 的环境特别容易漏。
解决:limits.conf里给 oracle 和 grid 都配 soft/hard memlock,数值按大页总量乘 1024 再留余量。改完必须重新登录会话,ulimit -l确认生效。大页数量按 SGA 加上 GIMR 的 1G 计算,Domain Service Cluster 模式下这 1G 躲不掉。
5.3 SCAN 校验过不去,提示名称无法解析
现象:gridSetup 走到网络配置那一步,SCAN 校验失败,提示名称解析不到或者返回的地址数量不对。手工nslookup有时能通有时不通。
原因:SCAN 名不在 GNS 委托的子域下面。比如委托的是vip.rac.lab,SCAN 写成了scan19.rac.lab,查询落到父域,GNS 管不到。或者反过来,不用 GNS 但/etc/hosts里留了 NS 委托记录,解析绕道去一个不存在的服务。
解决:SCAN 名必须包含被委托的子域,scan19.vip.rac.lab这种形式才对。不用 GNS 就把那两行 NS 记录删干净,SCAN 三个地址只放 DNS 不放 hosts。改完systemctl restart named,用nslookup scan19.vip.rac.lab连续查几次,能看到三个不同地址轮询返回才算过关。
5.4 runcluvfy 报一堆包缺失,装完却用不了
现象:preinstall RPM 装完,又手工往97-oracledatabase-sysctl.conf里写了一份参数,runcluvfy检查内核参数和实际值对不上,或者两边来回覆盖,sysctl -a的输出和文件里写的不是一回事。
原因:/etc/sysctl.d/下的文件按名字排序加载,preinstall 写的文件排序位置和手工文件不同,后加载的覆盖前面的。两个来源同时存在时,最终值取决于排序,不是取决于你最后改的那个文件。
解决:只用一套配置来源。要么全交给 preinstall,要么把 Oracle 相关参数集中到一个固定前缀的文件里,把 preinstall 写的同名项删掉。改完sysctl --system,用sysctl -a逐项核对,别只看文件内容。
5.5 root.sh 在第二个节点失败
现象:第一个节点 root.sh 跑完正常,第二个节点跑到一半报错退出,日志里提到集群注册或者 OCR 相关的内容。
原因:两个节点执行顺序反了,或者第一个节点的 root.sh 还没完全结束就开始第二个。也有可能是两边的 cvuqdisk 版本不一致,节点间校验对不上。
解决:严格按先 node1 后 node2 的顺序,第一个节点的 root.sh 看到明确结束提示再动第二个。执行前两个节点都rpm -q cvuqdisk确认版本一致。失败之后不要直接重跑,先看$GRID_HOME/cfgtoollogs下对应的日志,把残留配置清掉再重来,直接重跑往往会在同一个位置再挂一次。
6. 验证:跑完 dbca 之后怎么确认这套集群真的活着
建库完成不等于环境可用。图形界面最后一步显示成功,只说明安装程序把该做的事做完了,集群资源是不是真的在跑、SCAN 是不是真的轮询、故障切换是不是真的能触发,都要单独验一遍。这一步很多人省掉,等到业务上线才发现问题,排查成本翻好几倍。
先看集群层面的整体状态,资源树里每一项的状态都应该是 ONLINE,除了那些设计上就是 OFFLINE 的。
# 集群整体健康检查,两个节点都要返回 OK crsctl check cluster -all # 资源树,重点看 ora.LISTENER_SCAN1.lnsr 和各个 ASM 实例 crsctl stat res -t # 数据库实例状态,两个节点都应该是 OPEN srvctl status database -d ORCL # ASM 磁盘组,MOUNTED 状态、容量和冗余类型都要对 asmcmd lsdg然后验 SCAN 的轮询解析,这是客户端能不能连进来的关键:
# 连续查三次,应该返回三个不同的地址 nslookup scan19.vip.rac.lab nslookup scan19.vip.rac.lab nslookup scan19.vip.rac.lab <p> <a href="https://download.csdn.net/download/jwocnimabi/12237038" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>