☰
无外网环境Oracle静默安装:依赖包、响应文件与避坑实践
2026/10/14 15:51:26 网站建设 项目流程

这标题里说的“无外网”,和你在家断网玩手机不是一回事。真实的场景是:一台内网服务器放在隔离机房里,不能访问外网、没有外部软件源、甚至没法在线同步时间——而应用系统又必须在这个环境里装一套Oracle数据库。最近处理一个内部系统的迁移就撞上了这个局面,整个过程踩了不少坑,我发现无外网安装Oracle的难点其实不在“装”,而在“准备”。这篇文章把我整理出来的完整流程、响应文件写法、依赖清单和几个反直觉的报错一并记录下来,适合第一次接触离线部署的DBA,也适合要进机房前想提前避坑的运维工程师。

1. 隔离环境装Oracle,先想明白这三件事

1.1 “无外网”不是一个状态,而是三种状态

很多人一听“无外网”,下意识就是把安装包拷过去直接装,但实际工作中遇到的隔离环境差别很大,应对策略完全不同。

第一种是彻底的物理隔离,服务器连内网都没有,只能靠移动介质拷贝文件进去。这时候所有东西——安装包、依赖rpm、补丁、响应文件——都必须在外面准备好,少一个文件就得重新跑一趟机房。第二种是可以访问公司内部的软件源或镜像仓库,外部yum源不可达,但内部源里有基础系统包。这种环境最友好,依赖rpm基本上可以用内网yum现拉,难度直接降一档。第三种是有外网但带宽极低或只能短时间联网,比如要求“仅在变更窗口内联网下载”,这时候可以提前在外面把依赖包批量拉下来,再用临时网络传进内网。

判断属于哪种形态是第一优先级。我建议进机房前先确认两件事:目标服务器能不能通过命令行访问任何yum源、有没有内部文件传输的服务。这两个问题决定了你的准备清单是“按计划逐步做”还是“必须一次带齐”。完全隔离时,我一般把依赖包、Oracle安装包甚至备用补丁都放进一个目录,拷进去之后再核对一遍校验值,宁可多带几个包,也不要到现场才发现缺了什么。

1.2 版本选错,这台机器就白折腾了

离线环境下最尴尬的事不是装不上,而是介质本身就不对。比如项目要求19c,但你手里只有11g的安装包,装到一半发现模板文件对不上,最后只能推倒重来。所以在整个流程还没开始之前,先确定目标版本和目标操作系统的组合。

不同的Oracle版本对系统环境的要求差别很大。11gR2在RHEL 7上还算常见,但它依赖的兼容库在新系统里越来越难找;19c在RHEL 7和8上都能安装,但需要额外注意libnsl等基础库;12cR2常见于老项目的补丁基线,部署时往往还要带上后续小版本patch。更关键的是,有的介质是“安装包+补丁”组合,如果没有提前把补丁打进去,后续应用连库时可能遇到协议兼容问题,但离线环境又没法临时下载,只能干等。

我个人的建议是:如果项目没有强制的历史版本约束,离线环境优先选19c。原因有几个:安装介质相对好找,依赖项列表清晰,而且它在主流Linux版本上的官方认证覆盖面广。挑选版本时一定要同时确认操作系统大版本,比如RHEL 7.9和RHEL 8.6对应的安装包可能是同一套,但系统库版本不同,到现场再调整依赖就麻烦了。

1.3 离线安装的核心流程:其实只有四步

抛开各种报错和细节,离线安装Oracle的流程可以压缩成四个阶段:准备、基础环境、软件安装、实例配置。

准备阶段要做的是下载介质、收集依赖rpm、写好安装响应文件以及准备系统参数脚本。基础环境阶段要做的是安装依赖包、创建用户和组、创建目录结构、配置内核参数。软件安装阶段则是解压安装包、以静默模式运行runInstaller、最后执行两个root脚本。实例配置阶段包括设置环境变量、用netca创建监听、用dbca建库,以及配置开机自启。

