简介:这份安装手册面向需要在Red Hat Enterprise Linux 7.6上部署Oracle 19c RAC的数据库管理员与实施人员,重点解决GNS配置SCAN、Flex ASM启用以及集群模式选择等实施难点,并梳理从12.2版本开始的Standalone Cluster与Domain Service Cluster差异。正文按部署流程展开,依次覆盖操作系统环境检查、关闭THP并开启Hugepages、安装依赖软件包、内核参数配置、固定网络与GNS加固定网络两种方案、时钟同步等关键环节,同时给出配置受阻时的排查路径与分析思路,便于读者理解参数背后的约束。
资源包仅含1个docx文档,约160KB,内容以操作要点、参数说明和问题记录为主,章节层级清晰,适合现场对照与逐项核对。已有719人学习,具备Linux与Oracle基础的读者可借此系统梳理19c RAC安装流程,并补充GNS、Flex ASM及集群模式方面的知识缺口。
1. 两个节点跑到 root.sh 一半停住,问题在三天前就埋下了
做 19c RAC Linux 7.6 安装,最折磨人的不是图形界面点错,而是预检查给了一堆黄色 warning 你随手放过,等到 root.sh 在第二个节点上停住、或者集群起来了 ASM 实例死活起不来,才回头翻日志。我印象最深的一次现场,两节点 Linux 7.6,SSH 互信、时间同步、盘都备好了,结果cat /sys/kernel/mm/transparent_hugepage/enabled打出来还是[always] madvise never,Grid Infrastructure 配置阶段直接失败,回滚重装又是一天。这类故障的共同特征是:报错出现在最后一步,根因却躺在装机前那几页环境检查里。下面按现场顺序,把预检查、大页、SCAN 解析、磁盘权限四层拆开,每层都给能直接抄的命令。
2. 预检查满屏 FAILED:软件包与内核参数没对齐的连锁反应
安装介质解压完,第一件事是敲./runcluvfy.sh stage -pre crsinst -fixup -n node1,node2。屏幕上刷过去几十行,红的黄的混在一起,很多人第一反应是怀疑共享存储或者网络不通。实际情况是,在 Linux 7.6 上跑 19c RAC,预检查失败里超过一半是软件包没装全和内核参数两节点不一致,这两类问题排查成本最低,却最容易被人跳过。
2.1 报包缺失时 CVU 到底在比什么
CVU 的检查逻辑很简单:拿一份内置的包清单,去每个节点上跑rpm -q,逐个比对,只要有一个返回非零就报缺失。最小化安装的 RHEL 7.6 基本什么都缺,compat-libcap1、ksh、bc、smartmontools、net-tools这几个是高频漏网之鱼。与其对着报错一条条补,不如先把整份清单扫一遍,缺什么一次看清。
# 逐包扫描,rpm -q 找不到时返回非零,直接打印出来 for p in bc binutils compat-libcap1 compat-libstdc++-33 elfutils-libelf \ elfutils-libelf-devel glibc glibc-devel ksh libaio libaio-devel \ libgcc libstdc++ libstdc++-devel libX11 libXau libXi libXtst \ libXrender libXrender-devel make net-tools nfs-utils \ smartmontools sysstat; do rpm -q "$p" >/dev/null 2>&1 || echo "MISSING: $p" done这段脚本的作用是把「缺哪个」变成一份确定的清单,MISSING:后面跟着的就是要补的包名。循环体里的>/dev/null 2>&1是为了屏蔽rpm -q正常的版本输出,只看失败。清单里的libX11、libXtst、libXrender这几个别嫌多余,OUI 图形界面和部分 DBCA 模板依赖它们,少一个就可能在建库阶段报 JNI 加载失败。
确认完缺失项,用 yum 一次装齐:
# 按扫描结果补齐,注意 RHEL 7.6 的 ISO 源要先挂上 yum install -y bc binutils compat-libcap1 compat-libstdc++-33 \ elfutils-libelf elfutils-libelf-devel glibc glibc-devel ksh \ libaio libaio-devel libgcc libstdc++ libstdc++-devel \ libX11 libXau libXi libXtst libXrender libXrender-devel \ make net-tools nfs-utils smartmontools sysstat装完不要以为就完了,还要处理cvuqdisk。这个包不在系统源里,躺在 Grid 安装介质的cv/rpm目录下,作用是让 CVU 能识别共享磁盘。不装它,后面校验 ASM 磁盘那一步会直接卡住,报出来的信息还完全看不出跟这个包有关。
# 两个节点都要装,先指定属组再装包 export CVUQDISK_GRP=oinstall rpm -ivh /u01/soft/grid/cv/rpm/cvuqdisk-1.0.10-1.rpm # 已装过的先卸再装,避免版本冲突 # rpm -e cvuqdiskCVUQDISK_GRP这个环境变量必须指向oinstall组,它决定了装完之后/usr/sbin/cvuqdisk的属组,装错了 CVU 在校验磁盘时拿不到权限,报的错是「无法访问设备」,很容易被误判成多路径没配好。节点之间rpm -qi cvuqdisk出来的版本号也要一致,一台装了旧版一台装了新版,同样会报校验失败。
2.2 preinstall RPM 和手工 sysctl 为什么打架
Oracle 提供了oracle-database-preinstall-19c这个包,装上之后它会自动建用户、建组、写 sysctl、写 limits、把numa=off塞进内核参数。听起来很省事,但坑在于:如果你的环境里已经有人手工写过一份/etc/sysctl.conf,两个来源会打架,先加载的会被后加载的覆盖,最后生效的可能既不是 A 也不是 B。
我一般的做法是统一走手工配置,把参数落在一个独立的 drop-in 文件里,路径放在/etc/sysctl.d/下,利用 systemd 的字典序加载,文件名前缀给个靠后的数字,保证它盖过其他来源。
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 --system参数的几个关键点在注释之外还得单独说清。kernel.shmmax是单个共享内存段的最大字节数,这里给到 4G,够大多数测试库用;kernel.shmall的单位是页,4K 页乘以 2097152 约等于 8G,必须大于等于shmmax除以页大小,否则 SGA 分配时会报ORA-27123,这个错在建库阶段才冒出来,回头看参数已经来不及。kernel.sem的四个值依次是「每个信号集的信号量数、系统级信号量总数、每次 semop 调用的最大操作数、系统级信号集总数」,这四个数字写错一个顺序,表现就是数据库启动时进程卡在ora_pmon之后不动。
fs.aio-max-nr是给 ASM 用的,ASM 走异步 IO,这个值给小了会在asmcmd里看到ORA-27090,提示异步 IO 提交失败。默认的 65536 在很多机器上不够,1048576 是稳妥值。
改完两个节点的参数必须完全一致。CVU 里有一项是「内核参数一致性校验」,两个节点shmmax差一个字节都会报 FAILED,报错文案只会告诉你哪个参数不一致,不会告诉你哪个节点是对的。
2.3 参数改完不重启,等于什么都没做
sysctl --system能覆盖的只是运行时值,凡是写进GRUB_CMDLINE_LINUX的内核启动参数,不重启一律无效。最典型的就是numa=off和transparent_hugepage=never。preinstall RPM 会帮你改 grub,手工配置就得自己动手,改完还要重建引导文件。
验证分两头看,一头是运行时生效值,一头是内核命令行:
# 看内核启动参数里有没有你要的东西 cat /proc/cmdline # 看运行时参数是否按预期生效 sysctl -a 2>/dev/null | grep -E 'shmmax|shmall|aio-max-nr|kernel.sem'/proc/cmdline里如果没有numa=off,说明 grub 改的地方不对或者重建引导文件时选错了路径,这个在下一章讲大页时还会再遇到一次,是同一个坑。
3. HugePages_Total 是 0:THP 没关干净,大页永远分不出来
grep HugePages_Total /proc/meminfo打出来是 0,但sysctl -a | grep hugepages明明设了值,这是安装现场最常见的自相矛盾现场。原因几乎都指向同一个地方:透明大页没关,内核优先满足 THP,HugePages 的分配被挤掉了。更麻烦的是,有些人改完 grub 重启,/proc/cmdline里干干净净,一个参数都没有,等于白重启一次。
3.1[always] madvise never三种状态与重启失效的三种原因
先看当前状态,方括号括住哪个就是当前生效值:
# 透明大页总开关,[always] 表示已开启 cat /sys/kernel/mm/transparent_hugepage/enabled # 碎片整理开关,同样要看 cat /sys/kernel/mm/transparent_hugepage/defrag正常情况下这两个都应该是[never]。如果是[always] madvise never,说明 THP 开着,Oracle 数据库在这种状态下会出现两个问题:一是 SGA 走不到大页,全部落到普通 4K 页,页表项暴涨;二是内核的 khugepaged 会在后台反复整理内存碎片,表现为数据库偶尔出现莫名的延迟毛刺。这类问题没有明确报错,只能靠监控看出规律,属于典型的玄学故障。
关闭方式是把参数追加到GRUB_CMDLINE_LINUX:
# 先备份,改引导文件属于不可逆操作 cp /etc/default/grub /etc/default/grub.bak.$(date +%F) # 在已有的 GRUB_CMDLINE_LINUX 末尾追加,注意不要新建一行 sed -i 's/\(GRUB_CMDLINE_LINUX="[^"]*\)"/\1 transparent_hugepage=never"/' /etc/default/grub # 确认没改坏 grep GRUB_CMDLINE_LINUX /etc/default/grub这段sed的作用是在引号内追加参数而不是覆盖,\(...\)捕获引号前的内容,\1原样放回去,后面的transparent_hugepage=never才是新增部分。改完必须重建引导文件,而重建命令在 BIOS 和 UEFI 两种机器上是不同的:
# BIOS 引导的机器 grub2-mkconfig -o /boot/grub2/grub.cfg # UEFI 引导的机器 grub2-mkconfig -o /boot/efi/EFI/redhat/grub.cfg路径选错是第一个高频失误。UEFI 机器上跑 BIOS 那条命令,命令会成功返回、grub.cfg也会更新,但实际引导读的是 EFI 分区里那份,重启后参数自然不生效。判断方法很简单,ls /boot/efi/EFI/下有目录就是 UEFI。
第二个高频失误是sed匹配失败但没人发现。有些发行版的 grub 文件里写的是GRUB_CMDLINE_LINUX_DEFAULT,或者这一行被换行拆成两行,正则对不上,sed静默什么都不做,grep一下就能看出来。
第三个是改完没重启就接着装。transparent_hugepage=never是内核启动参数,echo never > /sys/.../enabled只能临时生效,重启就回去了。
3.2 nr_hugepages 与 memlock 的算账方式
THP 关掉之后才轮到配大页。大页的算法核心是两件事:页数够不够、锁内存额度够不够。
页数怎么算:Oracle 的 SGA 走 2M 大页,vm.nr_hugepages乘以 2M 要能覆盖 SGA 再加一点余量。19c 还有个额外变量——如果在 standalone 集群里启用了 GIMR(管理资料库 MGMTDB),它自己也要占大约 1G 的大页,这笔账不算进去,后面就会出现数据库起来了但 MGMTDB 起不来,或者反过来。
# 先确认系统页大小,绝大多数 x86_64 是 2048 KB PAGE_KB=$(awk '/Hugepagesize/{print $2}' /proc/meminfo) # SGA 目标 8G,按 10% 余量算页数 SGA_MB=8192 NR=$(( SGA_MB * 1024 / PAGE_KB * 11 / 10 )) # 追加到 sysctl 配置文件,注意别覆盖已有内容 echo "vm.nr_hugepages = $NR" >> /etc/sysctl.conf sysctl -pPAGE_KB从/proc/meminfo里读,避免硬编码,换到页大小不同的机器上脚本直接能用。11/10是余量系数,大页只能整页分配,SGA 如果没按 2M 对齐,尾数会多占一页。NR算出来之后写进sysctl.conf,这里故意不用 drop-in 文件,是因为vm.nr_hugepages属于可在运行时调整的参数,写主文件更直观。
光有页数不够,还得让 oracle 用户有权限锁住这些内存。memlock的单位是 KB,给unlimited最省事:
cat >> /etc/security/limits.conf <<'EOF' oracle soft memlock unlimited oracle hard memlock unlimited EOF有些环境的安全基线不允许unlimited,那就写具体数值,至少等于页数乘以页大小再加几百 KB 的余量。写小了的现象是数据库能起来,但alert log里反复出现ORA-27125相关的警告,SGA 只锁住了一部分。
3.3 三处验证,缺一不可
配置完重启,别急着装 Grid,先做三项交叉验证:
# 1. THP 必须全部是 never cat /sys/kernel/mm/transparent_hugepage/enabled cat /sys/kernel/mm/transparent_hugepage/defrag # 2. 内核命令行里必须能看到参数 cat /proc/cmdline # 3. 大页总数与空闲数 grep -E 'HugePages_Total|HugePages_Free|Hugepagesize' /proc/meminfoHugePages_Total是分配出来的总页数,HugePages_Free是还没被占用的。数据库还没启动的情况下,Free 应该等于 Total;如果 Total 有值但 Free 远小于 Total,说明已经有进程把大页吃掉了,安装前最好重启一次清干净。如果 Total 一直是 0 但sysctl -a里能看到vm.nr_hugepages有值,多半是内存碎片导致分配失败——内核找不到足够大的连续物理内存。这种情况只能重启,或者调小页数重试。
4. SCAN 校验失败:DNS、GNS 与 /etc/hosts 的三方打架
预检查跑到网络那一节,屏幕上出现 SCAN 相关的红色条目,是另一个高发点。最容易误导人的地方在于:你在命令行nslookup明明能通,返回三个地址也没错,但 OUI 的 SCAN 校验就是不通过。原因在于 OUI 校验的不只是「能不能解析」,还包括正反解一致性、响应时间、地址是否在同一子网、多个节点解析结果是否一致,任何一项不满足都会报红。
4.1 正解、反解、响应时间三项都要过
先把三项拆开验证,别笼统地「试试能不能 ping 通」:
# 正解:三个 SCAN 地址都得出来 nslookup scan19.vip.rac.libai # 反解:拿 IP 反查名字,结果必须和正解对得上 nslookup 192.168.204.33 nslookup 192.168.204.34 nslookup 192.168.204.35 # 每个节点都跑一遍,结果必须完全一致反解对不上是最常见的报红原因。DNS 里只配了正解 zone,没配反解 zone,nslookup IP直接超时,OUI 就报类似「无法确定 SCAN 名称」的错误。响应时间也有阈值,超过几秒同样判定失败,这种情况通常是 DNS 服务器配了错误的转发或者 forwarders 指向不通的地址,每次查询都在等超时。
还有一个容易被忽略的点:SCAN 的三个地址必须和 Public、VIP 在同一个子网段。跨子网的话,客户端连上来会有路由问题,OUI 在预检查阶段就会拦下来。现场的 IP 规划通常是这个形状:
# /etc/hosts,两个节点内容一致 192.168.204.11 pub19-node1.rac.libai 192.168.204.12 pub19-node2.rac.libai 40.40.40.41 priv19-node1.rac.libai 40.40.40.42 priv19-node2.rac.libai 192.168.204.21 vip19-node1.rac.libai 192.168.204.22 vip19-node2.rac.libai # SCAN 交给 DNS 解析,hosts 里不写,写了反而互相打架SCAN 的几条记录只应该在 DNS 里出现,如果同时写进了 hosts,不同节点的解析顺序不一致,会出现「节点 1 校验通过、节点 2 校验失败」这种看起来毫无道理的现场。我一般会在 hosts 末尾留一行注释,提醒后面接手的人不要往里加 SCAN。
4.2 GNS 子域委派的那两行是关键
用 GNS 自动分配 VIP 和 SCAN 的场景,DNS 配置比固定 IP 复杂一层。核心思路是把一个子域的解析权委派给 GNS 服务器,让 GNS 自己往里写记录。
正解 zone 文件里这两行是命门:
# 子域 vip.rac.libai 的权威服务器是 gns.rac.libai vip.rac.libai. IN NS gns.rac.libai. # 该服务器的地址 gns.rac.libai. IN A 192.168.204.10第一行的意思是「凡是xxx.vip.rac.libai的查询,别问我,去问gns.rac.libai」。第二行告诉解析器gns.rac.libai这个主机名对应哪台机器。少了第一行,GNS 分配出去的 VIP 记录永远不会被查到;少了第二行,解析器拿到委派信息后找不到下一跳,查询直接失败。
由此推出一条硬性约束:SCAN 的名字必须落在被委派的子域里。如果委派的是vip.rac.libai,那 SCAN 就得叫scan19.vip.rac.libai,改成scan19.rac.libai就跑到父域去了,GNS 管不到。在 gridSetup 里配置 GNS 那一步,VIP 地址填192.168.204.10,子域填vip.rac.libai,两处必须和 zone 文件严格对应,多一个点少一个点都会解析失败。
zone 声明部分还有一处经典错误,就是反解 zone 的名字。网段反着写再加后缀,192.168.204.0/24对应的 zone 名是204.168.192.in-addr.arpa,写成192.168.204.in-addr.arpa语法上不报错,但永远匹配不上查询。
# named.conf 关键片段 zone "rac.libai" IN { type master; file "named.rac.libai"; }; # 反解域名是网段倒序,别写反 zone "204.168.192.in-addr.arpa" IN { type master; file "named.192.168.204"; }; # 私网段的反解单独一个 zone zone "40.40.40.in-addr.arpa" IN { type master; file "named.40.40.40"; };改完 zone 文件记得递增 SOA 里的 serial 号,然后named-checkzone校验语法、systemctl reload named重载。serial 不改,从节点或者缓存不会刷新,改了等于没改。
4.3 命名规则与网段约束的几条硬线
Public、VIP、SCAN VIP 的名字只允许字母、数字和-,下划线绝对不行。这一点在 hosts 文件里写错了当时不报错,到 OUI 校验阶段才炸,报的是「名称格式无效」。主机名里带下划线在 Linux 上完全合法,所以没人会主动怀疑它。
Private 网络的规划也有一条容易忽略的规则:安装过程最多识别四块网卡做 HAIP,超过四块的部分自动降为冗余,不做负载。所以别想着把八个网卡都配上私网地址来增加带宽,第五块之后的地址只会占着配置位不干活。私网也不强制做 bond,集群自己能做高可用,硬做 bond 反而多一层排查难度。
还有一条全局约束:整个集群要么全 IPv4,要么全 IPv6,不能混。混着配的现场,表现为部分节点的 VIP 起不来,日志里能看到地址族不匹配的错误。
5. 常见问题五连:UDEV 权限、limits 不生效与时钟漂移
前面四章讲的是成体系的排查路径,这一章集中收几个零散但高频的坑。它们的共同点是:单个看都不难,但在安装进行到一半时冒出来,很容易让人怀疑是大方向错了,白白浪费几个小时。
5.1 磁盘权限不对,asmca 里根本看不到盘
现象:asmca或者 OUI 的磁盘发现页面,列表空空如也,明明lsblk能看到那些盘;偶尔能看到盘但勾选后报权限不足。原因基本都是 UDEV 规则写得过于宽松或者匹配方式不对,权限和属组没落到grid:asmadmin上。
最忌讳的写法是KERNEL=="sd*"一把抓,把所有 SCSI 盘都改成 asmadmin 属组,系统盘跟着遭殃,而且重启后盘符漂移,规则匹配到别的设备上。正确做法是按磁盘序列号绑定:
# 先查每块盘的唯一序列号 /usr/lib/udev/scsi_id -g -u -d /dev/sdb # 按序列号绑定,一一对应 cat > /etc/udev/rules.d/99-oracle-asmdevices.rules <<'EOF' KERNEL=="sd*", SUBSYSTEM=="block", ENV{ID_SERIAL}=="3600c0ff000d5e0e0b1a2b3c400000000", SYMLINK+="asm-disk1", OWNER="grid", GROUP="asmadmin", MODE="0660" KERNEL=="sd*", SUBSYSTEM=="block", ENV{ID_SERIAL}=="3600c0ff000d5e0e0b1a2b3c400000001", SYMLINK+="asm-disk2", OWNER="grid", GROUP="asmadmin", MODE="0660" EOF # 重载规则并触发 udevadm control --reload-rules udevadm trigger --type=devices --action=change # 验证属主属组和权限 ls -l /dev/asm-disk*ENV{ID_SERIAL}用序列号而不是KERNEL设备名,是因为设备名会随扫描顺序变化,序列号不会。SYMLINK+="asm-disk1"造一个稳定的软链接,后面 ASM 用这个路径而不是/dev/sdb。MODE="0660"是必须的,664 会让其他用户也能读,CVU 会报权限过宽。规则改完不udevadm trigger是不生效的,很多人改完文件就去重启机器,其实没必要。
5.2 /dev/shm 太小,安装卡在链接阶段
现象:OUI 在 87% 左右长时间不动,日志里能看到内存分配失败或者临时文件写不进去。原因:/dev/shm是 tmpfs,默认大小只有物理内存的一半,某些镜像里甚至被限制得很小,而 Oracle 的链接阶段会往里面写大文件。
# 先看当前大小 df -h /dev/shm # 临时改大,重启失效 mount -o remount,size=16G /dev/shm要永久生效得改/etc/fstab里 tmpfs 那行。另一个常被忽略的是/tmp,要求至少 1G,有些安全基线把/tmp单独分区并限制得很小,安装过程会报「临时目录空间不足」。绕开的办法是把 TMP 指到别的盘:
export TMP=/u01/tmp export TMPDIR=/u01/tmp mkdir -p /u01/tmp这两个变量要在执行runInstaller的那个会话里设置,并且建议写进 oracle 用户的.bash_profile,否则后面的dbca又会踩一次。
5.3 limits.conf 明明改了,ulimit 还是老值
现象:/etc/security/limits.conf里 memlock 已经写unlimited,用su - oracle切过去ulimit -l打出来还是 64。原因有两层:一是pam_limits只对真正的登录会话生效,su不带-的时候不会重新加载;二是有些发行版把 limits 拆到了/etc/security/limits.d/下,那边的文件按字典序后加载,会覆盖主文件。
# 必须带减号,模拟完整登录 su - oracle -c 'ulimit -l' # 看 limits.d 下有没有后加载的覆盖文件 ls -l /etc/security/limits.d/如果limits.d里有个20-nproc.conf之类带 memlock 的条目,主文件的配置会被它盖掉。解决办法是在limits.d里新建一个靠后编号的文件,或者直接改那个覆盖文件。还有一层是 systemd 托管的会话,/etc/systemd/system.conf里的DefaultLimitMEMLOCK优先级更高,容器化的环境尤其容易碰上。
5.4 两个节点时间差几秒,集群起来后资源乱跳
现象:crsctl stat res -t里某些资源反复在 ONLINE 和 OFFLINE 之间切换,日志里能看到时间戳对不上。原因:两个节点没有统一的时间源,或者时区配置不同。
# 看时间同步源状态 chronyc sources -v # 看时区和时间 timedatectl时区不同是最阴的一种,date出来时间是对的,但timedatectl显示一个节点是 UTC 一个是 CST,差出八小时,集群心跳直接崩。安装前两个节点都必须配好同一个时间源,把timedatectl set-timezone统一掉,再重启 chronyd。
5.5 启用 GIMR 后大页不够用
现象:数据库实例正常,但 MGMTDB 起不来,srvctl status mgmtdb显示未运行,日志里提示内存分配失败。原因:19c 的 standalone 集群里 GIMR 是可选项,一旦启用,它自己会占大约 1G 的大页内存,而很多人的vm.nr_hugepages只按数据库 SGA 算,没把这 1G 算进去。
解决办法有两个方向:要么把页数加上 512 页(1G 除以 2M)重新分配,要么在 gridSetup 阶段就不勾选 GIMR。后者在测试环境更省事,19c 开始 GIMR 在 standalone 安装里已经变成可选项,不装不影响集群基本功能,只是少了一些集中诊断能力。生产环境要看监控方案再定。
6. 快速定位:把报错映射到配置层的一句话判断法
装到第三台机器之后,我基本不再逐条读报错,而是先判断「这个错出现在哪一层」,直接跳到对应的检查点。这套映射关系帮我把平均排查时间从两小时压到二十分钟以内。
| 报错出现的位置 | 先查哪一层 | 一条命令 |
|---|---|---|
| 预检查一开始就红一片 | 软件包与 cvuqdisk | rpm -q cvuqdisk compat-libcap1 libaio |
| 预检查参数一致性失败 | sysctl 两节点差异 | sysctl -a | grep -E 'shmmax|shmall|sem' |
| Grid 配置阶段失败 | THP 与 HugePages | grep HugePages_Total /proc/meminfo |
| SCAN 校验红条 | DNS 正反解 | nslookup <scan 名>与nslookup <scan IP> |
| 磁盘发现列表为空 | UDEV 权限 | ls -l /dev/asm-disk* |
| 建库阶段内存报错 | memlock 与页数 | su - oracle -c 'ulimit -l' |
判断链路其实只有一条主线:先看/proc/cmdline里的内核参数在不在,再看sysctl -a的运行值对不对,然后看/proc/meminfo的大页有没有分出来。这三步覆盖了六成以上的安装失败。剩下的四成里,一半在网络解析,一半在磁盘权限,各自用一条nslookup和一条ls -l就能定位。
真正省时间的做法是把这些检查固化成安装前的一个脚本,跑完输出一张全绿的清单再动手。我现在的习惯是:任何一次 RAC 安装,不管第几次装、不管环境多像上次,都强制先跑一遍这份检查,包括 THP 状态、大页页数、两节点 sysctl diff、DNS 正反解、UDEV 权限、时钟偏移。听着啰嗦,但比装到一半回滚重来划算得多。那次在两台机器上耗掉整整一天之后,我就再没跳过这一步。希望帮到你。
本文还有配套的精品资源,点击获取