“无外网”三个字,一看到我就知道这项目不简单。很多搞运维的朋友平时联网装Oracle习惯了,yum一配、rpm一下载,半小时环境就绪。但一旦碰上机房隔离、专网环境、等保测评要求物理断开外网的项目,那才是真正考验基本功的时候——所有依赖包都要自己提前想清楚,ISO镜像得提前打包,装到一半发现缺个libaio真的会让人血压飙升。我这篇就围绕“无外网情况下安装Oracle”这个场景,把整个离线安装的完整链路拆开揉碎讲清楚,从准备工作、仓库规划、依赖处理到静默安装和常见翻车点排查,全部以实际项目中的操作经验为主线,你能直接照着做。
1. 项目概述:离线部署Oracle到底难在哪
先说清楚这项目的本质:在无法访问互联网、没有软件源、没有yum仓库的隔离网络环境里,完成Oracle数据库(这里以单机版为主)从介质准备到建库启库的全过程。它不只是一个安装动作,而是覆盖了整个交付链路——包括安装前的依赖评估、安装介质的离线打包、系统环境的预先配置、静默安装参数设计,以及安装后的初始化验证。
1.1 为什么“无外网”会让安装难度翻倍
很多人觉得Oracle安装难,是因为图形界面交互复杂、参数多。但真正做过离线部署的人都明白,联网环境下你遇到报错还能去搜、去下载、去补包;一旦断了外网,安装过程被卡住就是真的卡住了,所有缺失的依赖、冲突的版本、缺失的内核参数调整,都只能靠你自己事先预判并准备好。
我接手过一个银行类的模拟项目:数据库服务器在独立网段,安全策略要求彻底封锁对外访问,所有软件必须通过内部统一的介质审批流程进入。那台机器连基础编译工具都没有,装Oracle得先解决操作系统的依赖层,再解决数据库本身的安装,整个过程足足花了两个半天。其中一半时间不是装数据库,而是在跟各种“缺包”“版本不对”“内核参数没生效”打架。
经历了那个项目之后我总结出一个结论:**无外网安装Oracle,90%的工作量其实是在安装之前完成的。**准备得越充分,真正安装的过程就越顺。
1.2 离线部署的三种常见场景
在聊具体操作之前,先帮你对对场景,因为不同场景的处理策略完全不同:
第一类是“完全隔离网络”——数据库服务器所在网段和外网物理隔离,也没有内部软件源。这种最严格,所有介质必须提前通过离线方式带入,依赖包一个都不能少。
第二类是“受限网络”——服务器能上内网,但内侧软件源不完整或者需要审批。这种情况可以自己在内网搭建一个软件仓库镜像,比纯靠离线RPM包轻松不少。
第三类是“只通特定地址”——比如能访问公司内部的NTP、文件服务器,但访问不了公共软件源。这种情况可以把依赖包放在内部文件服务器上,通过网络分发代替U盘拷贝。
这篇博文以第一类场景为主,因为只要能搞定完全离线,剩下两种基本都是降维打击。
1.3 本项目的适用对象
这篇内容适合这几类人看:负责数据库安装交付的实施工程师、需要在内网环境搭数据库的开发人员、刚接触Oracle但公司网络管控比较严格的运维新人。即便你手头暂时没有离线安装需求,把依赖预判思路和静默安装这套过一遍也会很有收获——因为很多排查经验,联网环境下反而不容易触发。
2. 离线安装的整体设计思路
离线安装Oracle不是简单地把安装包拷到服务器上再双击,它是一套完整的链路。无论装的是Oracle 11g还是19c,整体思路基本一致,我按步骤逻辑给你拆开。
2.1 介质规划:第一步就定成败
离线安装的介质清单包括三大块:Oracle数据库安装包、依赖RPM包合集、操作系统基础镜像或内部软件源备份。
其中Oracle安装包通常分为两个zip文件(比如19c的LINUX.X64_193000_db_home.zip),必须把两个文件都传上去再解压到同一个目录,不能只传一半。依赖包这块最容易被低估,不同操作系统版本、不同内核版本,缺的包都不一样。我建议不要靠记忆“大概需要哪几个”,直接在联网环境上准备好后统一拉取。
具体操作思路是:在一台相同操作系统的联网机器上,提前准备好所有依赖,然后用脚本打包。RPM包获取方式不依赖外部命令的话,可以从系统安装ISO的Packages目录里提取,也可以从同一版本系统的缓存目录拷贝。推荐经验是:安装介质中一定要带上操作系统对应的ISO镜像或完整Packages目录,遇到缺包时可以直接本地解包找,不用干瞪眼。
2.2 依赖预判:用“干跑”代替试错
Oracle安装服务器要求很多依赖:binutils、compat-libcap1、compat-libstdc++、gcc、gcc-c++、glibc、glibc-devel、ksh、libaio、libaio-devel、libgcc、libstdc++、libstdc++-devel、libXext、libXtst、make、sysstat、unixODBC、unixODBC-devel等等……这只是基础名单,根据系统版本还会缺别的。
我的习惯做法是这样的:先在机器的root用户下执行Oracle安装前的检查脚本(也就是runInstaller的预检查部分),等它把缺的东西列出来之后,再统一从介质中补。但因为离线环境下载一次成本很高,所以更好的做法是:把所有可能用到的依赖一次性都备齐,宁可多带,不可少带,这样现场最稳。
一个实用技巧:在准备依赖的时候,用yumdownloader把依赖包全部下下来会附带自动解析,比如:
yumdownloader --resolve --destdir=/opt/oracle_deps binutils gcc libaio libaio-devel如果你用的系统不支持这个命令也没关系,直接在ISO的Packages目录里按名字匹配手工拷贝就行。离线环境下,只要有了一个完整的Packages目录,依赖问题基本就解决了一半。
2.3 系统层面的一次性配置清单
软件包之外,Oracle安装还强依赖系统参数。很多安装失败案例并不是包的问题,而是内核参数或用户配置没提前到位。离线安装尤其麻烦的是:一旦安装过程跑到一小半发现内核参数不对,即使改完也要从头来,时间成本很高。
所以我习惯在动手前把系统状态的配置做成一个检查表:
- 关闭防火墙和SELinux(或设置为 Permissive)
- 配置 /etc/hosts 保证主机名能解析到本地IP
- 创建 oracle 用户和 oinstall、dba 用户组
- 设置oracle用户的环境变量(ORACLE_HOME、ORACLE_BASE等)
- 配置内核参数:kernel.sem、kernel.shmall、fs.file-max、net.ipv4.ip_local_port_range等
- 设置资源的限制:/etc/security/limits.conf中的nofile、nproc、stack配置
- 关闭透明大页(THP)或调整到madvise,避免性能坑
检查表写好后贴在一个文本文件里,现场逐条核对。不要嫌麻烦,这一步出问题后面全折腾你。
3. 安装前的环境准备:每一条都别跳过
准备阶段是整个离线安装的底盘,这部分做得扎实,后面几乎不会出幺蛾子。我按照实际操作顺序一条条讲详细。
3.1 操作系统层面的准备
先把SELinux和防火墙处理掉。SELinux建议直接改为permissive,防火墙在测试环境里可以关掉,生产环境如果策略不允许关,至少要把Oracle需要的1521端口放通。
# 修改 SELinux 配置 sed -i 's/^SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config setenforce 0 # 关闭防火墙(测试环境推荐) systemctl stop firewalld systemctl disable firewalld主机名和hosts解析也很重要。Oracle对主机名的解析方式很敏感,反解失败会导致监听器起不来。我预处理的标准写法是:
hostnamectl set-hostname oradb01 echo "192.168.10.20 oradb01" >> /etc/hosts内核参数方面,直接贴一段我常用的/etc/sysctl.conf追加内容,注意数值在不同内存环境下可以等比调整:
fs.aio-max-nr = 1048576 fs.file-max = 6815744 kernel.sem = 250 32000 100 128 kernel.shmall = 1073741824 kernel.shmmax = 4398046511104 kernel.shmmni = 4096 net.core.rmem_default = 262144 net.core.rmem_max = 4194304 net.core.wmem_default = 262144 net.core.wmem_max = 1048576 net.ipv4.conf.all.rp_filter = 2 net.ipv4.conf.default.rp_filter = 2 net.ipv4.ip_local_port_range = 9000 65500 vm.swappiness = 10 vm.dirty_ratio = 60 vm.dirty_background_ratio = 30改完别忘了执行sysctl -p让它生效。如果对共享内存参数没把握,保守配置也不会错,只要 kernel.shmall 不小于内存页数、kernel.shmmax 不小于物理内存的一半,就基本没啥问题。
limits.conf 里的资源限制,我通常这么配:
oracle soft nproc 2047 oracle hard nproc 16384 oracle soft nofile 1024 oracle hard nofile 65536 oracle soft stack 10240 oracle hard stack 32768注意:这里生效需要确认/etc/pam.d/login里包含session required pam_limits.so,否则配了也白配。这也是离线安装很少人留意但很关键的一环。
3.2 用户和环境变量配置
创建Oracle用户和用户组,命令没什么特别的:
groupadd oinstall groupadd dba useradd -g oinstall -G dba oracle passwd oracle目录结构我一般按Oracle官方推荐来:
mkdir -p /u01/app/oracle/product/19.3.0/dbhome_1 mkdir -p /u01/app/oracle/oradata mkdir -p /u01/app/oracle/fast_recovery_area chown -R oracle:oinstall /u01/app chmod -R 775 /u01/apporacle用户的环境变量,我习惯写到.bash_profile里:
export ORACLE_BASE=/u01/app/oracle export ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1 export ORACLE_SID=orcl export PATH=$ORACLE_HOME/bin:$PATH export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib有一点要提醒:不同版本的ORACLE_HOME路径结构不同,11g常见是/u01/app/oracle/product/11.2.0/dbhome_1,19c和以后版本则统一了版本路径。你在现场执行时以自己装的版本为准,别机械照抄。
3.3 依赖RPM包的离线准备和安装
到了离线安装最关键的一步:RPM依赖。当年我在现场踩过的最大坑就是以为带够了包,结果装到校验阶段报缺compat-libstdc++,而那个包又不包含在ISO默认仓库里。
所以正式建议是:在联网的相同版本机器上,一次性把依赖包拉全。命令大概是这样的:
mkdir -p /opt/oracle_deps yumdownloader --resolve --destdir /opt/oracle_deps \ binutils compat-libcap1 compat-libstdc++-33 \ gcc gcc-c++ glibc glibc-devel ksh libaio libaio-devel \ libgcc libstdc++ libstdc++-devel libXext libXtst \ make sysstat unixODBC unixODBC-devel下载完成之后,记得重点检查 compat-libstdc++ 相关的几个包是不是真的拉到了,这个最容易漏。现场执行安装时统一用:
cd /opt/oracle_deps rpm -Uvh *.rpm如果担心有版本冲突,可以先rpm -qa查询现状再决定。我建议不要急着-Uvh一把梭,分两批装:核心编译相关一批,libXext、libXtst等图形库一批,这样出问题定位更快。
如果你连yumdownloader都用不了,还有一个更朴素的方案:从操作系统ISO的Packages目录里直接把缺的包抠出来拷贝过去。前提是安装介质版本和服务器系统版本一致,RHEL的ISO基本覆盖了全部依赖,唯独compat包可能需要另想办法。另外,有些系统上用yum install --downloadonly也能实现类似效果,但离线现场就别指望这些了,带介质才是王道。
提示:检查是否装了某个包,可以用
rpm -q 包名;批量检查就在依赖目录下执行rpm -Uvh --test *.rpm做一次预演,不真正安装,只看会不会报依赖缺失。这个“预演安装”的习惯能帮你提前发现所有坑。
4. 核心实操:离线安装Oracle的完整流程
前面所有准备工作就绪,真正安装Oracle本体反而是最流程化的部分。我以Oracle 19c为例讲讲完整流程,因为19c是当前离线部署中最常见的版本。
4.1 安装介质的上传与解压
先把两个zip包传到服务器上。推荐放到/u01/app/oracle目录下,然后切到oracle用户解压:
su - oracle cd /u01/app/oracle unzip -q LINUX.X64_193000_db_home.zip -d /u01/app/oracle/product/19.3.0/dbhome_1这里有个关键点:如果你解压时用的是root用户,后面运行安装命令时会出现文件属主和权限不对的问题,所以要么用oracle用户解压,要么解压后整体chown。
4.2 静默安装的响应文件设计
Oracle安装支持三种方式:图形交互、静默命令行、模板响应文件。离线环境的服务器通常没有图形界面,所以必须走静默安装,核心就是一个响应文件。
响应文件的内容很多,但最关键的就是下面这几个参数,一定要结合实际规划填对:
oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v19.0.0 oracle.install.option=INSTALL_DB_SWONLY UNIX_GROUP_NAME=oinstall INVENTORY_LOCATION=/u01/app/oraInventory ORACLE_BASE=/u01/app/oracle ORACLE_HOME=/u01/app/oracle/product/19.3.0/dbhome_1 oracle.install.db.InstallEdition=EE oracle.install.db.rootconfig.executeRootScript=false oracle.install.db.OSDBA_GROUP=dba oracle.install.db.OSOPER_GROUP=dba oracle.install.db.OSBACKUPDBA_GROUP=dba oracle.install.db.OSDGDBA_GROUP=dba oracle.install.db.OSKMDBA_GROUP=dba oracle.install.db.OSRACDBA_GROUP=dba oracle.install.db.config.starterdb.type=GENERAL_PURPOSE oracle.install.db.config.starterdb.globalDBName=orcl oracle.install.db.config.starterdb.SID=orcl oracle.install.db.config.starterdb.characterSet=AL32UTF8 oracle.install.db.config.starterdb.memoryLimit=2048 oracle.install.db.config.starterdb.password.ALL=YourStrongPassword SECURITY_UPDATES_VIA_MYORACLESUPPORT=false DECLINE_SECURITY_UPDATES=true有两点特别注意:第一,响应文件里不能出现中文字符或者特殊符号,否则解析会报错;第二,SECURITY_UPDATES_VIA_MYORACLESUPPORT和DECLINE_SECURITY_UPDATES这两个参数必须在有外网的安装中设为false和true,否则安装流程会去联网检查更新,离线环境下会卡住或超时。
4.3 执行安装命令与root脚本处理
响应文件准备好后,切到oracle用户执行:
su - oracle cd $ORACLE_HOME ./runInstaller -silent -responseFile /u01/app/oracle/install.rsp -ignorePrereq注意最后那个-ignorePrereq参数。官方建议不要轻易用它,但在离线环境下,因为你没法联网运行某些远程校验,加上内核参数差异很大,不加这个参数经常会在预检查阶段停下。我的实际经验是:预检查报的问题如果是依赖缺失,先补齐再忽略;如果只是一些非关键项的警告,用-ignorePrereq跳过问题不大。
安装到执行完会提示你用root用户去跑两个脚本,一个是oraInventory的orainstRoot.sh,一个是ORACLE_HOME下的root.sh。这一步千万别偷懒:
/u01/app/oraInventory/orainstRoot.sh /u01/app/oracle/product/19.3.0/dbhome_1/root.sh跑完root.sh,软件安装部分就算正式完成了。
4.4 静默建库与启动实例
装了软件不算完,数据库实例还得建。有两种方式:一种是在响应文件里直接配置建库参数,另一种是装完软件后再用DBCA静默建库。我更推荐第二种,因为更灵活,不用在安装阶段把所有参数定死。
DBCA静默建库命令如下:
dbca -silent -createDatabase \ -templateName General_Purpose.dbc \ -gdbname orcl -sid orcl \ -characterSet AL32UTF8 \ -totalMemory 2048 \ -sysPassword YourStrongPassword \ -systemPassword YourStrongPassword \ -storageType FS \ -datafileDestination /u01/app/oracle/oradata \ -recoveryAreaDestination /u01/app/oracle/fast_recovery_area \ -emConfiguration NONE执行完之后,数据库会自动创建并启动。你可以用以下命令验证状态:
sqlplus / as sysdba SQL> select status from v$instance;如果返回OPEN,说明建库成功。然后配置监听:
netca -silent -responsefile $ORACLE_HOME/assistants/netca/netca.rsp lsnrctl start lsnrctl status到这里,一个完整的离线Oracle实例就起来了。
4.5 一个完整的SQL验证脚本
我习惯建完库立刻跑一组检查脚本,确认基础功能正常,顺便把表空间、用户状态、字符集都过一遍。下面这段我实测大量使用:
-- 检查实例状态 select instance_name, status, database_status from v$instance; -- 检查数据库状态 select name, open_mode from v$database; -- 检查字符集 select * from nls_database_parameters where parameter='NLS_CHARACTERSET'; -- 查看默认表空间和用户 select tablespace_name, status from dba_tablespaces; -- 创建一张测试表并插入数据验证读写 create table sys.test_tab (id number, name varchar2(50)); insert into sys.test_tab values (1, 'offline test'); commit; select * from sys.test_tab;通过这套验证,你的离线安装才算真正闭环。
5. 常见问题与排查技巧实录
离线安装Oracle,坑是必然的,但大多数坑其实高度相似。我把这些年踩过的问题按出现频率排个序,每一条都是一线实战总结,适合打印出来现场对照。
5.1 依赖缺失类问题
最经典报错就是RPM check failed或者Missing required RPM。有一次我在现场看到提示说缺libnsl.so,以为是某个包没装,查了一圈才发现是compat库版本带错了。这个问题的解决思路是:先看报错字眼,然后把缺少的库名用rpm -qf反查到对应的包名,再去Packages目录里找同名包补装。
一个实操技巧:在所有RPM安装结束时统一做一次rpm -V验证,或者干脆在跑Oracle安装前执行ldconfig -p | grep 缺失库名,确认动态库能被系统正常加载。如果库文件在但ldconfig没加载,可能是安装RPM时ldconfig没刷新,执行一遍ldconfig就好。
5.2 预检查卡住或误报
离线环境下预检查(Prereq Checks)经常卡在联网检测一步。报错信息里通常会有Port 443、oasis.oracle.com之类的字样。遇到这种别慌,直接把响应文件里那两个安全更新参数置成false和true,然后-ignorePrereq重跑。
还有一次预检查报“物理内存不足”,但free -h看明明有32G。后来发现是内核参数vm.nr_hugepages配置得太大,把大页内存占满了。把hugepages调小或者干脆关掉(echo never > /sys/kernel/mm/transparent_hugepage/enabled),再跑预检查就过了。
5.3 权限和属主问题
安装目录权限不对是离线环境高频问题。典型现象是:oracle用户没有/u01/app下目录的读写权限,安装到一半报cannot create log file。解决很简单,安装前用root确认chown -R oracle:oinstall和chmod -R 775全部到位。
另外,如果你把安装包解压到了/root或/tmp下,oracle用户根本无法读取,这也是很容易忽略的点。我的习惯是所有Oracle相关文件要么在/u01下,要么在$ORACLE_HOME下,避免跨目录权限绕来绕去。
5.4 监听器起不来的排查路径
监听器起不来,多半不是因为端口占用,而是hosts解析和主机名不匹配导致的。执行lsnrctl start报TNS-01154或TNS-12545时,先检查/etc/hosts有没有把主机名正确指向本机IP,然后检查/etc/nsswitch.conf里hosts是否配置了真正的DNS解析方式。
另一个不太容易发现的问题是主机名带有大写字母或下划线,Oracle的解析器在这种环境下容易出现怪问题。生产服务器主机名规范建议全小写、无特殊字符、不超过15个字符。
5.5 一次真实的故障复盘
我遇到过一次印象很深的安装失败案例:数据库软件装完了,DBCA建库时报ORA-27102: out of memory。当时第一反应是物理内存不够,结果free一看8G内存完全够。最后定位到原因是kernel.shmall和kernel.shmmax配置有问题——共享内存参数设小了,SGA申请不出足够的内存。
现场调整/etc/sysctl.conf里的kernel.shmmax和kernel.shmall后执行sysctl -p,并且重启了数据库再重新建库,问题才彻底解决。
这个案例给我们的教训是:离线环境下别急着把“内存不足”归咎于硬件,先看共享内存参数和系统限制,通常真正的坑都在这些被忽略的底层配置上。
| 现象 | 可能原因 | 第一排查动作 |
|---|---|---|
| 预检查堵在联网更新 | 安全更新参数未屏蔽 | 检查响应文件两个安全参数 |
| RPM校验失败 | 缺compat包 | rpm -qa比对后补装 |
| 目录无法创建 | 属主或权限不对 | ls -ld检查oracle用户权限 |
| 监听器起不来 | hosts解析异常 | cat /etc/hosts+nsswitch.conf |
| 建库报ORA-27102 | 共享内存参数异常 | sysctl -p后复验ipcs -lm |
6. 离线安装全流程速查清单
最后给你整理一份走查清单,按顺序打勾操作,现场照着做基本不会再出大问题。
- 盘点机器资源:内存、磁盘、OS版本、架构(x86_64还是aarch64)
- 规划目录结构:ORACLE_BASE、ORACLE_HOME、数据文件目录
- 准备依赖包:在联网环境用yumdownloader拉全,或从ISO Packages目录复制
- 准备Oracle介质:两个zip包或一个安装目录都要完整
- 系统配置:SELinux、防火墙、hosts、内核参数、limits.conf全部改好
- 创建用户组和用户:oinstall组、dba组、oracle用户
- 设置目录属主:/u01/app整体chown给oracle:oinstall
- 解压安装包:oracle用户操作,确认文件属主
- 写响应文件:参数务必全英文,密码复杂度要满足要求
- 静默安装:runInstaller相关命令,必要时加-ignorePrereq
- 执行root脚本:orainstRoot.sh和root.sh一个都不能少
- 建库:DBCA静默建库,设置字符集和内存参数
- 配置监听:netca静默配置,lsnrctl启动验证
- 功能验证:SQL脚本建表、插入、查询一条龙
- 备份介质:安装包和依赖目录最好保留在案,方便后续扩容或复制
这份清单也是我每次交付离线数据库的默认交付文档之一,你可以直接粘下来稍作修改就去用。我个人在实际操作中的体会是,离线安装Oracle本质上不是技术难题,而是细致活。所有报错都可以在准备阶段通过“预演”提前发现,真正的安装过程反而安静得让人怀疑是不是还没开始。只要你把依赖、权限、内核参数这三座大山提前安排好,后面就是一马平川。希望这篇能帮你在下一个隔离环境项目里少熬几个夜。