为什么在线安装通常感觉轻松?因为在线环境下yum会自动拉取依赖,Oracle安装程序也能直接访问官方更新服务,很多前置条件被自动处理掉了。离线环境中,安装程序对依赖的检查是硬性的,缺一个rpm就报错一次。把这些步骤拆开看,每一阶段的准备质量都会直接影响下一阶段能否顺利跑完。下面我会按这个顺序把这四步展开讲,每一步的细节都是实际部署中被验证过的写法。

2. 离线安装前的准备清单,少一样都要返工

2.1 安装介质从哪里来,怎么信任它

离线环境里的所有软件来源,本质上都依赖“外面一台能联网的机器”。Oracle的安装包通常很大,19c的Linux x86-64安装包解压之后差不多8GB以上,传输时间不可忽视,所以第一步是找一份可靠的介质。

我的习惯是在有外网的机器上先下载官方安装包,然后用md5sum或sha256sum记录校验值,拷贝到目标机之后第一时间重新校验。不要只靠“能解开zip”来判断文件完整,Oracle安装包在传输过程中哪怕错一个字节,解压时不一定立刻报错,但装到某个配置助手阶段会莫名失败,排查起来非常痛苦。介质来源最好能从官方渠道或公司内部统一的软件仓库取,渠道越单一,后续对介质版本产生疑惑时越容易定位问题。

传输方式上,如果是彻底隔离的环境,用移动硬盘或光盘拷贝;如果内网有文件传输服务,可以用scp或内网共享目录。需要注意:Oracle安装包解压后的目录结构在Unix-like系统里区分大小写,建议在目标机上用unzip解压,而不是先在Windows上解压再传目录,后者很可能因为文件权限和符号链接丢失导致安装失败。解压后的目录属主改成oracle用户,这一步放在后面用户创建完成后一起做更省事。

2.2 依赖rpm包是离线安装的第一大障碍

在线安装时,如果系统缺少某个库,yum会自动装上;离线环境没有这个待遇。Oracle安装程序对依赖检查很严格,缺一个包就直接中断。

准备依赖包最常用的方法有两种:一种是在有外网的机器上使用yumdownloader --resolve把指定rpm及其依赖全部下载下来,另一种是从操作系统的安装光盘里提取。以CentOS/RHEL 7或8为例,如果目标机有内部yum源,可以直接在目标机上用yum安装依赖,这是最省事的路径;如果没有,就需要在外部机器上批量下载。

假设目标系统是CentOS 7,准备依赖时我一般会执行类似这样的操作:

mkdir -p /tmp/oracle_deps cd /tmp/oracle_deps yum install -y yum-utils yumdownloader --resolve \ binutils compat-libcap1 compat-libstdc++-33 \ gcc gcc-c++ glibc glibc-devel ksh libaio libaio-devel \ libgcc libstdc++ libstdc++-devel libnsl make sysstat

注意--resolve参数很重要,它会自动把依赖这些包的库也一起拉下来。命令执行完后检查目录里的rpm数量,通常会有几十个。把这些rpm全部拷贝到目标机上,然后统一安装:

