RHEL 7.6 两节点部署 Oracle 19C ASM 与 DataGuard 实战 简介面向需要在 Red Hat Enterprise Linux 7.6 上搭建 Oracle 19C 高可用数据库环境的中高级 DBA 与运维人员这份安装指南围绕 ASM 存储管理与 Data Guard 主备复制展开覆盖从系统准备、GI 与数据库软件部署到主从配置的完整流程。全包仅含 1 个 PDF 文件压缩包约 4.68MB篇幅集中、便于离线查阅与打印对照适合作为实验环境和生产演练时的操作参照。内容结合具体节点规划展开给出 primary 与 physical standby 的主机资源、目录布局、网络地址及安装前检查项并提示全路径预创建、gridSetup 安装位置等易错细节能够帮助读者理清安装顺序、理解 ASM 磁盘组与 Data Guard 配置之间的衔接关系。目前已有 705 人学习适合希望系统掌握 RHEL 下 Oracle 19C ASM 加 Data Guard 部署思路的读者参考。1. RHEL 7.6 装 Oracle 19C ASM DataGuard先在纸上把两个节点画完再动手最典型的安装失败并不是 gridSetup 弹出报错而是它根本不报错——磁盘发现页一片空白。你以为是共享盘没有映射其实只是 udev 规则里的 chown 用户组写错了。在 RHEL 7.6 上装 Oracle 19C、用 ASM 管存储、再用 DataGuard 做一份物理备库这套组合在实验环境和中小规模生产里出现频率极高两个节点、两套 ORACLE_HOME、四个共享磁盘、一套主备复制。它不难但每一步都要依赖前面的路径、权限和参数完全正确前面留一个小尾巴后面就要用几小时去翻日志。这篇适合两类人手上有能开两台虚拟机、想把 19C 高可用真正跑通一次的开发者以及装过单实例、第一次碰 ASM 和 DG、不确定该先做哪一步的人。2. 系统与装前准备从 df 到 sysctl 一次落地装 19C 之前先把系统这一层“压平”。RHEL 7.6 本身不挑硬件挑的是你有没有按 Oracle 的规矩给内存、swap、共享内存和目录留位置。这一章按顺序把磁盘布局、目录、网络、依赖包、内核参数、用户权限、时间同步一次性配完配完就能直接进 ASM 那一步。2.1 两个节点的磁盘与内存对照先把两台的实际情况摆出来后面所有参数都从这里推。项目node2primarynode2dgphysical standbyCPU4 core4 core内存20G20Gswap20G20G/dev/shm9.8G9.9G根分区/20G已用 4.8G20G已用 4.7G/boot197M197M/app45G已用 20G40G已用 33M主机 IP10.6.0.13910.6.0.13719C 官方给的最低线是 RAM 不小于 2GB、Oracle Base 至少留 7.5GB实际跑 ASM 加 DG这组数字基本只够“装得上”。swap 的规则是RAM 在 2.5GB 到 16GB 之间时swap 设成和 RAM 一样大RAM 大于 16GB 时swap 固定 16GB。这里 20G 内存配了 20G swap是留了余量的做法不算错但也没必要再往上加——swap 太大反而会掩盖内存不足的问题。/dev/shm那一栏要特别注意它是 tmpfs默认是内存的一半。19C 的自动内存管理依赖它DG 场景下备库应用日志时也会有额外开销9.8G 这个值刚好卡在线上不建议再往下压。提示/app主库已经用了 20G说明软件和库文件都落在上面备库那 40G 是干净的。装之前先df -h各看一遍别等 runInstaller 跑到 80% 才提示空间不足。2.2 目录创建gridSetup 只认它自己所在的路径这一步很多人会跳过直接解压然后跑安装器结果 ORACLE_HOME 检测那一页永远过不去。原文给的那句备注值得抄在本子上需提前创建好全路径否则安装软件时检测不到路径软件会安装在 gridSetup 所在路径。# GI 侧ORACLE_BASE 与 ORACLE_HOME 必须是两条独立路径 mkdir -p /app/grid mkdir -p /app/product/19.2.0/crs mkdir -p /app/oraInventory # DB 侧 mkdir -p /app/oracle/product/19.2.0/dbhome_1 # 安装过程中的临时目录19C 解压和链接都会往这里写 mkdir -p /app/tmp逻辑上/app/grid是 GI 的 ORACLE_BASE下面会生成diag、admin、audit这些运行期目录/app/product/19.2.0/crs是 GRID_HOME只放软件本体。把这两个混在一个路径里后面打补丁、清理日志都会很别扭。/app/oraInventory是两个 ORACLE_HOME 共用的清单目录单独拎出来是为了补丁和卸载时能统一管理。建完立刻把属主和权限落下去# GI 相关目录归 grid组用 oinstall chown -R grid:oinstall /app/grid /app/product/19.2.0/crs /app/oraInventory chown -R oracle:oinstall /app/oracle chmod -R 775 /app/grid /app/product/19.2.0/crs chmod 1777 /app/tmp参数说明775让同组用户可写方便后续两个用户互查文件/app/tmp给1777是因为安装器会以不同用户往里面写临时文件粘滞位能防止互相删。两个节点都要执行别只做主库——备库同样要装 GI 和 DB 软件不是建个空目录就完事。注意如果先unzip再补chown解压出来的文件属主是 root安装器权限检查会直接红叉。顺序是先建目录、再 chown、最后解压。2.3 主机名、IP 与 NOZEROCONF网络这块出问题症状往往出现在很后面的 DG 阶段排查成本极高。所以主机名和 hosts 在装之前就要定死装完再改会很麻烦。# node2 上执行node2dg 上把主机名换掉再执行一次 hostnamectl set-hostname node2 # 两个节点的 hosts 必须完全一致大小写、后缀都要一致 cat /etc/hosts EOF 10.6.0.139 node2 10.6.0.137 node2dg EOF检查一遍hostname ping -c 2 node2dgping必须能通且返回的 IP 要和 hosts 里写的一致。DG 的LOG_ARCHIVE_DEST_2后面跟的是一个服务名最终通过 tnsnames 解析到 IP中间任何一层对不上报的就是 ORA-12154 或者 ORA-12514 这类看着像监听问题的错。再处理 zeroconfchmod 644 /etc/sysconfig/network echo NOZEROCONF yes /etc/sysconfig/network/etc/sysconfig/network在 RHEL 7.6 上默认是 600安装器预检查会提示权限过严。NOZEROCONFyes是关掉 169.254 网段的自动地址分配多网卡机器上不关有时候主机名会被解析到 link-local 地址上表现就是“明明配了 hosts安装器还是说解析失败”。提示hosts 里不要写127.0.0.1 node2这种行。安装器会取第一个匹配到的主机名取到回环地址后后面所有依赖 IP 的检查都会失败。2.4 依赖包一条 rpm -q 查完缺的两个手动补RHEL 7.6 的 DVD 镜像里大部分包都有但有两个例外。先用一条命令把状态查清楚别盲装rpm -q --qf %{NAME}-%{VERSION}-%{RELEASE} (%{ARCH})\n \ bc binutils compat-libcap1 compat-libstdc-33 glibc glibc-devel ksh \ libaio libaio-devel libX11 libXau libXi libXtst libXrender-devel libXrender \ libgcc libstdc libstdc-devel libxcb make nfs-utils net-tools python \ python-configshell python-rtslib python-six smartmontools sysstat targetcli--qf是自定义输出格式%{NAME}、%{VERSION}、%{RELEASE}、%{ARCH}分别取包名、版本、发布号、架构。用默认输出的话没装的包混在package xxx is not installed里一眼扫不出来缺哪几个。能直接 yum 的部分yum install -y bc binutils compat-libcap1 glibc glibc-devel ksh \ libaio libaio-devel libX11 libXau libXi libXtst libXrender-devel libXrender \ libgcc libstdc libstdc-devel libxcb make nfs-utils net-tools python \ python-configshell python-rtslib python-six smartmontools sysstat targetclicompat-libstdc-33在 RHEL 7 的镜像里没有得手工传两个 rpm 进去rpm -ivh compat-libstdc-33-3.2.3-72.el7.x86_64.rpm \ compat-libstdc-33-3.2.3-72.el7.i686.rpmx86_64 和 i686 两个都要装19C 的某些二进制依赖 32 位版本只装 64 位能过检查但运行期会报找不到libstdc.so.5。另外两个细节原文的 yum 列表里写了python-configshell8实际包名以yum list | grep configshell查到的为准libgcc_s.so.1、libc.so.6是文件名不是包名写进 yum 列表会报No package available忽略即可它们本来就属于 glibc 和 libgcc。2.5 sysctl.confshmall 和 shmmax 按内存算不要照抄内核参数是最容易照抄出错的地方因为不同内存的机器上这些数值完全不同。fs.aio-max-nr 1048576 fs.file-max 6815744 kernel.shmall 4294967296 kernel.shmmax 12640516096 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逐个说清楚取舍kernel.shmmax是单个共享内存段的最大字节数经验值取物理内存的一半。20G 内存一半是 10737418240原文给的是 12640516096约 11.77G比一半略大一点没问题只要不超过物理内存就行。kernel.shmall是共享内存总页数单位是页4K 页大小下shmall shmmax / 4096。原文的 4294967296 页换算下来是 16TB远大于 shmmax属于“给足不设限”的写法符合“shmall 大于或等于 shmmax”的要求。kernel.sem的四个值依次是每个信号集的信号量数、系统级信号量总数、每次 semop 调用可操作的数量、信号集总数。250 32000 100 128 是 Oracle 的标准配置。fs.aio-max-nr建议不低于 1048576ASM 加 DG 的异步 IO 请求量不小设小了会报 ORA-27090。写进去之后用 root 执行sysctl -p然后抽查两个sysctl kernel.shmmax kernel.shmall ipcs -lmipcs -lm能看到当前系统允许的最大共享内存段大小跟 sysctl 里的值对得上才算生效。2.6 用户、组、limits.conf 与 PAMOracle 官方推荐的组和 GID 是固定的照着建就行避免后面权限判断出错。/usr/sbin/groupadd -g 54321 asmadmin /usr/sbin/groupadd -g 54322 asmdba /usr/sbin/groupadd -g 54323 asmoper /usr/sbin/groupadd -g 54324 dba /usr/sbin/groupadd -g 54325 oper /usr/sbin/groupadd -g 54326 oinstall /usr/sbin/groupadd -g 54327 backupdba /usr/sbin/groupadd -g 54328 dgdba /usr/sbin/groupadd -g 54329 kmdba /usr/sbin/groupadd -g 54330 racdba /usr/sbin/useradd -u 54321 -g oinstall \ -G dba,asmdba,backupdba,dgdba,kmdba,racdba,oper oracle /usr/sbin/useradd -u 54322 -g oinstall \ -G asmadmin,asmdba,asmoper,dba grid组的作用分工oinstall是主组软件安装目录归它dba给数据库管理权限asmadmin是 ASM 磁盘的管理组udev 绑定时要用asmdba让 oracle 用户能访问 ASM 实例asmoper是 ASM 的运维操作组。dgdba用于 DataGuard 的 broker 管理kmdba是 TDE 钱包管理racdba这套单实例用不上但建上不影响以后要扩成集群省得再动。然后是 shell 限制/etc/security/limits.conf两个用户各写一段grid soft nproc 2047 grid hard nproc 16384 grid soft nofile 1024 grid hard nofile 65536 grid soft stack 10240 grid hard stack 32768 grid soft memlock 3145728 grid hard memlock 3145728 oracle soft nproc 2047 oracle hard nproc 16384 oracle soft nofile 1024 oracle hard nofile 65536 oracle soft stack 10240 oracle hard stack 32768 oracle soft memlock 3145728 oracle hard memlock 3145728memlock单位是 KB3145728 就是 3GB用于锁定 SGA 不被换出。nofile硬限 65536 是 19C 的推荐值软限保持 1024 是为了兼容性——实际运行中会用到硬限。stack32MB 是给 ASM 和 DG 的进程栈留余量。PAM 那边要把 limits 加载进来echo session required pam_limits.so /etc/pam.d/login改完必须重新登录才生效验证方式su - grid -c ulimit -n; ulimit -u; ulimit -l三个值应该分别对应 nofile、nproc、memlock 的软限。如果还是原来的 1024/4096说明 PAM 没生效或者改错了文件。2.7 时间同步与 avahi-daemon 关停实验环境里最简单的做法是干脆不用外部时间源systemctl status chronyd systemctl disable chronyd systemctl stop chronyd mv /etc/chrony.conf /etc/chrony.conf_bak不用 NTP 和 chrony 之后GI 会自动启用自带的 CTSS集群时间同步服务来保证节点间时间一致。前提是装 GI 那一刻两个节点的时间差不能太大最好先在两台机器上各跑一次date对一下差个几秒就手动date -s调平。生产环境还是建议保留 chrony指向内网时间源。实验环境这么做的原因是省事且不会因为外部源不可达导致 CTSS 告警。avahi-daemon 要停掉systemctl status avahi-daemon systemctl stop avahi-daemon systemctl disable avahi-daemon它做的是 mDNS 服务发现占 5353 端口本身不影响 Oracle但安装器的预检查会把它列成待处理项。停掉能少一行警告也少一个运行中的隐患。到此为止第 2 章这套动作在两个节点上各做一遍系统层就算配平了。接下来才是真正跟 Oracle 打交道。3. ASM 共享盘与 GI 安装从 WWID 绑定到 gridSetup 走完ASM 这一层最容易让人怀疑人生磁盘明明在/dev下能看到gridSetup 的磁盘发现页就是不显示。根因几乎都是 udev 规则没生效或者权限没落对。这一章把 WWID 获取、规则编写、权限验证和环境变量串成一条线最后走到 gridSetup 真正把 DATA 磁盘组建出来。3.1 先用 scsi_id 拿到每块盘的 WWID共享盘准备好之后虚拟化平台上挂四块共享盘设备名一般是/dev/sdc到/dev/sdf不要用设备名去绑重启一次顺序就变了。要用 WWID/usr/lib/udev/scsi_id -g -u /dev/sdc /usr/lib/udev/scsi_id -g -u /dev/sdd /usr/lib/udev/scsi_id -g -u /dev/sde /usr/lib/udev/scsi_id -g -u /dev/sdf输出是一串 32 位十六进制像36000c291ca220c52c813c595ffdf14f4。这串东西在虚拟化平台上一般由存储后端生成跨节点是稳定的所以拿它做主键最可靠。参数说明-g是 treat device as whitelisted-u是输出 WWID 而不是 vendor/model。如果盘走了多路径/dev/sdc可能对应多个底层设备这时候要改用/usr/lib/udev/scsi_id -g -u -d /dev/sdc指定-d或者直接从/dev/mapper/mpathX上取。四块盘的 WWID 抄下来后面规则里一条对应一个。# 顺手确认一下四块盘的大小和类型别把系统盘绑进去 lsblk -o NAME,SIZE,TYPE,MOUNTPOINT注意绑之前一定核对设备名把根盘绑成asmdisk的下场不用多说。判断方法是看lsblk输出里这块盘有没有挂载点、是不是disk类型。3.2 udev 规则的写法四块盘写四条规则文件放在/etc/udev/rules.d/99-my-asmdevices.rules用 99 开头是因为数字越大优先级越低、执行越靠后能覆盖前面的规则vi /etc/udev/rules.d/99-my-asmdevices.rules内容按原文的格式一块盘一条KERNELsd*[!0-9], ENV{DEVTYPE}disk, SUBSYSTEMblock, \ PROGRAM/usr/lib/udev/scsi_id -g -u -d $devnode, \ RESULT36000c291ca220c52c813c595ffdf14f4, \ RUN/bin/sh -c mknod /dev/asmdisk01 b $major $minor; chown grid:asmadmin /dev/asmdisk01; chmod 0660 /dev/asmdisk01 KERNELsd*[!0-9], ENV{DEVTYPE}disk, SUBSYSTEMblock, \ PROGRAM/usr/lib/udev/scsi_id -g -u -d $devnode, \ RESULT36000c29d82b62077ca6ced88065bfc1f, \ RUN/bin/sh -c mknod /dev/asmdisk02 b $major $minor; chown grid:asmadmin /dev/asmdisk02; chmod 0660 /dev/asmdisk02 KERNELsd*[!0-9], ENV{DEVTYPE}disk, SUBSYSTEMblock, \ PROGRAM/usr/lib/udev/scsi_id -g -u -d $devnode, \ RESULT36000c29a2d05c23b4ca757912c0bc9ca, \ RUN/bin/sh -c mknod /dev/asmdisk03 b $major $minor; chown grid:asmadmin /dev/asmdisk03; chmod 0660 /dev/asmdisk03 KERNELsd*[!0-9], ENV{DEVTYPE}disk, SUBSYSTEMblock, \ PROGRAM/usr/lib/udev/scsi_id -g -u -d $devnode, \ RESULT36000c296d86677032ffcc5b372c28a98, \ RUN/bin/sh -c mknod /dev/asmdisk04 b $major $minor; chown grid:asmadmin /dev/asmdisk04; chmod 0660 /dev/asmdisk04逐段解释这几个匹配条件KERNELsd*[!0-9]只匹配整盘设备[!0-9]排除了sdc1这种带分区号的避免对分区也执行一遍。ENV{DEVTYPE}disk再兜一层确保是磁盘而不是分区。SUBSYSTEMblock限定块设备。PROGRAM调用 scsi_id 取当前设备的 WWID结果存进RESULT做比较。RESULT里填的就是上一步抄下来的 WWID必须一字不差——包括大小写。RUN里做三件事用$major和$minor创建块设备节点、把属主改成grid:asmadmin、权限设成0660。0660这个权限是关键grid 用户可读写asmadmin 组可读写其他人无权限。ASM 实例以 grid 用户运行磁盘组管理依赖 asmadmin 组两边都对上才认得出盘。3.3 触发规则并验证权限写完之后不用重启直接触发/sbin/udevadm trigger --typedevices --actionchange--typedevices表示只处理设备事件--actionchange是触发 change 动作对应规则里的匹配逻辑。等两三秒再查ls -l /dev/asmdisk*正常输出应该是brw-rw---- 1 grid asmadmin 8, 32 Nov 12 10:21 /dev/asmdisk01 brw-rw---- 1 grid asmadmin 8, 48 Nov 12 10:21 /dev/asmdisk02 brw-rw---- 1 grid asmadmin 8, 64 Nov 12 10:21 /dev/asmdisk03 brw-rw---- 1 grid asmadmin 8, 80 Nov 12 10:21 /dev/asmdisk04b开头说明是块设备属主和属组必须是grid asmadmin权限rw-rw----。任何一项不对就回到规则里查。再用 udev 自己的视角确认一遍udevadm info --queryall --name/dev/asmdisk01 | grep -E DEVNAME|ID_SERIAL如果这条命令能返回信息说明设备节点是 udev 管着的如果报Unknown device那就是mknod出来的节点没被 udev 数据库收录虽然能用但重启后行为不稳定。提示两个节点都要做一遍规则文件内容完全一样。备库上如果ls -l /dev/asmdisk*出来的属主不对说明grid用户或asmadmin组还没建回头补第 2 章的用户创建步骤。3.4 grid 用户的环境变量装 GI 之前先把 grid 用户的~/.bash_profile配好安装器会读这些变量。# grid 用户 ~/.bash_profile 追加以下内容 ORACLE_SIDASM; export ORACLE_SID JAVA_HOME/usr/local/java; export JAVA_HOME ORACLE_BASE/app/grid; export ORACLE_BASE ORACLE_HOME/app/product/19.2.0/crs; export ORACLE_HOME ORACLE_TERMxterm; export ORACLE_TERM NLS_DATE_FORMATYYYY:MM:DDHH24:MI:SS; export NLS_DATE_FORMAT NLS_LANGAMERICAN_AMERICA.UTF8; export NLS_LANG TNS_ADMIN$ORACLE_HOME/network/admin; export TNS_ADMIN ORA_NLS11$ORACLE_HOME/nls/data; export ORA_NLS11 PATH.:${JAVA_HOME}/bin:${PATH}:$HOME/bin:$ORACLE_HOME/bin PATH${PATH}:/usr/bin:/bin:/usr/bin/X11:/usr/local/bin export PATH LD_LIBRARY_PATH$ORACLE_HOME/lib LD_LIBRARY_PATH${LD_LIBRARY_PATH}:$ORACLE_HOME/oracm/lib LD_LIBRARY_PATH${LD_LIBRARY_PATH}:/lib:/usr/lib:/usr/local/lib export LD_LIBRARY_PATH CLASSPATH$ORACLE_HOME/JRE CLASSPATH${CLASSPATH}:$ORACLE_HOME/jlib CLASSPATH${CLASSPATH}:$ORACLE_HOME/rdbms/jlib CLASSPATH${CLASSPATH}:$ORACLE_HOME/network/jlib export CLASSPATH THREADS_FLAGnative; export THREADS_FLAG export TEMP/app/tmp export TMPDIR/app/tmp umask 022 export DISPLAY10.6.0.243:0.0 alias sqlplusrlwrap sqlplus alias rmanrlwrap rman alias asmcmdrlwrap asmcmd几个关键点的取舍ORACLE_SIDASM是 ASM 实例的固定 SIDGI 装完之后用ASM连 ASM 实例。NLS_LANG用AMERICAN_AMERICA.UTF8而不是 GBK原文里那行 GBK 是注释掉的因为 19C 默认字符集走 AL32UTF8客户端设成 GBK 会出现中文乱码。umask 022保证安装出来的文件默认权限是 755/644不会因为 umask 太严导致后续读取失败。DISPLAY指向运行 X Server 的那台机器图形化安装必须配否则gridSetup.sh起来就报Cant connect to X11 window server。rlwrap那几个 alias 不是必须的但装了之后sqlplus里能用上下键翻历史命令日常巡检省不少事。3.5 解压 GI 包并跑 gridSetup先确认解压路径和 ORACLE_HOME 一致# 注意 -d 指向的就是 ORACLE_HOME解压完直接在里面跑安装器 unzip V981627-01.zip -d /app/product/19.2.0/crs cd /app/product/19.2.0/crs ls -l gridSetup.sh这一步对应原文那句备注软件会装在gridSetup所在的路径。所以解压目录必须是/app/product/19.2.0/crs不能先解压到/tmp再挪。解压前目录的属主已经是grid:oinstall解压出来的文件会自动继承。然后执行./gridSetup.sh图形界面出来之后按下面这条路径走配置选项选Configure Oracle Grid Infrastructure for a Standalone Server。这套是单实例加 ASM不是 RAC选错了后面会要求配 VIP 和 SCAN。磁盘组磁盘组名填DATA冗余模式选Normal三块盘以上才允许 Normal四块盘刚好。点Change Discovery Path把路径改成/dev/asmdisk*否则它默认只扫/dev/oracleasm/disks扫不到东西。**密码本文还有配套的精品资源点击获取