
最近在 CentOS 8 上做了一回 Oracle 11.2.0.1 的静默安装过程比预想中折腾不少。CentOS 8 本身已经偏向保守而 Oracle 11.2.0.1 又算是老古董级别的版本官方认证早在 RHEL 6 之后就基本停更了大量依赖包和运行库在新系统里要么改名、要么直接消失。这篇文章把我整个操作链路完整记录下来包括环境准备、依赖处理、rsp 响应文件逐项拆解、监听配置、建库验证以及最后那些绕不开的补丁建议。给准备在 CentOS 8以及同源的 Rocky Linux、AlmaLinux上跑 11.2.0.1 的朋友一份可以直接抄作业的参考。1. 先算一笔账CentOS 8 跑 Oracle 11.2.0.1 的兼容性底细1.1 为什么还要用 11.2.0.1很多人可能第一反应是都什么年代了还在装 11.2.0.1但现实就是不少存量系统的业务代码、存储过程、分区逻辑都是基于 11g 写的尤其是一些上了年纪的 ERP、MES 系统直接迁移到 19c 往往牵一发动全身。与其冒着重写 SQL 的风险去升级不如先把现有环境在干净的操作系统上复现出来。11.2.0.1 作为 11g R2 的第一个发行版虽然在后续版本中暴露了不少 bug但它的安装包体积小、对硬件要求低在一些离线环境、内网隔离环境中仍然是很多人手中的“保底方案”。另外一个现实原因Oracle 官方对 RHEL 8 / CentOS 8 从未给出过 11.2.0.1 的官方认证。官方认证列表里 11.2.0.1 支持的最高系统是 RHEL 6但这并不代表完全装不上。社区里大量实践表明只要把依赖库补齐、绕过 OUI 的先决条件检查11.2.0.1 在 CentOS 8 上运行是没问题的。关键是要理解它卡在哪、缺什么而不是一上来就用“系统不兼容”劝退自己。1.2 CentOS 8 带来的三个新麻烦与 CentOS 6/7 相比CentOS 8 在安装 Oracle 11.2.0.1 时主要有三个比较棘手的差异点。第一个是包管理器从 yum 变成了 dnf。虽然 dnf 兼容大部分 yum 用法但仓库结构变了很多老包不在默认仓库里比如compat-libstdc-33需要去 PowerTools 仓库找libXp则干脆被移除了只能手动下载 RPM。如果不知道这些信息光依赖检查就能卡你一整天。第二个是glibc 版本过高。CentOS 8 的 glibc 是 2.28而 Oracle 11.2.0.1 编译时的运行环境要老得多。大部分场景下 Oracle 自身能跑但一些工具会出现奇怪的报错比如imp/exp导入导出时提示缺符号、sqlplus的历史命令乱码等。这类问题没有统一解药通常靠安装后打补丁来缓解。第三个是IPv6 默认开启。CentOS 8 的/etc/hosts会把localhost解析到::1而 Oracle 监听服务对 IPv6 的支持比较保守经常出现lsnrctl start成功但客户端连不上或者监听反复重启的问题。最省心的做法是直接关掉 IPv6或者把监听地址显式绑定到 IPv4 地址。1.3 版本规划与目录设计我这次的目标环境是一台 4 核 8G 内存的虚拟机磁盘 100G操作系统是 CentOS 8.5 Minimal 安装没有图形界面。既然要走静默安装图形环境本来就不需要Minimal 反而更干净。目录规划这部分建议一开始就定下来后面改起来非常麻烦。我采用的是经典 OFA 结构/u01/app/oracle # ORACLE_BASE /u01/app/oracle/product/11.2.0/dbhome_1 # ORACLE_HOME /u01/app/oraInventory # 安装清单目录数据库 SID 我规划为orcl字符集用AL32UTF8内存给 4G 的 40% 左右。这些参数后面都会写进 rsp 文件和 dbca 命令中提前规划能避免反复重装。2. 系统层面的准备依赖包、内核参数、账户与目录2.1 依赖包清单与 compat 库的特殊处理Oracle 11.2.0.1 的安装程序在静默模式下同样会做系统预检查虽然我们可以用-ignoreSysPrereqs跳过检查但缺失的系统库会在后续make编译阶段集中爆发那时候报错会让人抓狂。所以依赖包这一步我建议老老实实全装。在 CentOS 8 上我用的完整安装命令如下dnf install -y binutils compat-libcap1 compat-libstdc-33 \ elfutils-libelf elfutils-libelf-devel gcc gcc-c glibc \ glibc-common glibc-devel glibc-headers ksh libaio libaio-devel \ libgcc libstdc libstdc-devel libXext libXtst libX11 libXau \ libXi make sysstat unixODBC unixODBC-devel libnsl libnsl2 \ libnsl2-devel注意几个坑。compat-libstdc-33在默认 AppStream 仓库里并没有必须先从 PowerTools 仓库装dnf install -y compat-libstdc-33 --enablerepoPowerToolslibXp这个库被 Oracle 的安装程序依赖但 CentOS 8 已经彻底移除。我是在一个有外网的机器上先下载了 el7 的 RPM 包再拷进去装的rpm -ivh libXp-1.0.2-2.1.el7.x86_64.rpm rpm -ivh libXp-devel-1.0.2-2.1.el7.x86_64.rpm如果你是完全离线的环境这个 RPM 必须提前准备好。别指望dnf install libXpCentOS 8 仓库里是真的没有。另外pdksh这个包在 CentOS 8 中早已不复存在用ksh替代即可。如果安装程序日志里还提到pdksh直接用-ignoreSysPrereqs跳过检查就行不影响后续安装。2.2 内核参数与 shell 资源限制Oracle 对内核参数的检查非常严格但如果参数值不满足要求安装程序会直接终止。以下参数是我在/etc/sysctl.conf中写入的值实测在 8G 内存环境下能够满足安装和运行需求fs.file-max 6815744 fs.aio-max-nr 1048576 kernel.shmall 2097152 kernel.shmmax 536870912 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写入后执行sysctl -p使其生效。这里有一个容易忽略的点net.ipv4.ip_local_port_range默认是32768 60999而 Oracle 要求端口范围必须包含 9000 到 65500如果不修改数据库连接多的时候会出现端口耗尽的问题。shell 资源限制同样重要修改/etc/security/limits.conforacle soft nproc 2047 oracle hard nproc 16384 oracle soft nofile 1024 oracle hard nofile 65536 oracle soft stack 10240 oracle hard stack 32768CentOS 8 里还要注意/etc/security/limits.d/20-nproc.conf这个文件它可能会覆盖上面的nproc设置。我直接把oracle用户的 nproc 限制写进了20-nproc.conf中避免被覆盖oracle soft nproc 2047顺便把 IPv6 关掉免得监听出幺蛾子。修改/etc/sysctl.confnet.ipv6.conf.all.disable_ipv6 1 net.ipv6.conf.default.disable_ipv6 1执行sysctl -p后用ip addr确认 IPv6 地址已不生效。2.3 用户、组与目录权限按照 Oracle 安装惯例需要创建三个组和一个用户groupadd oinstall groupadd dba groupadd oper useradd -g oinstall -G dba,oper oracle passwd oracle创建目录结构并授权mkdir -p /u01/app/oracle/product/11.2.0/dbhome_1 mkdir -p /u01/app/oraInventory chown -R oracle:oinstall /u01/app chmod -R 775 /u01/appORACLE_HOME 一级对应dbhome_1目录必须是空的。因为在静默安装时Oracle Universal Installer 会往这个目录里解压文件如果目录里已经有内容安装程序会拒绝继续。这里有个实战经验不要把安装包解压到/tmp下再执行很多 CentOS 8 默认把/tmp挂在独立分区并且可能设置了 noexec。我遇到过runInstaller: Permission denied的诡异问题排查半天才发现是/tmp挂载参数带了noexec。把数据库安装包解压到/home/oracle/或者/u01/下更稳妥。2.4 环境变量配置用oracle用户编辑~/.bash_profile加入以下内容export ORACLE_BASE/u01/app/oracle export ORACLE_HOME$ORACLE_BASE/product/11.2.0/dbhome_1 export ORACLE_SIDorcl export PATH$PATH:$ORACLE_HOME/bin export LD_LIBRARY_PATH$ORACLE_HOME/lib:/usr/lib umask 022LD_LIBRARY_PATH要特别注意。CentOS 8 的libnsl分离成了 32 位和 64 位两套机制如果LD_LIBRARY_PATH配置不正确sqlplus 连接时会报找不到libnsl.so.1之类的错误。把/usr/lib加进去能解决一部分这类问题。3. 静默安装的答卷response file 逐项拆解3.1 rsp 文件从哪里来、要改哪几项静默安装的核心是 response file响应文件它相当于把图形安装界面里的所有选项提前填写好。11.2.0.1 安装包解压后响应文件模板在database/response/db_install.rsp。建议先把模板复制到/home/oracle/下再编辑cp /home/oracle/database/response/db_install.rsp /home/oracle/db_install.rsp chown oracle:oinstall /home/oracle/db_install.rsp下面是我最终使用的关键配置项逐项说明oracle.install.optionINSTALL_DB_SWONLY ORACLE_HOSTNAMEoracle-server UNIX_GROUP_NAMEoinstall INVENTORY_LOCATION/u01/app/oraInventory SELECTED_LANGUAGESen,zh_CN ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 ORACLE_BASE/u01/app/oracle oracle.install.db.InstallEditionEE oracle.install.db.DBA_GROUPdba oracle.install.db.OPER_GROUPoper oracle.install.db.BACKUPDBA_GROUPdba oracle.install.db.DGDBA_GROUPdba oracle.install.db.KMDBA_GROUPdba oracle.install.db.CLUSTER_NODES SECURITY_UPDATES_VIA_MYORACLESUPPORTfalse DECLINE_SECURITY_UPDATEStrue重点解释几个ORACLE_HOSTNAME必须和/etc/hosts里配置的主机名一致。我之前在另一台机器上装的时候这里随便写了个网络域名结果安装程序在验证主机名时直接卡住。oracle.install.optionINSTALL_DB_SWONLY表示只安装数据库软件不创建数据库实例。实例通过后续的dbca单独创建这样更可控也方便把“装软件”和“建库”两个步骤分开排查问题。SELECTED_LANGUAGESen,zh_CN是语言选项。这里不建议只写en因为后续如果要使用中文数据或者中文工具缺少中文字符集会带来额外麻烦。oracle.install.db.InstallEditionEE是企业版。如果机器配置有限可以考虑选择 Standard EditionSE但大部分业务系统默认都按 EE 来装没必要在版本上省。DECLINE_SECURITY_UPDATEStrue表示不接受安全更新这个一定要设为 true否则安装程序会强制联网并弹出配置 My Oracle Support 的交互流程静默安装会直接卡死在那里。3.2 执行 runInstaller 的完整命令与常见报错响应文件准备好后用oracle用户进入解压目录下的database目录执行./runInstaller -silent -responseFile /home/oracle/db_install.rsp -ignoreSysPrereqs-ignoreSysPrereqs非常关键。CentOS 8 的某些发行版信息、包名、内核版本都会让 OUI 判定为“系统不满足要求”如果没有这个参数安装程序会在预检查阶段直接退出连 rsp 文件都不会处理。执行后终端会输出日志路径一般是/tmp/InstallActions时间戳。真正的报错信息都记录在$ORACLE_BASE/oraInventory/logs/installActions时间戳.log里。我强烈建议全程用tail -f盯住这个日志文件不要在黑暗中等待。这个阶段最容易出问题的还是依赖包不完整典型报错是Checking for compat-libstdc-33... not found但凡看到not found就老老实实把缺的包装上再重跑一次。运行安装程序前可以先把rpm -qa的结果和依赖清单对比一遍能省不少时间。3.3 安装过程中的 link 阶段藏雷11.2.0.1 在 CentOS 8 上安装时最大的拦路虎其实是安装后半段的二进制链接阶段。因为 11.2.0.1 版本太老Oracle 的证书和部分 makefile 在较新的系统上会因为时间或库版本问题报错。最常见的是下面这个Error in invoking target install of makefile /u01/app/oracle/product/11.2.0/dbhome_1/ctx/lib/ins_ctx.mk这是 11.2.0.1 的经典 bug根本原因是 Oracle 内部的证书时间已过期导致 interMedia/Context 组件的 make 环节失败。解决办法是修改一个规则文件sed -i s/11.1.0.6;0/11.1.0.6;1/ $ORACLE_HOME/ctx/lib/ctxrules.tf然后再手动重试失败的 make 目标make -f $ORACLE_HOME/ctx/lib/ins_ctx.mk install如果报错是agent nmhs相关的比如Error in invoking target agent nmhs of makefile /u01/app/oracle/product/11.2.0/dbhome_1/sysman/lib/ins_emagent.mk那是因为新的 glibc 和 Oracle 自带的部分组件在符号链接上不兼容给这个 makefile 加上-lnnz11库参数即可绕过sed -i s/\$(MK_EMAGENT_NMHS)/$(MK_EMAGENT_NMHS) -lnnz11/ $ORACLE_HOME/sysman/lib/ins_emagent.mk make -f $ORACLE_HOME/sysman/lib/ins_emagent.mk agent nmhs如果还有其他 makefile 报错先不要慌逐个看日志中失败的是哪一个.mk文件确认是缺库还是缺符号大部分都能通过sed微调 makefile 或手动补装库来解决。这一步确实费时间但只要解决掉ins_ctx.mk和ins_emagent.mk这两个大头剩下的基本都是小事。3.4 以 root 执行脚本的流程安装程序执行到最后会提示你需要用 root 执行两个脚本/u01/app/oraInventory/orainstRoot.sh /u01/app/oracle/product/11.2.0/dbhome_1/root.sh在静默模式下这两个脚本需要手动跑。我习惯在日志里看到提示后立刻切到 root 执行cd /u01/app/oraInventory ./orainstRoot.sh cd /u01/app/oracle/product/11.2.0/dbhome_1 ./root.shroot.sh执行时会询问是否把本地 bin 目录加入 PATH直接回车默认即可。这里要注意root.sh必须一次执行完毕中途不要按 CtrlC否则/etc/oratab等文件会写入不完全后续开机自启会出问题。两个脚本执行完成后回到终端安装程序会自动把剩余流程走完最后显示类似Successfully Setup Software的信息数据库软件部分就算装完了。4. 监听与建库静默模式下最费神的两个环节4.1 netca 静默配置监听软件安装完成后下一步是配置网络监听。Oracle 11.2.0.1 自带 netca 工具支持静默模式$ORACLE_HOME/bin/netca /silent /responsefile $ORACLE_HOME/network/install/netca.rsp这条命令会自动创建listener.ora文件并注册一个名为LISTENER的监听服务。执行完成后用下面的命令确认监听状态lsnrctl status如果看到类似The command completed successfully和Listening Endpoints Summary的输出说明监听已经起来了。但 CentOS 8 上这里很容易翻车最常见的症状是监听启动失败或者启动成功但客户端连接超时。这就要进入排查链路了。4.2 监听无法启动的排查链路ORA-28547 等热搜词里专门有人搜过oracle监听服务无法启动说明这是安装 11.2.0.1 时的重灾区。我结合自己的踩坑经历把排查链路完整理一遍。第一步看错误码。执行lsnrctl start如果报TNS-12545: Connect failed because target host or object does not exist这基本是/etc/hosts里的主机名解析出了问题。检查/etc/hosts127.0.0.1 localhost localhost.localdomain 192.168.1.100 oracle-server注意主机名必须和hostname命令的输出严格一致也不要有多余的空格。很多人喜欢用127.0.0.1 oracle-server这种写法虽然也能通但生产环境建议直接映射到实际的内网 IP。第二步lsnrctl start报TNS-12541: TNS:no listener这通常说明监听进程已经异常退出或者端口被占用。用netstat -tlnp | grep 1521看看端口状态。如果端口被别的进程占了改掉listener.ora里的端口再启动即可。第三步也是最容易和 CentOS 8 关联起来的错误码ORA-28547: connection to server failed, probable Oracle Net admin error这个报错在 11.2.0.1 CentOS 8 的组合里非常邪门。我遇到的那次监听在lsnrctl status里是正常的但客户端一连接就报 28547。排查到最后发现是 OUI 在安装时自动生成的listener.ora把主机名写成了大写字母而/etc/hosts里是小写字母大小写不匹配导致 Net 层校验失败。LISTENER (DESCRIPTION_LIST (DESCRIPTION (ADDRESS (PROTOCOL TCP)(HOST ORACLE-SERVER)(PORT 1521)) ) )把HOST改成/etc/hosts中的实际主机名保持大小写一致然后重启监听lsnrctl stop lsnrctl start另外一个隐藏点如果/etc/hosts里同时存在::1 localhost的记录Oracle 的 Net 配置在解析时有可能优先尝试 IPv6 地址导致连接失败。这也是前面说为什么建议直接关闭 IPv6 的原因。4.3 dbca 静默建库命令与参数监听就绪后我用dbca完成最后的建库操作。静默模式下dbca 的命令行参数非常直观dbca -silent -createDatabase \ -templateName General_Purpose.dbc \ -gdbname orcl -sid orcl \ -sysPassword Oracle123 -systemPassword Oracle123 \ -datafileDestination /u01/app/oracle/oradata \ -recoveryAreaDestination /u01/app/oracle/fast_recovery_area \ -characterSet AL32UTF8 \ -memoryPercentage 40 \ -storageType FS \ -databaseType MULTIPURPOSE逐个参数解释-templateName General_Purpose.dbc通用模板最省心。如果你的业务偏 OLTP有Data Warehouse.dbc模板可选但通用模板兼容性最好。-gdbname和-sid全局数据库名和实例名。我统一设置为orcl。-sysPassword/-systemPasswordsys 和 system 用户的密码。密码复杂度要满足 Oracle 要求纯数字会被拒绝至少要混合大写字母和数字。-datafileDestination数据文件目录。记得到建库前先把目录建好并授权给 oracle 用户。-characterSet AL32UTF8字符集。建议默认就用这个和大多数应用兼容后续遇到中文数据也不会乱码。-memoryPercentage 40数据库使用物理内存的 40%。我这是 8G 内存大约 3.2G 分给 SGA 和 PGA测试环境足够生产环境可以根据实际情况调整到 40%-60%。建库过程大概需要 10 到 20 分钟取决于磁盘速度。日志输出会展示每一步的状态到Database creation complete就说明成功了。由于General_Purpose.dbc在 11.2.0.1 中有时会触发ORA-12547: TNS lost contact的怪问题如果遇到十有八九又是$ORACLE_HOME权限或者$ORACLE_HOME/bin/oracle二进制文件权限不对。执行一下chmod 6751 $ORACLE_HOME/bin/oracle大部分情况下能解决。4.4 装完验证sqlplus 基本检查建库完成后用 oracle 用户做几个最基础的验证sqlplus / as sysdba能进到SQL提示符说明本地认证没问题。接着执行select status from v$instance;看到OPEN状态就是正常的。再查看监听注册情况lsnrctl services确认orcl实例以READY状态注册到了监听器上。如果注册状态是BLOCKED通常说明数据库还在启动过程中等一下再查即可。最后做一次远程连接测试用另一个客户端工具sqlplus system/Oracle123192.168.1.100:1521/orcl能连上整条链路就算通了。5. 事后收尾开机自启、补丁与后续运维习惯5.1 配置 Oracle 随系统启动CentOS 8 使用 systemd 管理服务Oracle 自带的dbstart/dbshut脚本可以被 systemd 托管但配置稍微有点绕。我使用的是比较直接的方式。先修改/etc/orataborcl:/u01/app/oracle/product/11.2.0/dbhome_1:Y最后那个Y表示允许开机自启。这里安装时如果 root.sh 执行得不完整这一行可能是N记得改过来。然后创建 systemd service 文件/etc/systemd/system/oracle.service[Unit] DescriptionOracle Database 11g Afternetwork.target [Service] Typeforking Useroracle Groupoinstall ExecStart/u01/app/oracle/product/11.2.0/dbhome_1/bin/dbstart /u01/app/oracle/product/11.2.0/dbhome_1 ExecStop/u01/app/oracle/product/11.2.0/dbhome_1/bin/dbshut /u01/app/oracle/product/11.2.0/dbhome_1 RemainAfterExityes [Install] WantedBymulti-user.target注意dbstart执行时会依赖$ORACLE_HOME环境变量所以在 systemd 配置中最好把环境变量写进去或者直接在ExecStart前用/bin/bash -c source ...的方式。最简单的办法是在/etc/rc.d/rc.local中追加脚本适合不需要精细控制启动顺序的场景。最后执行systemctl daemon-reload systemctl enable oracle.service systemctl start oracle.service如果启动过程中遇到库找不到的问题在 service 文件里加上EnvironmentLD_LIBRARY_PATH/u01/app/oracle/product/11.2.0/dbhome_1/lib:/usr/lib配好之后重启机器验证一次确认数据库能自动起来。5.2 版本补丁与升级到 11.2.0.4 的建议聊一个比较实际的问题11.2.0.1 装上运行没问题但要不要打补丁升到 11.2.0.4我的建议是如果你有时间装完 11.2.0.1 后最好立刻打 P13390677 补丁包升级到 11.2.0.4。有两个原因一是 11.2.0.1 在编写时对应的是 2013 年左右的操作系统环境很多内存管理、网络栈的兼容逻辑在 CentOS 8 的 4.18 内核上并不能完全发挥性能最典型的是大页内存HugePages支持和MEMORY_TARGET自动内存管理的稳定性。11.2.0.4 补丁包针对这些问题做了大量修复。二是 11.2.0.1 的配套工具exp/imp、SQL*Loader、Data Pump 的部分组件在 CentOS 8 的 glibc 2.28 下偶发段错误升级到 11.2.0.4 之后明显稳定。我曾在 11.2.0.1 上做数据泵导出连续三次都在processing object type TABLE_EXPORT/TABLE时崩溃升级补丁后同一条命令跑完未报错。升级到 11.2.0.4 的大致流程是下载 P13390677 的两个 zip 包先停止数据库和监听解压后放到一个目录执行$ORACLE_HOME/OPatch/opatch apply。整个过程大概 20-30 分钟。opatch版本如果太低还需要先去补丁包里找p6880880升级 OPatch 工具本身。如果项目不允许停机升级那至少要把官方发布的one-off patch中与ins_ctx、emagent、libnsl相关的补丁单独打上。这些东西不处理数据库功能可能不受影响但备份恢复、企业管理器这类周边工具很容易踩雷。5.3 一些老生常谈但值得记住的注意事项在这套环境稳定跑了一段时间后我觉得有几点值得分享给后面接手的运维同行。关于备份装完库第一件事是做一次一致性冷备份把整个/u01/app/oracle/oradata目录连同pfile、spfile一起打包归档。11.2.0.1 环境一旦跑起来往往就是几年不动周围的系统每次升级都可能影响它的运行留一份干净基线比什么都强。关于大页内存如果你的服务器内存大于 32G务必研究一下 HugePages 的配置否则数据库运行一段时间后会出现严重的 CPU 使用率高但业务延迟也高的问题。CentOS 8 下 HugePages 配置需要同时改/etc/sysctl.conf中的vm.nr_hugepages和 Oracle 侧的pga_aggregate_target、sga_target参数让它们互相匹配这是一个独立的优化项目。关于日志清理Oracle 11g 的trace日志、listener.log、alert_log增长速度快得惊人建议在部署时就配上 crontab 定时清理find /u01/app/oracle/diag/rdbms/orcl/orcl/trace -name *.trc -mtime 7 -delete最后再啰嗦一句别在/etc/hosts里加乱七八糟的域名解析Oracle 的网络层对字符串大小写和顺序极其敏感少动就是少出事。这套安装链路里我最想强调的还是那句话11.2.0.1 在 CentOS 8 上不是装不上而是你必须把“系统预期是 RHEL 6”这个事实接受下来所有预检查都不必强求通过真正要盯紧的是后面make阶段的日志。那些报错才是系统真实兼容性的镜子对照日志一项项补最终装出来是能稳定跑的。