rpm -Uvh /tmp/oracle_deps/*.rpm

如果目标系统是RHEL 8/Rocky 8,部分老兼容包(比如compat-libstdc++-33)可能无法直接下载,这是正常现象,通常19c在RHEL 8上不再强制要求这个包。Oracle的官方安装文档里会有对应系统的依赖列表,准备介质时最好把那一段说明打印出来对照。

2.3 内核参数、账号组和目录,一次配对的建议

系统层面的参数调整最好在安装Oracle之前一次性做完,因为这些改动有些需要重启才彻底生效,如果等到runInstaller运行到检查阶段再改,会白白浪费一次尝试窗口。

内核参数中比较关键的包括:内存相关的kernel.shmall和kernel.shmmax,信号量相关的kernel.sem,文件句柄相关的fs.file-max,以及异步IO相关的fs.aio-max-nr。我通常会在/etc/sysctl.conf里追加一套基准配置:

fs.file-max = 6815744 kernel.sem = 250 32000 100 128 kernel.shmmni = 4096 kernel.shmall = 1073741824 kernel.shmmax = 4398046511104 net.core.rmem_default = 262144 net.core.rmem_max = 4194304 net.core.wmem_default = 262144 net.core.wmem_max = 1048576 fs.aio-max-nr = 1048576 net.ipv4.ip_local_port_range = 9000 65500 vm.swappiness = 10 vm.dirty_ratio = 40 vm.dirty_background_ratio = 10

这些值必须根据服务器实际内存大小调整,不能照抄。比如shmmax设得比物理内存还大很多时没有实际意义,建议按物理内存的70%到90%估算。执行sysctl -p让配置当前生效,部分参数(如kernel.shmmni)改动后强烈建议重启一次,避免后续数据库启动时报莫名错误。

账号和目录结构关系到后续所有操作权限。标准做法是创建两个组和一个用户:

groupadd oinstall groupadd dba useradd -g oinstall -G dba oracle mkdir -p /u01/app/oracle chown -R oracle:oinstall /u01 chmod -R 775 /u01

oinstall组负责Oracle软件安装的属主权限,dba组用于数据库管理员的系统权限。发展到19c之后,Oracle官方还建议创建oper、backupdba、dgdba、kmdba、racdba等组,但最小化场景下至少保持oinstall和dba即可。还要确认oracle用户的umask是022,否则安装过程中生成的文件权限可能异常,导致后续进程无法读取配置文件。

2.4 进机房前自检清单

准备工作做得越细,现场操作越顺利。我习惯在出发之前把下面这份清单打出来,一项一项勾选:

检查项预期结果验证方式
Oracle安装包完整校验值一致md5sum / sha256sum
依赖rpm齐全目录内rpm数量合理ls /tmp/oracle_deps
磁盘空间充足/u01剩余空间足够df -h /u01
内存与swap不低于安装要求free -h
内核参数已配置sysctl -p无报错执行确认
账号与目录创建完毕oracle用户可登录id oracle
/etc/hosts主机名映射主机名能解析ping 主机名
响应文件就绪参数已按目标机修改打开复查

这套清单看起来简单,但实际排查效率极高。比如/etc/hosts缺少主机名映射这一条,很多人当场发现不了,等到netca配置助手卡住甚至失败时才开始怀疑,然后再回头改,整个安装窗口就被拖长了。装箱单上多花十分钟,现场通常能省下一两个小时。

3. 静默安装全程:从响应文件到root.sh

3.1 解压、校验,先让介质别出错

介质进入目标机后,第一步永远是把校验值核对一遍。这里我习惯用sha256而不是md5,碰撞概率低很多。执行sha256sum和外面的记录比对一致后,再切换到oracle用户解压。

su - oracle cd /u01/app/oracle unzip -q /tmp/介质目录/LINUX.X64_193000_db_home.zip -d /u01/app/oracle/product/19.0.0/dbhome_1

注意Oracle 19c的zip包解压后,dbhome_1必须就是ORACLE_HOME目录本身,不要在dbhome_1下面再套一层目录。解压完之后检查目录权限,确保oracle用户对这些文件有读写权限。传递介质时如果用的是移动硬盘,拷贝完成后最好先umount再重新挂载读取一次,防止缓存带来的假象文件。

3.2 db_install.rsp 里必须写对的关键参数

静默安装的核心是响应文件,它决定安装程序在无交互情况下如何选择安装类型、路径和分组。Oracle安装介质里自带了一个db_install.rsp模板,我的习惯是复制一份出来修改,而不是直接改模板,这样能保留原始参考。

一份最小可用的19c响应文件关键项如下:

oracle.install.option=INSTALL_DB_SWONLY UNIX_GROUP_NAME=oinstall INVENTORY_LOCATION=/u01/app/oraInventory ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 ORACLE_BASE=/u01/app/oracle oracle.install.db.InstallEdition=EE oracle.install.db.OSDBA_GROUP=dba oracle.install.db.OSOPER_GROUP=oper oracle.install.db.OSBACKUP_GROUP=dba oracle.install.db.OSDG_GROUP=dba oracle.install.db.OSKMGMT_GROUP=dba oracle.install.db.OSRAC_GROUP=dba SELECTED_LANGUAGES=en,zh_CN ORACLE_HOME_NAME=OraDBHome1 SECURITY_UPDATES_VIA_MYORACLESUPPORT=FALSE DECLINE_SECURITY_UPDATES=TRUE oracle.install.db.root_config.executeRootScript=false

这里每个参数都值得认真核对。INSTALL_DB_SWONLY表示只安装数据库软件而不建实例,我强烈建议采用这个选项,把建库和配置分开做,因为一旦安装和建库绑在一起,出了问题你需要同时排查两条链路。ORACLE_HOME和ORACLE_BASE必须和实际解压目录完全一致,写错任何一个后续环境变量都会跟着乱。InstallEdition如果误写成SE2,装出来就是标准版,本文后面会专门讲这个坑。executeRootScript=false的含义是让安装程序不要自动执行root脚本,而是等我们手动控制,这一步实际部署中很有用,可以避免root脚本在配置助手尚未准备好时抢先执行。

3.3 runInstaller 执行与日志追踪

一切就绪后,在oracle用户下执行:

cd $ORACLE_HOME ./runInstaller -silent -responseFile /home/oracle/db_install.rsp

如果担心系统检测有偏差导致安装中断,可以临时追加-ignoreSysPrereqs。但我不建议默认加这个参数,它会让安装程序跳过部分环境检查,把隐患留到后面。比较合理的用法是:第一次预检查失败后,查看具体原因并修复,确认是误报时才用-ignoreSysPrereqs绕过。离线环境里最容易误报的一项是网络更新检查,因为完全无外网会导致安全更新配置无法验证,这种情况在响应文件里已经设置SECURITY_UPDATES_VIA_MYORACLESUPPORT=FALSE,一般不会触发。

静默安装不是完全没有输出,只是交互为0。安装过程中可以同时打开两个终端,一个跑安装命令,另一个跟踪日志:

tail -f /u01/app/oraInventory/logs/installActions*.log

日志里会逐条记录依赖检查、文件复制、配置助手执行状态。看到“Completed”之类的字眼,并不代表全部结束,安装命令返回后,屏幕通常会提示需要以root身份执行两个脚本。这时不要急着关终端,先记录返回消息。

3.4 两个root脚本,顺序不能乱

安装结束后的提示里会出现两个脚本路径,一个在/u01/app/oraInventory下,叫orainstRoot.sh,另一个在$ORACLE_HOME下,叫root.sh。

su - /u01/app/oraInventory/orainstRoot.sh /u01/app/oracle/product/19.0.0/dbhome_1/root.sh

第一个脚本负责设置Oracle Inventory目录的属主和权限,第二个脚本负责配置ORACLE_HOME环境、网络服务等相关本地信息。先跑orainstRoot.sh再跑root.sh,顺序反了可能导致权限记录错乱。执行root.sh时如果系统提示主机名解析失败,说明之前在准备阶段漏掉了/etc/hosts那一项,先修复再重新执行,不要硬着头皮继续。

执行完成后,检查一下$ORACLE_HOME/root.sh生成的日志文件,确认没有错误。很多人在这一步只看屏幕上打印的“successful”,忽略了日志里的warning,结果后面监听器配置时才发现问题。

4. 装上只算完成一半:实例、监听和自启

4.1 环境变量:让sqlplus在一个终端里能用

软件安装完成之后,oracle用户的环境变量还没配置。每次登录都手动export太费劲,我习惯把它固化到~/.bash_profile里:

export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 export ORACLE_SID=orcl export PATH=$PATH:$ORACLE_HOME/bin export LD_LIBRARY_PATH=$ORACLE_HOME/lib

ORACLE_SID是实例名,静默建库时指定的SID要和这里一致,否则sqlplus会默认找错实例。LD_LIBRARY_PATH指向$ORACLE_HOME/lib,很多第三方程序和部分Oracle自带工具需要靠这个变量找到动态库。配置完之后source ~/.bash_profile,再执行sqlplus / as sysdba验证,如果提示“不满足权限”之类,说明当前用户不在dba组,或者$ORACLE_HOME/bin下的oracle可执行文件权限不对。

4.2 netca静默创建监听,并验证端口

监听器负责接收外部客户端连接请求。Oracle安装时如果没有选择自动配置监听,就需要手动用netca创建。最简方式是在oracle用户下直接执行:

$ORACLE_HOME/bin/netca -silent

netca会在默认位置生成listener.ora和sqlnet.ora,监听默认端口1521。执行完用lsnrctl status查看状态,如果显示“no listener”,检查$ORACLE_HOME/network/admin/listener.ora是否存在,以及/etc/hosts里主机名映射是否正确。确认监听端口在系统防火墙里也是放开的,特别是很多内网服务器默认开了firewalld或iptables,1521端口没放行的话,客户端在本机连没问题,跨机器一定连不通。

4.3 dbca静默建库:字符集和内存的取舍

建库是数据库管理员最常手动执行的一步。dbca同样支持静默模式,下面是一个常用的建库命令示例:

$ORACLE_HOME/bin/dbca -silent \ -createDatabase \ -templateName General_Purpose.dbc \ -gdbName orcl \ -sid orcl \ -sysPassword Oracle123 \ -systemPassword Oracle123 \ -memoryPerc 40 \ -characterSet AL32UTF8 \ -emConfiguration NONE \ -datafileDestination /u01/app/oracle/oradata \ -recoveryAreaDestination /u01/app/oracle/fast_recovery_area

选General_Purpose.dbc模板最通用,适合绝大多数业务系统,不需要在一开始就纠结是数据仓库还是事务处理。密码必须满足Oracle的复杂度要求,长度不少于8位、包含大小写和数字,很多首次部署的人在这一步被反复退回来。memoryPerc表示把系统内存的多少百分比分配给数据库内存区,在一个专门跑数据库的机器上我建议40到50,如果机器还跑其他应用就降到30以下。

字符集需要提前想清楚。AL32UTF8是当前新项目的主流选择,多语言支持和扩展性都好;ZHS16GBK在老系统中很常见,中文占用字节更少,但如果你后续要和其他UTF8系统交换数据,转换会很痛苦。我的原则是新库一律UTF8,除非有明确的存量数据兼容要求。

建库过程通常持续20到40分钟,期间不要干别的,因为日志会实时反映建库进度。完成后用sqlplus / as sysdba登录,执行select status from v$instance;确认实例是OPEN状态。

4.4 开机自启:systemd接管Oracle的守护

数据库不是装完能启动就结束,重启服务器后能不能自动起来才是生产级别的关键。Oracle有自己的dbstart脚本,配合/etc/oratab可以管理实例启停。需要先编辑/etc/oratab,把实例那一行的末尾改成Y:

orcl:/u01/app/oracle/product/19.0.0/dbhome_1:Y

然后在systemd里创建一个服务单元,例如/etc/systemd/system/oracle-db.service:

[Unit] Description=Oracle Database Service After=network.target [Service] User=oracle Group=oinstall Type=forking Environment=ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1 Environment=ORACLE_SID=orcl ExecStart=/u01/app/oracle/product/19.0.0/dbhome_1/bin/dbstart $ORACLE_HOME ExecStop=/u01/app/oracle/product/19.0.0/dbhome_1/bin/dbshut $ORACLE_HOME Restart=on-failure [Install] WantedBy=multi-user.target

执行systemctl daemon-reload、systemctl enable oracle-db、systemctl start oracle-db。这里需要注意,dbstart脚本不只启动实例,还会启动该ORACLE_HOME下的所有监听器,所以如果netca那一步没配好,dbstart可能会连带失败。服务启动后确认一下监听和实例状态,再把机器重启一次做完整验证,这是离线部署环境中最值得做的一个闭环测试。

5. 我在离线安装中实际踩过的五个坑

5.1 依赖“装了”和“满足”是两回事

有一次在RHEL 8机器上装19c,我明明把所有官方文档列出来的依赖包都装了,runInstaller还是直接报缺少libnsl.so.1。当时很困惑,rpm -qa | grep libnsl能看到包存在,为什么还报缺?

后来用yum list available libnsl.i686才发现,系统里装的是64位libnsl,但安装程序检查时可能要32位版本。RHEL 8以后部分库的32位包不再默认随系统安装,需要单独补齐。另一个更隐蔽的情况是,某些库虽然存在,但版本符号不满足,Oracle检查的是库里的符号表,而不只是包名。排查这类问题时,最有效的方式是看Oracle安装日志里针对具体库的检查项,再配合ldd $ORACLE_HOME/bin/oracle | grep "not found"定位是哪个动态库缺失。不要盲目在网上搜索“缺少xxx”,先确认架构和版本符号,否则绕一大圈还在原地。

5.2 netca没跑起来,主机名解析背锅

有一次整个安装过程看起来很正常,runInstaller也跑完了,root脚本也执行了,但监听器就是起不来,lsnrctl status报“TNS-12537: TNS:connection closed”。打开$ORACLE_HOME/cfgtoollogs/netca/下的日志,发现netca在创建默认监听器时尝试解析主机名失败。

原因就是目标机的/etc/hosts里没有写入机器自身的主机名映射。很多Linux服务器默认只配了localhost,Oracle的配置助手会尝试用hostname命令的结果去本地解析,解析不了就直接失败。修复方法很简单,把类似下面一行加进/etc/hosts:

192.168.10.20 mydb-server

然后重新执行$ORACLE_HOME/bin/netca -silent,监听器立刻正常。这个坑的高发点在于:安装过程本身不一定报错,可能只在某些配置助手阶段悄悄失败,所以让人误以为是监听配置步骤本身出了问题。

5.3 内核参数改完没生效,数据库启动才报错

还有一次,我配置好内核参数之后顺手执行了sysctl -p,以为万事大吉。结果数据库建完之后启动,报了一个ORA-27102: out of memory的错误,检查物理内存明明还有富余。

问题出在kernel.shmall和kernel.shmmax这两个参数上。sysctl -p可以加载配置,但部分内核参数如果想在运行中的系统里彻底生效,必须重启,否则当前内核仍然沿用旧值。Oracle数据库启动时需要申请大块共享内存,如果shmall设置得比实际需要小,就会出现“内存充足但申请失败”的反直觉现象。处理方法是把参数值改大,写入/etc/sysctl.conf,然后执行sysctl -p临时生效;如果系统显示参数值已经变新但仍不生效,那就只能重启后再验证。这种错在离线环境里特别容易让人怀疑是安装包问题,实际是内核参数和系统状态不一致。

5.4 安装版本误选为SE,装完才发现功能缺

响应文件里oracle.install.db.InstallEdition这个参数看起来不起眼,但它直接决定你装的是企业版还是标准版。有一段时间我使用的是旧模板,里面写的是SE2,结果装机全程零报错,数据库也能正常跑,直到应用方要求启用某个企业版特性时才发现版本不对。

这个坑最难受的地方在于,它不会在安装阶段暴露任何问题。数据库、监听、实例全部正常,连sqlplus / as sysdba都能登录,只有当你深入使用某个高级功能时才暴雷。解决方案没有捷径,只能在启动安装前反复确认响应文件里的版本参数,同时打开安装日志里关于版本选择的段落,如果日志显示的是“Standard Edition”,果断中断安装。离线环境重装成本极高,这一步的核对时间花得绝对值。

5.5 ORACLE_SID没导出,dbca就罢工

建库过程中最常见的一个“伪错误”是:dbca执行到一半时报ORA-12560: TNS: protocol adapter error,看起来像监听器问题,于是去折腾listener.ora和防火墙,浪费了不少时间。

其实在一台刚装完Oracle数据库软件、还没建库的机器上,这个报错大概率是因为当前终端没有导出ORACLE_SID。dbca需要知道要操作哪个实例,而它获取实例名的途径之一就是环境变量。如果.bash_profile里没有export ORACLE_SID=orcl,或者source时机不对,dbca就找不到实例,然后报出误导性极强的TNS错误。遇到这个报错先执行echo $ORACLE_SID,为空就到.bash_profile里补上,再重新source一次,很多时候问题就没了。这个细节在在线安装教程里几乎没人提,在离线环境里因为操作步骤多,反而更容易被带上弯路。

操作了这么多次离线安装,我最大的体会是:无外网环境的成败,80%在准备阶段就决定了。安装本身可能只需要半小时,但把依赖、参数、响应文件和介质全部理清楚,往往需要大半天。现在每次做这类部署,我都会顺手把依赖包目录、响应文件和校验清单打包成一份“部署归档”,下次换一台机器,改一下主机名和ORACLE_SID就能复用。隔离环境里的问题都是线性的,前面每省下一次返回机房的次数,后面就给整个项目的交付节奏多留出一点余量。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询