简介:面向 Oracle 数据库运维与架构人员的安装手册,聚焦 Red Hat Enterprise Linux 7.6 环境下 Oracle 19c RAC 的部署与排错,适合具备一定 Linux 与集群基础、需要完成集群落地或梳理 GNS 配置 SCAN 的中高级读者。整包仅含 1 个 docx 文档,约 160KB,体积轻便但内容集中,可按目录快速定位操作系统检查、THP 关闭与 Hugepages 开启、软件包安装、内核参数配置、CVU 校验、网络固定配置及 GNS 加固定配置、时钟同步等关键环节。文档还延展到 Flex ASM、各版本变化,以及从 12.2 起 Standalone Cluster 与 Domain Service Cluster 两种集群模式的差异,并给出配置问题解决与分析思路。已有 719 人学习下载,适合用作搭建实验环境、核对实施步骤和沉淀故障排查方法的参考。
1. 19c RAC 装到 gridSetup 就停:多数人不是栽在数据库,是栽在 Linux 7.6 的预检查上
19c RAC Linux 7.6 安装最反直觉的地方在于:真正让人熬到凌晨的,几乎不是 gridSetup.sh 那几屏图形界面,而是它之前那一长串 PRVF 报错。十几个节点检查项一次刷屏,能追上滚屏的没几条,关掉窗口重来一次还是一样。我见过不止一个人在这里反复重装系统、把能想到的包全装一遍,结果第二天重启完,同一个报错又原样回来了——改的东西根本没落盘,或者被另一个配置文件覆盖掉了。这类故障的共同点是:报错文案含糊、根因散落在内核参数、limits、DNS 解析、udev 规则四五个层面,而且每次都要装到七八成才暴露。下面按我自己装机的实际顺序拆:预检查、网络与解析、ASM 磁盘、几个装完才发作的细节,最后给一套从日志里快速判断根因的路子。
2. 预检查报一长串 PRVF:OS 层没对齐,到 gridSetup 才暴露
gridSetup.sh 弹窗之前,安装器会先跑一遍 Cluster Verification Utility。这一关的报错全部以 PRVF / PRVG 开头,一次刷十几条,很多新手看到第一条就动手修,修完重跑发现还是同一批。原因是这批告警里大半是同一个根因派生出来的:THP 没关干净会连带出内存、HugePages、swap 的一串告警;limits 没生效会连带出文件描述符、进程数、memlock 的告警。正确的顺序是先看 OS 层三件事——大页与内存相关参数、用户资源限制、软件包与 sysctl,对齐之后再跑带-fixup的检查,剩下的才是真问题。
2.1 THP 看着关了,重启后又变回 always
透明大页面(THP)是 Oracle 在 Linux 上最经典的性能争议点,19c 的预检查会明确提示要关。最容易翻车的不是「不知道怎么关」,而是「以为已经关了」。先在节点上确认当前状态:
# 当前是否启用 THP,方括号框住的就是生效值 cat /sys/kernel/mm/transparent_hugepage/enabled # 碎片整理策略,同样要看方括号 cat /sys/kernel/mm/transparent_hugepage/defrag如果输出是[always] madvise never,说明 THP 正在全局启用。有的资料教用echo never > ...直接写,这条命令在本次运行期间确实有效,但重启后内核会按引导参数重新初始化,一切归零。真正要落盘的是引导参数:
# 先备份引导配置,改错了还能退回去 cp /etc/default/grub /etc/default/grub.bak.$(date +%F) # 只往 GRUB_CMDLINE_LINUX 这一行末尾追加,不要整行重写 grep -n '^GRUB_CMDLINE_LINUX=' /etc/default/grub在GRUB_CMDLINE_LINUX="..."的引号内、最后一个参数后面补上transparent_hugepage=never。改完必须重建引导配置文件,否则参数只停留在/etc/default/grub里,引导时读的还是旧的 grub.cfg:
# BIOS 引导的老机器 grub2-mkconfig -o /boot/grub2/grub.cfg # UEFI 引导,目标路径里的目录名按实际发行版调整 grub2-mkconfig -o /boot/efi/EFI/<distro>/grub.cfggrub2-mkconfig会把/etc/default/grub与/etc/grub.d/下的脚本合成最终配置并写入目标文件,-o后面跟的是实际被引导读取的那个 grub.cfg。重建完成后shutdown -r now重启,再验证:
# 从内核命令行确认参数真的传进去了 cat /proc/cmdline | tr ' ' '\n' | grep -i transparent # 从内核视角确认生效,AnonHugePages 应该接近 0 grep -i AnonHugePages /proc/meminfo cat /sys/kernel/mm/transparent_hugepage/enabled这里有两个血泪经验。一是某些加固基线或 tuned profile 会在开机脚本里重新写 THP,改完重启又变回 always,遇到这种情况要先tuned-adm active看看有没有 profile 在管,把[always]的写入源找出来,而不是反复改 grub。二是 UEFI 机器上把目标路径写成 BIOS 的/boot/grub2/grub.cfg,命令执行成功、没有任何报错,但引导读的根本不是这个文件,看上去「改完了」,实际完全没生效——这类假成功最容易骗人。
2.2 HugePages 与 memlock 不配对:内存够却报分配失败
THP 关掉之后,大页要接手。19c 的 SGA 走 HugePages,页数算少了数据库起不来,页数算多了内存被白白占住,机器上其他进程会开始 OOM。计算逻辑并不复杂:x86_64 上标准大页是 2MB 一页,用 SGA 大小除以 2 得到基础页数,再留 5% 左右余量。要注意的是 19c 的 Standalone 集群可以选配 GIMR,一旦启用,管理库的 SGA 还要额外吃掉一份内存,也要算进大页里。
# 按 SGA 16G + GIMR 1G 估算,留 5% 余量,结果向上取整 awk 'BEGIN{sga=16384; gimr=1024; printf "%d\n", int((sga+gimr)*1.05/2)}' # 看当前大页分配情况,HugePages_Total 是目标值,HugePages_Free 是没被用的 grep -i huge /proc/meminfo把算出来的数字写进 sysctl 配置文件,文件名带序号是为了保证加载顺序在系统默认配置之后:
# /etc/sysctl.d/99-oracle-hugepages.conf vm.nr_hugepages = 8909紧跟着是 memlock。大页内存要能锁定不被换出,oracle 和 grid 用户的可锁定内存上限必须覆盖整个大页区域,否则实例启动时会报无法锁定内存:
# /etc/security/limits.d/99-grid-oracle-limits.conf grid soft memlock unlimited grid hard memlock unlimited oracle soft memlock unlimited oracle hard memlock unlimitedvm.nr_hugepages的单位是页数不是 KB,这是最常见的写错点,写成 8909 才对,写成 8909M 或 18222(误按 1G 页算)都会出问题。memlock 用unlimited比写死 KB 数省事,但前提是 sshd 配置里UsePAM yes已开启,否则 limits 根本不会被 PAM 加载。验证要切到真实用户下去看,不能用 root 的ulimit -l冒充:
# 重新加载 sysctl,然后切用户验证 sysctl --system su - grid -c 'ulimit -l' su - oracle -c 'ulimit -l' grep -i huge /proc/meminfo如果HugePages_Total已经设成目标值但HugePages_Free一直是 0,通常说明有大页被别的进程占着,或者内存碎片严重分配不出来——后者在刚重启完的机器上更容易成功,所以这类参数调整最好放在重启后的第一时间做。我一般会顺手确认Hugepagesize是不是 2048 kB,有些内核参数把默认大页尺寸改过,按 2MB 算出来的页数会整个偏掉。
2.3 软件包与内核参数:PRVF-7573、PRVF-7506 一条条补
包缺失和内核参数不达标是预检查里报得最直白的两类,但正因为直白,很多人习惯性只装报错里点名的那一个,重跑又冒出下一个,来回四五轮。我的做法是一次性把所有依赖摊开核对,用循环一次性列全:
# 19c 在 EL7 上常见的依赖清单,缺哪个补哪个 pkgs="bc binutils compat-libcap1 compat-libstdc++-33 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" for p in $pkgs; do rpm -q "$p" >/dev/null 2>&1 || echo "MISSING: $p" done这段循环用rpm -q静默查询,查不到就打印包名,输出为空说明全部就位。清单里net-tools是集群组件要用的,nfs-utils关系到 ACFS,librdmacm-devel服务于节点间 RDMA 通信,smartmontools和sysstat属于诊断工具,缺了不影响安装但排障时很难受。compat-libstdc++-33在部分 19c 版本里已经不在强制要求内,装了也无害,不必纠结。
能联网的话,最省事的路径是用预安装 RPM 一次性把用户、组、sysctl、limits 全部配好:
# 配置软件源后安装预安装包,它会创建 oracle/grid 用户和 oinstall、dba、asmadmin 等组 yum install -y oracle-database-preinstall-19c这个包会做的事包括:建用户和组、写/etc/sysctl.d/下的内核参数、写 limits、设置numa=off。它最大的价值不是省几条命令,而是避免手工抄参数时漏项——numa=off这种容易被忽略的项,手工配置十次有八次会忘。
不能联网或者要求参数完全可控的场景,就手工写 sysctl。下面这份是我在 19c 上一直用的基线:
# /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 和数据库都靠它;fs.file-max是系统级文件句柄上限;kernel.shmall单位是页,2097152 页乘以 4KB 等于 8GB,是共享内存段的总量上限;kernel.shmmax单位是字节,4294967295 就是 4GB 减 1,物理内存大的机器建议提到内存的一半;kernel.shmmni是共享内存段个数上限;kernel.sem四个值依次是信号量集合最大数、系统信号量总数、单次操作最大数、信号量集合上限,改的时候四个要一起看,只改一个容易互相冲突。net.ipv4.ip_local_port_range起始端口抬到 9000,是为了给 Oracle 留出低位端口段,避免监听端口和临时端口撞车。
参数写进文件不等于生效,sysctl -p只读一个文件,sysctl --system才会按目录顺序把所有配置文件过一遍,后者才是安装前的正确做法:
# 全量加载,输出里能看到每个文件的处理结果 sysctl --system # 抽查几个关键值是否落地 sysctl kernel.shmall kernel.shmmax kernel.sem net.ipv4.ip_local_port_range最后补上 CVU 自己依赖的那个小包。它不在系统源里,位置在 Grid 安装介质的cv/rpm目录下,而且必须装到每一个节点:
# 环境变量告诉 RPM 这个包归哪个组所有,通常就是 oinstall export CVUQDISK_GRP=oinstall # 逐个节点安装,版本号以介质里的实际文件为准 rpm -ivh /u01/app/19.0.0/grid/cv/rpm/cvuqdisk-1.0.10-1.rpm装完之后再跑预检查,并且一定要带-fixup:
# -fixup 会尝试自动修可修项,-verbose 把每一项的判定过程打出来 ./runcluvfy.sh stage -pre crsinst -fixup -n node1,node2 -verbose-fixup能自动处理一部分包缺失和参数偏差,但改动需要重启才生效的项它只能提示。-verbose的价值在排障阶段远大于省屏幕——它会告诉你每一项检查读的是哪个文件、期望值多少、实际值多少,比图形界面那行红字有用得多。真正跑完整套检查建议配合后面的日志路径一起看,否则报错一滚屏就找不回来了。
3. runcluvfy 卡在节点连通性:SCAN 解析、GNS 子域、网段三处硬伤
预检查跑到网络这一段,报错文案会突然变得很抽象:PRVG-1101说 SCAN 名解析失败,PRVF-4656说节点连通性检查没过,还有INS-40913这种主机名校验错误。这三类错误在装过的机器上高度集中在同一个地方——DNS。Oracle 集群要求 SCAN 必须能正向解析出多个地址、并且每个地址都能反解回名字,只做一半的 DNS 在这里必然翻车。
3.1 SCAN 解析失败:正向能通,反解是空的
先摆现象。runcluvfy 或者 gridSetup 走到网络配置那一步,弹出:
PRVG-1101 : SCAN name "scan19.rac.example" failed to resolve PRVF-4656 : Node connectivity check failed第一反应是去nslookup,结果发现正向解析是通的,于是开始怀疑防火墙。真正的原因常常是反解记录没写——CVU 不只看正向,它会把解析出来的每个地址拿去做 PTR 查询,查不到就判定这个 SCAN 不可用。手工验证要正反都打一遍:
# 正向:必须返回三个不同的地址 dig +short scan19.rac.example A # 反向:对上面返回的每个地址逐个做 PTR dig +short -x 192.168.204.162正解域文件的写法,注意 SCAN 的三条 A 记录必须指向三个不同地址,写成一个地址会让 SCAN VIP 失去意义:
# /var/named/named.rac.example $TTL 600 @ IN SOA ns1.rac.example. admin.rac.example. ( 2024010101 ; serial,改动后必须递增 1H ; refresh 15M ; retry 1W ; expire 3H ) ; minimum @ IN NS ns1.rac.example. ns1.rac.example. IN A 192.168.204.12 pub19-node1.rac.example. IN A 192.168.204.11 pub19-node2.rac.example. IN A 192.168.204.12 vip19-node1.rac.example. IN A 192.168.204.21 vip19-node2.rac.example. IN A 192.168.204.22 scan19.rac.example. IN A 192.168.204.162 scan19.rac.example. IN A 192.168.204.163 scan19.rac.example. IN A 192.168.204.164反解域文件与上面的地址一一对应,前缀就是 IP 的最后一段:
# /var/named/named.192.168.204 $TTL 600 @ IN SOA ns1.rac.example. admin.rac.example. ( 2024010101 1H 15M 1W 3H ) @ IN NS ns1.rac.example. 11 IN PTR pub19-node1.rac.example. 12 IN PTR pub19-node2.rac.example. 21 IN PTR vip19-node1.rac.example. 22 IN PTR vip19-node2.rac.example. 162 IN PTR scan19.rac.example. 163 IN PTR scan19.rac.example. 164 IN PTR scan19.rac.example.serial那个数字每次改完必须往上加,否则从节点走的是缓存里的旧记录,你改了文件、重启了服务、验证还是旧结果,这种情况最容易让人误以为配置文件写错了位置。改完systemctl reload named,然后在两个节点上都验证一遍,别只在一台上试。
还有两个隐蔽点。一是/etc/nsswitch.conf里hosts那一行的顺序,如果files排在dns前面,/etc/hosts里残留的旧条目会遮蔽 DNS 的正确解析,验证时看着是对的,安装器读到的却是另一套。二是/etc/resolv.conf如果由网络管理服务接管,重启网卡后指向可能被改回去,装到一半解析突然失效,非要把PEERDNS=no之类的开关关掉才不再复发。
3.2 GNS 子域没配对:SCAN 名不在托管子域下,装完也起不来
如果打算用 GNS 自动分配 VIP 和 SCAN,配置思路和纯手工完全不一样,坑也更集中。19c 的 GNS 要求你在 DNS 里划出一个子域交给它托管,SCAN 名必须落在这个子域下面,否则安装器不会把地址注册请求发给 GNS。
关键就是正解域文件里的这两行:
# 子域 vip.rac.example 的权威服务器是 gns.rac.example vip.rac.example. IN NS gns.rac.example. gns.rac.example. IN A 192.168.204.10第一行把vip.rac.example这个子域的解析权委派给 GNS 节点,第二行告诉解析器 GNS 节点自己的地址。少了任何一行,后面的配置全部白做。
对应的安装界面参数必须严丝合缝地对上:SCAN 名写scan19.vip.rac.example(注意中间带vip.),GNS 的 VIP 地址写192.168.204.10,subdomain 写vip.rac.example。这里最典型的翻车是 SCAN 名写成scan19.rac.example——看着更简洁,但它不在vip.rac.example子域下,GNS 收到注册请求也不会处理。表现是安装过程一路绿灯,到最后启动集群资源时 SCAN 状态一直是 offline,反复srvctl也起不来。
出问题先看这两个命令的输出,比翻安装日志快:
# 看 SCAN 当前配置了几个地址、落在哪个网段 srvctl config scan # 看 SCAN VIP 和 SCAN 监听的真实状态 srvctl status scan srvctl status scan_listenerconfig scan里如果只显示一个 SCAN VIP,或者地址和你在 DNS 里规划的对不上,基本可以确定是子域委派没生效或者 SCAN 名不在托管域内。另外 GNS 本身是集群资源的一部分,它的状态也要单独确认,srvctl status gns显示未运行时,后面所有自动注册都无从谈起。
3.3 网段、命名与下划线:剩下的连通性报错都在这
去掉 DNS 因素之后,PRVF-4656剩下的原因集中在网卡和地址规划上。这几条是硬约束,违反了不会「有时能过」,只会稳定失败:
Public、VIP、SCAN VIP 必须在同一个子网。VIP 的设计前提是能和 Public 在同一网段内做地址漂移,跨网段时集群校验会直接拦下来。Private 必须是独立网段,而且要保证节点之间二层可达,最常见的错误是图省事把 Private 也配到 Public 那个网段里,安装时能过,跑起来节点间心跳和业务流量抢同一块网卡。
名称里不能出现下划线。主机名、VIP 名、SCAN 名都只允许字母、数字和连字符,rac_node1这种写法在别的场景没问题,在这里会触发INS-40913一类的校验失败,而且报错信息往往只说「名称无效」,不说具体是哪个字符。
Private 网卡可以不做 bond,超过四块的部分集群会自动当作冗余处理,所以不必为了数量纠结。手工验证节点间 Private 互通,指定网卡比 ping 主机名更有说服力:
# 指定私有网卡做连通性测试,两个方向都要通 ping -c 2 -I 10.10.10.41 10.10.10.42 ping -c 2 -I 10.10.10.42 10.10.10.41 # 确认每块网卡的地址和掩码没配错段 ip -4 addr show-I后面跟的是源地址,用它能把「路由通但网卡选错」这种情况暴露出来——不指定源地址的 ping 经常从 Public 绕一圈回来也能通,看着正常,实际 Private 是不通的,等到集群启动才报心跳失败。
4. ASM 磁盘认不到、权限变成 root:root:UDEV 绑定与设备名漂移
预检查全绿、集群装完,卡在 ASM 那一步的人反而更多。典型症状是 gridSetup 的磁盘发现界面一块盘都看不到,或者重启之后节点上的磁盘权限从grid:asmadmin变回了root:root,ASM 实例起不来,报ORA-15032一串错误。根因几乎都指向同一个东西:udev 规则没写对,或者写了但没真正生效。
4.1 规则不生效:先确认真正的磁盘唯一标识
写 udev 规则之前必须先拿到磁盘的 WWID,凭/dev/sdb这种内核设备名做匹配是行不通的——重启、加盘、换 HBA 之后设备名会变。取标识:
# 先看整体拓扑,WWN 列就是我们要的 lsblk -o NAME,SIZE,TYPE,WWN,TRAN # 对每块候选盘取 SCSI 唯一标识,注意路径是 /usr/lib/udev 不是 /sbin /usr/lib/udev/scsi_id -g -u -d /dev/sdb第二条命令输出一串36000c29...形式的字符,这就是 WWID,同一块共享盘在两个节点上取到的值必须完全一致,不一致说明多路径没配对或者看到的是不同 LUN。规则文件按下面的写法落地:
# /etc/udev/rules.d/99-oracle-asmdevices.rules KERNEL=="sd[b-f]", SUBSYSTEM=="block", ENV{DEVTYPE}=="disk", \ PROGRAM=="/usr/lib/udev/scsi_id -g -u -d /dev/$name", \ RESULT=="36000c29xxxxxxxxxxxxxxxxxxxxxxxxxxxx", \ SYMLINK+="asm-disk1", OWNER="grid", GROUP="asmadmin", MODE="0660"KERNEL用字符集限定只匹配 sdb 到 sbf,避免误伤系统盘;SUBSYSTEM加DEVTYPE双重限定,只对整盘生效不对分区生效;PROGRAM里$name是 udev 传进来的内核设备名;RESULT是上面取到的 WWID,这是绑定的核心,写错了规则永远匹配不上;SYMLINK生成/dev/asm-disk1这种稳定别名,后面在 ASM 里加盘全用别名;OWNER/GROUP/MODE决定权限,0660加上asmadmin组才够 grid 用户读写。
改完规则要重新加载并触发,两个命令缺一不可:
# 重新读规则文件 udevadm control --reload-rules # 对已存在的设备重新触发 change 事件,--action=change 是关键 udevadm trigger --type=devices --action=change # 验证别名和权限 ls -l /dev/asm-disk*只执行reload-rules不trigger,规则读进去了但从来没被应用过,ls一看什么都没有,很多人到这里开始怀疑规则语法,其实只是少了一条命令。规则错了要看 udev 自己的判定过程,test子命令会把匹配每条规则的细节全打出来:
# 把这块盘的 udev 处理过程完整打印,重点看 RESULT 匹配是否成功 udevadm test /sys/block/sdb 2>&1 | grep -i asm-disk4.2 重启后权限回退:规则被别的文件覆盖了
另一种更气人的情况:手工 trigger 之后/dev/asm-disk*一切正常,欢天喜地去装 ASM,装完重启,权限又变回root:root。根因通常有三个。
第一个是规则文件命名顺序。udev 按文件名排序依次处理,99-之后的数字越大越晚执行,如果你把规则写成了10-oracle-asmdevices.rules,后面系统自带的60-、70-开头规则可能又把权限改回去。统一放到99-开头基本能规避。
第二个是用KERNEL=="sd*"这种大通配。这类写法会把系统盘、引导盘一起匹配上,某些情况下系统盘被改了属主,后面的服务启动异常,表现和 ASM 完全不相干,排查方向直接跑偏。字符集限定看起来啰嗦,但能省下几小时的误判。
第三个是设备其实被多路径接管了,/dev/sdb只是一个不完整的视图,udev 真正处理的是dm-*设备。用udevadm info确认:
# 看这块盘有没有 ID_WWN 以及是否属于某个多路径设备 udevadm info --query=all --name=/dev/sdb | grep -E 'ID_WWN|DM_NAME|DM_UUID'如果输出里出现了DM_NAME,说明它是多路径设备的成员盘,规则应该改成匹配dm-*,而不是继续跟sd*纠缠。
4.3 共享存储场景:用 DM_UUID 绑定才扛得住扫盘
共享存储配上多路径之后,/dev/sd*的编号在节点间不一致是常态——同一个 LUN 在 A 节点是 sdc,在 B 节点是 sdd,两边规则里写sd[b-f]都能匹配上,但到底哪块对应 ASM 里的哪个盘就说不清了。这种环境要用多路径层的标识:
# /etc/udev/rules.d/99-oracle-asmdevices-mpath.rules KERNEL=="dm-*", SUBSYSTEM=="block", ENV{DM_UUID}=="mpath-36000c29xxxxxxxxxxxxxxxxxxxxxxxxxxxx", \ SYMLINK+="asm-disk1", OWNER="grid", GROUP="asmadmin", MODE="0660"DM_UUID以mpath-开头后跟 WWID,这个值在两个节点上完全一致,用它绑定才能保证节点看到的是同一块盘。KERNEL=="dm-*"限定只对多路径设备生效,不会碰到底层成员盘。规则文件在两个节点上必须逐字节一致,任何一个字符不同,两边生成的别名就可能指向不同设备,ASM 加盘时会报盘头冲突。
规则落地之后进 ASM 实例做最终确认,重点看header_status和mode_status:
# 以 sysasm 身份登录,不用密码文件的话用 OS 认证 sqlplus / as sysasm SQL> set lines 200 SQL> col name for a20 SQL> col path for a40 SQL> select name, path, header_status, mode_status from v$asm_disk; SQL> exitheader_status显示CANDIDATE才说明这块盘被 ASM 认可、可以加进磁盘组,显示MEMBER表示已经在某个磁盘组里,显示PROVISIONED或UNKNOWN则说明盘头上残留着旧信息或者权限不对。mode_status是ONLINE才算正常。这一段排查顺序是固定的:先看ls -l /dev/asm-*权限对不对,再看v$asm_disk能不能看到,最后才去看磁盘组的v$asm_diskgroup,从下往上找,比一上来就盯着 ORA 错误码翻文档快得多。
5. 避坑清单:五个装完才发作、返工成本最高的细节
前面几章是「装不过去」的问题,这一章记的是「装过去了但后面出事」的问题。这五条的共同特征是安装阶段完全没症状,等到建库、打补丁或者第一次重启才爆,而那时候动手的时间窗口已经很窄了。
5.1 cvuqdisk 只在主节点装了,副节点跑检查就报找不到包
现象:在主节点上跑runcluvfy.sh一切正常,在第二个节点上跑,第一条就报找不到cvuqdisk包,或者干脆提示 CVU 无法执行。
原因:cvuqdisk这个 RPM 不在系统源里,它在 Grid 安装介质的cv/rpm目录下。主节点装完软件顺手rpm -ivh了,副节点压根没进过那个目录。
解决:在每个节点上装同一个版本,安装前先清掉可能存在的旧版本,并用环境变量指定属组:
# 有旧版本先卸载,避免版本不一致 rpm -e cvuqdisk 2>/dev/null # 指定属组后安装,两个节点执行同样的命令 export CVUQDISK_GRP=oinstall rpm -ivh /u01/app/19.0.0/grid/cv/rpm/cvuqdisk-1.0.10-1.rpm # 确认版本一致 rpm -q cvuqdisk两个节点的版本必须完全相同,一个 1.0.10 一个 1.0.9,检查结果会莫名其妙地不一致。
5.2 limits.conf 改了一大段,ulimit 一看还是老值
现象:/etc/security/limits.conf里明明写了oracle soft nofile 65536,切到 oracle 用户执行ulimit -n,返回的还是 1024,安装器报文件描述符不足。
原因:limits.d目录下的文件会在limits.conf之后加载,同一个项后加载的覆盖先加载的。系统或者预安装包在limits.d里放了配置,你就被静默盖掉了。另一种情况是登录方式不对,用su oracle不加短横线不会重新走 PAM,读的还是当前会话的限制。
解决:先看目录里有什么,再决定改哪个文件:
# 看有哪些文件在管内核资源限制,注意文件名排序 ls -l /etc/security/limits.d/ # 用登录方式切换,确保重新走 PAM 加载 su - oracle -c 'ulimit -n' # 确认 sshd 允许 PAM 加载限制 grep -i '^UsePAM' /etc/ssh/sshd_config要改就改排序靠后的那个文件,或者新建一个99-开头的,比在limits.conf里跟别人抢更省事。UsePAM不是yes的话,不管怎么改都不会生效。
5.3 为了安全关掉 X11 Forward,结果 runInstaller 起不来
现象:加固时把 sshd 的X11Forwarding关成no,第二天跑./runInstaller直接报连不上 X11 显示服务,图形界面弹不出来。
原因:这两个需求是直接冲突的。图形化安装需要转发 X11,安全基线要求关掉它。装的时候关了,装完又忘了恢复,下次再装就得重新翻一遍配置。
解决:装的时候临时放开,或者干脆绕开图形界面走静默安装。临时方案是在 sshd 侧放开并重启
本文还有配套的精品资源,点击获取