
内网服务器装Oracle我把踩过的坑都写在里面了刚接手一批内网生产服务器的时候我差点被离线安装Oracle这件事整崩溃。网上的教程九成都是在线安装——yum装依赖、wget拉安装包、联网跑root脚本看着很顺滑但搁在不通外网的机房环境里这些操作全部作废。你只能靠自己手里那几张ISO、一堆rpm包以及最原始的命令行工具把Oracle数据库从零到一地装起来还要保证监听能起、实例能建、应用能连。这篇博文就是把我这几次离线安装Oracle的完整思路、操作步骤和踩过的坑整理出来。无论你是要装单机版做测试还是给生产环境搭一套内网数据库这套流程都可以直接参考。我会重点讲离线场景下最麻烦的依赖收集、静默安装参数、监听故障这几个环节你照着走基本能顺利落地。1. 动手前必须想明白的三件事1.1 你的离线环境到底离线到什么程度很多人在网上提问离线怎么装Oracle但离线的标准其实不太一样。我遇到过三种情况第一种服务器本身没有外网但同机房的跳板机、运维终端能上网。这种情况最好办你可以从跳板机上把需要的rpm包下载好再通过内网传过去。第二种所有机器都完全内网隔离但公司自己搭了内网Yum源、镜像仓库。这种情况依赖包可以直接从内网源拉Oracle介质也能从公司文件服务器拿。第三种纯物理隔离什么都没有只有一组安装光盘和Oracle安装包。这种情况下所有依赖只能从光盘里翻Oracle还得确认是完整包而不是需要联网下载的瘦身版。不同离线程度对应的准备工作完全不同。建议你动手前先把网络拓扑和介质清单摸清楚别一上来就闷头找依赖。我就吃过这个亏——有一次没确认介质完整性带着一个只有基础安装文件的Oracle包去了现场装到一半报缺少组件来回折腾了两天才把包补齐。1.2 依赖问题才是离线安装的真正难点在线装Oracle一条yum install oracle-database-preinstall就把系统参数、依赖包全解决了。离线环境里你没法享受这种待遇只能手动处理两件事rpm依赖包和内核参数。Oracle 11g/12c/19c 对操作系统的依赖包还算稳定翻来覆去就是 libaio、glibc、libnsl、compat-libcap1、compat-libstdc、elfutils-libelf、ksh 这几类。但问题在于不同Linux发行版、不同版本对这些包的名字和版本要求有差异CentOS 7、CentOS 8、Ubuntu、麒麟系统之间包名和依赖树完全是两回事。我建议你在有网络的机器上先准备好两样东西一个是Oracle官方文档里对应操作系统版本的依赖包清单一个是依赖包的rpm文件本身。到现场之后不要盲目安装先用 rpm 的查询命令逐个比对缺哪个装哪个避免把整个系统依赖搞乱。1.3 安装策略图形界面还是静默安装离线环境很少有完整的图形桌面即便有Oracle安装程序用X11转发也经常出问题。我实践下来最稳的方案是静默安装利用Oracle自带的 responseFile 应答文件和-silent参数全程命令行操作不需要X窗口。但静默安装对参数的准确性要求很高路径写错一个字符就得重新来。所以我的建议是在同等环境比如本机虚拟机先走一遍完整安装找到最合适的应答文件参数组合再到目标服务器执行。这相当于把试错成本放在可控环境里生产服务器只做一次成型。另外要提前规划好安装用户、目录结构和监听端口。Oracle要求不能用root直接安装必须创建专属用户比如 oracle安装目录的属主、权限、空间都要提前确认。我见过有人把所有东西都装到/根分区下结果到最后空间不足只能全盘重来。2. 离线依赖包收集三条路线的优缺点对比2.1 路线一在联网机器上用 yumdownloader 批量拉取如果你有一台可以上网、且操作系统版本与目标机基本一致的机器这是效率最高的一条路。核心思路是先用 yum 模拟安装时解析出所有依赖再用 yumdownloader 把rpm包全部下载下来。# 在联网机器上执行 # 安装 yum-utils 工具包 yum install -y yum-utils # 创建一个空目录用于下载所有依赖 mkdir -p /root/oracle-rpms cd /root/oracle-rpms # 下载 oracle-database-preinstall 及其全部依赖 yumdownloader --resolve --destdir/root/oracle-rpms oracle-database-preinstall # 如果你的Oracle版本没有对应的preinstall包也可以用 yumdownloader 拉取核心依赖 yumdownloader --resolve --destdir/root/oracle-rpms \ binutils compat-libcap1 compat-libstdc-33 gcc gcc-c glibc glibc-devel ksh \ libaio libaio-devel libgcc libstdc libstdc-devel libXext libXtst \ libX11 libXau libXi make sysstat unixODBC unixODBC-devel--resolve选项会自动把依赖树里的所有rpm都拉下来非常省事。下载完成后把这些rpm文件打包传到内网机器执行rpm -Uvh *.rpm即可。这条路线的坑在于如果目标服务器是多网卡、做了bond或者配置了特殊网络策略的机器依赖包版本可能在个别环境下不一致。所以安装完后一定要对照上一节的清单逐个核对。2.2 路线二从系统安装光盘里找rpm如果连联网机器都没有但手上有操作系统安装光盘或ISO镜像也可以从光盘里翻出大部分依赖包。CentOS/RHEL 的光盘里自带Packages目录几千个rpm包躺在里面Oracle需要的那些基础依赖大多能从这里找到。# 挂载光盘或ISO镜像 mount -o loop /path/to/CentOS-7-x86_64-DVD-2009.iso /mnt/cdrom # 进到包目录 cd /mnt/cdrom/Packages # 查找是否包含目标包 ls | grep -E ^libaio|^glibc-devel|^compat-libstdc用光盘做依赖源的优点是完全断网可用缺点是版本可能偏旧且部分包如 compat-libcap1、compat-libstdc-33在较新版本的光盘里可能已经不再带了。这种时候你需要去别的配套光盘比如扩展包光盘或者找旧版本的系统光盘来补缺。2.3 路线三借助createrepo搭建本地Yum源依赖文件收集齐了之后统一把它们做成一个本地Yum源是一个很好的习惯不建议直接用rpm -ivh逐个安装。因为依赖包之间互相有依赖关系手工程序容易装了A发现缺B装了B又说要和A冲突。用 createrepo 做一个离线Yum源然后在目标机上指向该源让 yum 自动解析依赖出错概率会低得多。# 在装有依赖rpm的目录下生成元数据 yum install -y createrepo createrepo /root/oracle-rpms # 编写 repo 配置文件 cat /etc/yum.repos.d/oracle-local.repo EOF [oracle-local] nameOracle Local Dependencies baseurlfile:///root/oracle-rpms enabled1 gpgcheck0 EOF # 清理缓存并测试 yum clean all yum makecache yum install -y oracle-database-preinstall这一步做完依赖问题基本就解决了。本地Yum源还有另一个好处后续如果还需要装别的软件比如unzip、vim只要把对应rpm丢进这个目录刷新一下repos就能继续用yum管理不用每次都在网上现找。2.4 依赖包收集的查漏补缺技巧哪怕你下载了全套依赖到现场还是可能漏一两个。这时候不要急着瞎装先用系统自带的 rpm 校验工具检查缺什么# 检查某个包是否已安装 rpm -q libaio libaio-devel glibc-devel compat-libstdc-33 # 用 rpm 验证待安装包的依赖是否全部满足 rpm -Uvh --test oracle-database-preinstall-*.rpm--test参数非常有用它只做模拟安装不会真正改动系统却能准确列出缺少的依赖。看到error: Failed dependencies之后按提示补齐对应rpm再来一遍--test直到没有任何报错再真正执行。3. 静默安装的全过程从应答文件到数据库实例3.1 内核参数、用户和目录是必须先做的前置工作Oracle安装对系统参数有硬性要求这些参数如果不提前设好安装程序会在前检测阶段直报错甚至无法继续。以下是我整理的一个常用配置基线适用于CentOS 7/8 类环境# /etc/sysctl.conf 追加以下内容 cat /etc/sysctl.conf EOF 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 EOF # 使参数生效 sysctl -p同时还需要创建 oracle 用户、用户组和安装目录groupadd oinstall groupadd dba useradd -g oinstall -G dba oracle mkdir -p /u01/app/oracle chown -R oracle:oinstall /u01/app/oracle chmod -R 775 /u01/app/oracle对于/etc/security/limits.conf也要加上oracle用户的资源限制。尤其要关注 nproc 和 nofile 这两项很多数据库连接数上不去、进程数上限不够导致实例启动失败就是这两个参数没设置好。3.2 应答文件静默安装的灵魂Oracle安装包解压后在database/response/目录下能找到三个模板文件db_install.rsp、dbca.rsp、netca.rsp。静默安装前你需要把db_install.rsp复制出来并修改关键字段。cp /path/to/database/response/db_install.rsp /home/oracle/db_install.rsp chown oracle:oinstall /home/oracle/db_install.rsp chmod 755 /home/oracle/db_install.rsp重点修改以下几项# 安装类型只装数据库软件 oracle.install.optionINSTALL_DB_SWONLY # 版本和目录 UNIX_GROUP_NAMEoinstall INVENTORY_LOCATION/u01/app/oraInventory 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_GROUPdba需要注意INVENTORY_LOCATION这个路径。Oracle会用它记录所有安装组件的清单如果该目录属主不对安装时会直接报权限错误。另外ORACLE_HOME的路径层级是有规范的不能随便取名否则后面的工具脚本可能因为路径层级不匹配而找不到某些配置。3.3 执行安装runInstaller 的常用参数全部准备就绪后用 oracle 用户执行安装命令su - oracle cd /path/to/database ./runInstaller -silent -responseFile /home/oracle/db_install.rsp \ -ignorePrereqFailure \ -showProgress-si这个参数的作用是当某些非关键的前置检测不过时不阻断安装进程。但切记它只能跳过非关键项如果是内核参数、依赖缺失这类硬性条件不满足跳过之后安装过程中照样会失败。安装过程中建议打开另一个终端实时观察日志输出。Oracle会把日志写到$ORACLE_BASE/cfgtoollogs/dbua/以及/tmp/installActions*.log。如果等了很久没有进展或者日志卡在某个百分比不动多半是某个可执行文件权限不对、或者临时目录满了。安装完成后Oracle提示需要以root身份执行两个脚本oraInventory目录下生成的orainstRoot.sh以及$ORACLE_HOME下的root.sh。这一步绝对不能偷懒。我曾经试过不执行 root.sh 继续建库结果监听配置、权限相关的操作全出现异常最后查来查去发现就是这里漏了。3.4 用netca和dbca静默配置监听与建库软件装完后接着用 netca 和 dbca 创建监听和数据库实例这两个工具同样支持静默模式。配置监听$ORACLE_HOME/bin/netca /silent \ -responseFile $ORACLE_HOME/network/install/netca.rsp监听默认端口是1521如果你所在的内网环境里1521被其他服务占用可以在$ORACLE_HOME/network/admin/listener.ora里手动改端口。改完之后用lsnrctl start启动然后用lsnrctl status确认监听状态。创建数据库实例$ORACLE_HOME/bin/dbca -silent \ -createDatabase \ -templateName General_Purpose.dbc \ -gdbName orcl \ -sid orcl \ -sysPassword SysPassword123 \ -systemPassword SystemPassword123 \ -storageType FS \ -datafileDestination /u01/app/oracle/oradata \ -recoveryAreaDestination /u01/app/oracle/flash_recovery_area \ -characterEventSet AL32UTF8 \ -memoryPercentage 30 \ -emConfiguration NONE这里有几个参数值得说两句。-characterSet AL32UTF8建议在首次建库时就明确指定如果建完之后再改字符集很容易出现数据乱码和ORA-12712之类的报错。-memoryPercentage 30是根据服务器内存情况分配SGAPGA占比生产环境建议你根据业务量调优而不是直接用默认值。-emConfiguration NONE是关掉Enterprise Manager内网环境没必要开还能省掉相关进程资源。dbca建库耗时不短日志在$ORACLE_HOME/cfgtoollogs/dbca/orcl/下。看到Database creation complete基本就成了。4. 监听起不来、ORA报错离线安装后的典型故障排查4.1 监听服务无法启动的完整排查链路这是离线安装后最常见的故障热搜里也有oracle监听服务无法启动这么一个长期霸榜的条目。我自己在安装现场至少遇到过三次每次原因都不太一样。这里把排查链路完整写出来。第一步先用状态命令确认监听到底卡在哪lsnrctl status lsnrctl start如果lsnrctl start报TNS-12541: TNS:no listener或者TNS-12560: TNS:protocol adapter error第一反应先看端口占用netstat -tlnp | grep 1521端口没被占用的话接下来看 hosts 和 listener.ora 配置。Oracle监听对这个文件里的主机名或IP非常敏感。我也犯过这样的错——安装时服务器的hostname带了一个奇怪的短域名listener.ora里代码自动生成的host就是那个短域名结果监听死活起不来。解决方法是直接把 listener.ora 里的 HOST 改为服务器实际分配的IP地址然后重启监听。第二步如果监听进程虽然起来了但lsnrctl status显示 The listener supports no services这说明数据库实例没有向监听注册。多数原因是实例还没完全启动或者local_listener参数没配对。执行以下SQLALTER SYSTEM SET local_listener(ADDRESS(PROTOCOLTCP)(HOST192.168.1.10)(PORT1521)) SCOPEBOTH; ALTER SYSTEM REGISTER;再把服务手工注册一下监听状态里就能看到对应的服务名了。第三步用tnsping验证网络层通不通。如果tnsping能通但应用连接还是报错重点检查tnsnames.ora里的服务名是否和lsnrctl status里显示的服务名完全一致。4.2 ORA-12514和ORA-01034的快速定位思路ORA-12514TNS: listener does not currently know of service requested in connect descriptor这个报错出现的频率非常高。大部分人第一时间去改 tnsnames.ora但其实绝大多数情况问题出在实例没有注册到监听。我的排查思路是先执行lsnrctl services看监听识别到的服务名列表。如果列表为空回到4.1的注册流程如果列表里有和连接串不一致的名字把 tnsnames.ora 里的 SERVICE_NAME 改成监听实际注册的那个名字。ORA-01034ORACLE not available则是实例层面的问题。建议按以下顺序排查先ps -ef|grep smon确认实例是否存活再sqlplus / as sysdba进去看数据库状态状态显示MOUNTED但没OPEN用alter database open打开。如果连 STARTUP 都做了还是不行看看$ORACLE_HOME/dbs里的参数文件、密码文件是否存在权限是不是oracle用户。离线环境最容易出现的问题就是密码文件缺失因为初始化脚本没跑全。4.3 12c之后的卸载残留问题热搜里有一条12c删除不干净oracle这个问题值得单独提一下。12c和更高版本的Oracle引入多租户架构CDB/PDB卸载时的残留文件比11g更多常见的有三类第一类/etc/oratab里残留的实例启动项。卸载后这个文件不会自动清理导致重启机器时Oracle尝试去启动已经不存在的实例报错但不影响系统运行很烦人。手动编辑该文件删掉对应行即可。第二类$ORACLE_BASE/cfgtoollogs和$ORACLE_HOME下遗留的日志、跟踪文件。Oracle官方其实提供了deinstall命令但很多人不知道仍然手动删目录。手动删也问题不大关键是删除顺序先删数据库dbca -silent -deleteDatabase再删监听netca -silent -deconfigure最后删软件deinstall。顺序反了后面步骤会拿不到实例信息只能硬删。第三类/etc/oraInst.loc文件。它记录了Inventory的位置如果不删重装Oracle时安装器会认为系统里已有旧版本导致无法安装。重新安装前记得把它和对应的 Inventory 目录一起清掉。4.4 离线环境下打补丁的注意事项生产环境装完Oracle后打补丁是绕不开的一步尤其是11.2.0.4这类经典版本补丁集经常要打到最新的PSU。在线环境可以用 OPatch 自动从网络下载但离线环境必须手工把补丁包传到服务器上。打补丁前先确认两件事# 确认OPatch版本是否满足补丁要求 $ORACLE_HOME/OPatch/opatch version # 确认当前补丁基线 $ORACLE_HOME/OPatch/opatch lsinventory补丁包通常是一个zip文件里面有patch目录和README.txt。严格按照README里的顺序执行第一步通常是在sqlplus里执行alter system set _use_single_log_writertrue之类的预检查操作第二步是opatch apply第三步是跑数据字典升级脚本catupgrd.sql或者catbundle.sql。我踩过的坑是打完补丁没有跑数据字典脚本结果应用一上来就报 ORA-00600后来才反应过来是数据字典版本和二进制版本不匹配。所以打完补丁后务必在日志里确认二进制补丁和SQL补丁两步都执行成功缺一个都不行。5. 国产系统环境下的离线安装补充5.1 与CentOS差异巨大的发行版要先做兼容性验证热搜词里有linux国产随着国内自主操作系统的普及在统信UOS、麒麟、龙蜥、欧拉这些系统上装Oracle的需求已经越来越多了。国产系统虽然大多基于Linux内核但包管理器、glibc版本、系统目录结构都有不同程度的改动不能拿CentOS的经验直接套。例如在麒麟V10上compat-libstdc-33这个包名可能不存在替代的方案是安装当前系统的libstdc.so.6兼容版本或者直接做一个软链接指向已有库。又比如某些国产系统默认没有/u01这样的挂载点规划文件系统目录结构更靠近/data需要你在应答文件里修改所有路径。我的建议是去现场之前先在相同版本的国产系统虚拟机里做一次完整的安装演练。这一步能发现八成以上的兼容性问题省去在现场反复试错的痛苦。5.2 重新打包安装目录的复制部署方案如果目标机器数量比较多比如一堆内网测试服务器都要装Oracle一台一台静默安装的效率会很低。另一个思路是找一台环境完全一致的机器装好Oracle并打好补丁然后打包整个$ORACLE_HOME、$ORACLE_BASE再拷贝到其他机器上做解压部署。这个方案有几个前置条件一是所有机器操作系统版本、内核参数完全一致二是解压后必须重新执行 root.sh 和 orainstRoot.sh三是要重新配置监听和实例名不能直接用原机器的。虽然稍显粗暴但操作熟练之后单台机器的部署时间能从两小时压缩到二十分钟以内。5.3 把准备工作脚本化省掉重复劳动离线安装的整个流程里有大量重复性的准备工作创建用户、改内核参数、配置limits、解压安装包。我习惯把这些操作整理成一个初始化脚本在每台机器上先执行一遍。#!/bin/bash # oracle_preinstall.sh # 创建用户和目录 groupadd -f oinstall groupadd -f dba id oracle /dev/null 21 || useradd -g oinstall -G dba oracle mkdir -p /u01/app/oracle chown -R oracle:oinstall /u01/app/oracle # 内核参数 cat /etc/sysctl.conf EOF 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 EOF sysctl -p # 资源限制 cat /etc/security/limits.conf EOF oracle soft nproc 2047 oracle hard nproc 16384 oracle soft nofile 1024 oracle hard nofile 65536 oracle soft stack 10240 oracle hard stack 32768 EOF echo Oracle preinstall configuration completed.每次到新环境先跑一遍这个脚本再进入Oracle安装流程能大幅度降低低级错误的出现概率。6. 我的一点个人经验总结离线安装Oracle这件事本质上考验的不是你对Oracle命令的熟练程度而是你对环境差异的预判能力。看再多的教程都不如自己完整地走过一遍从依赖收集到建库的流程。我在前几次安装时也踩了不少坑但有一个很深的体会凡是遇到离奇的报错先别急着搜索解决方案而是按顺序检查基础环境——文件权限、目录属主、hosts配置、内核参数——十次里有八次问题都出在这些低级环节。如果你准备在近期做离线安装我的建议是先在虚拟机里完整跑一遍把依赖包清单、应答文件参数、初始化脚本都在虚拟机里验证好。到生产环境时你会发现自己手里的材料已经足够应付绝大多数情况了。后面如果再遇到比较有代表性的故障我还会继续整理分享。