
1. 整体设计与落地思路拆解1.1 为什么必须离线安装离线安装到底难在哪先说说我碰到的实际场景。接手一台新上架的Linux服务器放在客户机房内网安全策略非常严格这台机器不能访问外网。客户要求部署Oracle数据库作为生产系统核心库。线上环境无法用yum install直接拉依赖也下载不了Oracle安装包所有软件必须提前在能联网的机器上准备好再用U盘或内网传输工具拷过去。这种场景在企业里太常见了政府项目、银行项目、制造业内网十有八九都是离线环境。离线安装的难点本质上是三个一是安装介质从哪来二是系统的依赖库怎么补齐三是安装过程中Oracle的图形界面用不了必须靠静默配置文件来完成。很多新手第一次搞离线Oracle不是卡在Oracle本身的安装反而是卡在系统依赖装不齐或者X11转发转发不了图形界面打开一片空白。这些坑我都踩过这篇就是把这套完整的流程走一遍把会踩的坑提前标出来。1.2 安装前的版本选型和整体流程规划离线安装第一步不是找安装包是确定Oracle版本。目前国内存量最多的还是Oracle 11g R211.2.0.4虽然官方早已停止普通支持但很多老业务系统跑在上面稳定压倒一切。而2019年之后的机器很多客户会指定装Oracle 19c因为19c是12c/18c之后的长支持版本技术路线相对干净。不同版本对应的系统要求略有差异。11g R2建议配CentOS 7.x、RHEL 7.x内核版本3.10以上。19c则建议RHEL 7.6以上或8.x对glibc的要求也更高。我下面主要以Oracle 11.2.0.4 CentOS 7.9这套组合来做整体讲解因为这套装法最普遍架构最典型。19c在安装思路上完全一致就是依赖包列表和内核参数的初值略有差别我会在对应章节里标出来。整个离线安装的流程我会按照下面这条线走准备好安装介质Oracle的zip包和依赖库的rpm包在目标服务器上挂载系统镜像配置本地YUM源解决依赖库问题调整内核参数、创建用户和目录结构编写静默安装响应文件responseFile执行安装用netca静默配置监听用dbca静默建库启动数据库并做基本验证这套流程做下来一台Oracle单机库从零到能建库跑SQL熟练的话五六个小时就能搞定。第一次搞建议预留一整天因为依赖和权限问题总是会在意想不到的地方冒出来。2. 环境准备与离线依赖库补齐2.1 离线依赖库准备的三种方案先说依赖库的问题。Oracle安装时会调用系统命令和动态库缺少任何一个都会在环境检查阶段报错压根不让你继续。在线环境一条yum install -y就完事离线环境就必须提前准备好rpm包。我常用的有三种方案按省事程度排序第一种在有外网的同版本机器上用yumdownloader工具把相关依赖rpm全部拉下来然后拷到目标机器安装。命令大概是mkdir /root/oracle-deps cd /root/oracle-deps yumdownloader --resolve --destdir/root/oracle-deps binutils compat-libcap1 compat-libstdc-33 gcc gcc-c glibc glibc-devel ksh libaio libaio-devel libgcc libstdc libstdc-devel libXext libXtst libXau libXi libXrender make sysstat unixODBC unixODBC-devel--resolve参数会把依赖包一并下载非常方便。注意目标机器的系统版本要一致CentOS 7.9拉出来的rpm不能直接装到RedHat 8上版本不匹配会报依赖冲突。第二种直接把系统安装镜像里的Packages目录整体拷到目标机器然后配置成本地YUM源。这种方式相当于把整个系统软件仓库搬到了内网后面装任何软件都能解决依赖不只是Oracle需要的那几个包。第三种Oracle官方文档的依赖清单里有些包在CentOS默认镜像里本来就有比如binutils、glibc这种基础包。如果目标机器上之前有别的应用很可能已经装了一部分。所以装依赖之前先检查一遍缺什么补什么没必要无脑全部装一遍。2.2 配置本地YUM源让服务器可以离线“联网”我自己最推荐的是第二种方案把镜像Packages目录拷过去之后配置本地YUM源。这样以后在离线环境装任何软件都不用再折腾依赖成本一次投入长期受益。具体操作先把系统ISO镜像挂载或者把Packages目录通过U盘拷贝到/opt/centos-packages。然后新建一个repo文件mkdir -p /opt/centos-packages # 假设ISO已经挂载在 /mnt/iso cp -rp /mnt/iso/Packages/*.rpm /opt/centos-packages/ # 初始化createrepo的元数据CentOS 7自带 createrepo如果没有需要另行安装 createrepo /opt/centos-packages/然后写repo配置[local-repo] nameLocal CentOS Repository baseurlfile:///opt/centos-packages enabled1 gpgcheck0执行yum clean all yum makecache之后就能用yum install正常安装本地仓库里的软件了。这里有个细节CentOS 7.9镜像里包比较全但有些Oracle需要的包比如compat-libstdc-33在默认镜像里可能没有它在AppStream或Extras里这个时候还是要靠第一种方案从外网下载。2.3 图形界面用不了那就放弃图形界面Oracle 11g和12c的安装程序如果没有图形界面默认会尝试调用X11连接。在离线服务器上十有八九没有显示器也没有图形环境哪怕用XShell的X11转发也经常卡在半路。这是我第一次安装时浪费最多时间的地方。后来我学乖了全部用静默模式。静默安装本质上是一个Java程序读取你预先填好的响应文件然后自动完成安装动作。整个过程只会在控制台打印日志不需要任何图形交互。这不光解决了无图形界面的问题还让安装过程可以完全脚本化部署效率大幅提升。Oracle的响应文件在安装包解压后的response/目录里有模板比如db_install.rsp。安装前把它拷贝出来填好关键参数然后通过-silent参数指定它系统就会按配置走完整个安装流程。3. 内核参数、用户与目录规划3.1 内核参数调整确保数据库运行的基础环境Oracle数据库对Linux内核参数有硬性要求不符合的话安装程序会在环境检查时直接给出警告或直接终止。建议在安装前就手工把参数改好避免安装中途被打断。编辑/etc/sysctl.conf加入以下推荐参数以11g为例fs.aio-max-nr 1048576 fs.file-max 6815744 kernel.semmsl 250 kernel.semmns 32000 kernel.semopm 100 kernel.semmni 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 vm.max_map_count 655360改完执行sysctl -p使其生效。这里面我最常被人问到的就是kernel.sem四个值——semmsl、semmns、semopm、semmni分别表示每个信号量集合的最大信号量数、系统中信号量总数上限、每个信号量操作的最大次数和系统级信号量集合数。Oracle的进程间通信大量依赖信号量如果配置过小数据库启动时会报出ORA-27300之类的错误。vm.max_map_count这个参数在Oracle 19c里尤其重要因为数据库对内存映射区域的要求更高默认的65530很容易不够用导致实例无法启动建议直接放宽到655360不会有副作用只是增加虚拟内存映射上限。3.2 创建Oracle用户和环境变量Oracle不允许直接用root来安装和运行数据库。官方建议是创建一个专门的oracle用户归属oinstall和dba两个组。实际操作中我通常会一并创建好因为后面建监听和建库都要用这个用户。groupadd oinstall groupadd dba useradd -g oinstall -G dba oracle passwd oracle创建完成之后通过id oracle确认一下用户组归属确认没问题再往下走。Oracle用户需要设置环境变量主要是ORACLE_BASE、ORACLE_HOME、ORACLE_SID和PATH。这里有个容易弄混的地方ORACLE_BASE是Oracle安装的根路径ORACLE_HOME是具体版本软件的安装路径。按OFAOptimal Flexible Architecture规范来我习惯将路径设置为export ORACLE_BASE/u01/app/oracle export ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 export ORACLE_SIDorcl export PATH$ORACLE_HOME/bin:$PATH写入~/.bash_profile即可。注意如果安装的是Oracle 19cORACLE_HOME路径中版本数字会不同但结构思路一样。还有一个小细节Oracle 11g的ORACLE_HOME路径层级会比ORACLE_BASE多两层这个在后续建库和打补丁时都会用到路径别记错。3.3 目录创建与权限设置安装Oracle之前需要把软件安装目录创建好并且把属主改成oracle用户。这个操作看起来简单但目录权限不对会导致安装程序无法写入报OUI-10086之类的权限错误。mkdir -p /u01/app/oracle chown -R oracle:oinstall /u01注意这里把/u01整层都授权给oracle:oinstall了因为Oracle安装过程中会创建/u01/app/oraInventory以及/u01/app/oracle下的子目录。如果/u01是独立挂载的数据盘还要确认挂载参数里没有noexec选项否则安装程序在解压和运行二进制时会直接被系统拒绝。3.4 检查系统资源限制Oracle还要求对oracle用户设置进程数和文件描述符限制编辑/etc/security/limits.conforacle soft nproc 2047 oracle hard nproc 16384 oracle soft nofile 1024 oracle hard nofile 65536 oracle soft stack 10240同时还要确认/etc/pam.d/login中有session required pam_limits.so这一行CentOS 7默认有。这步不做的话数据库启动时后台进程可能因为文件句柄耗尽而异常退出日志里跟着就会出现ORA-12547: TNS:lost contact这类信息很隐蔽。4. 安装Oracle软件与静默配置4.1 解压Oracle安装介质准备响应文件拿到linux.x64_11gR2_database_1of2.zip和linux.x64_11gR2_database_2of2.zip之后两个包都要解压到同一个目录下11g分两个包19c只有一个。解压后会出现一个database目录里面就有runInstaller和response子目录。unzip p13390677_112040_Linux-x86-64_1of7.zip unzip p13390677_112040_Linux-x86-64_2of7.zip解压完检查一下database目录的所有者。我遇到过一种情况U盘和压缩包是从Windows传过来的解压后文件所有者是root如果不提前chown -R oracle:oinstall database安装程序在写临时文件时会出现Permission denied。然后把db_install.rsp拷贝出来备用cp database/response/db_install.rsp /home/oracle/ chown oracle:oinstall /home/oracle/db_install.rsp4.2 响应文件核心参数逐个解读db_install.rsp里的参数非常多大部分保持默认就好但有几个是必须改的直接决定安装结果。我列一下最核心的几个oracle.install.responseFileVersion/oracle/install/rspfmt_dbinstall_response_schema_v11_2_0 oracle.install.optionINSTALL_DB_SWONLY ORACLE_HOSTNAME你的主机名 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 oracle.install.db.config.starterdb.typeGENERAL_PURPOSE oracle.install.db.config.starterdb.globalDBNameorcl oracle.install.db.config.starterdb.SIDorcl oracle.install.db.config.starterdb.memoryLimit800 oracle.install.db.config.starterdb.password.ALL你的数据库密码 DECLINE_SECURITY_UPDATEStrue这里oracle.install.optionINSTALL_DB_SWONLY表示只装数据库软件不建库。建库放到后面用dbca单独做这样更可控也符合生产环境的一般做法——软件和数据库实例分开管理。密码字段在11g的静默安装中如果不设置安装到一半会卡住等交互所以务必提前填好。4.3 静默执行runInstaller响应文件准备好之后切换到oracle用户进入database目录执行安装cd /home/oracle/database ./runInstaller -silent -responseFile /home/oracle/db_install.rsp电脑屏幕会开始滚动日志整个安装过程大概20到40分钟取决于磁盘速度和CPU性能。如果一切顺利最后日志中会出现类似Successfully Setup Software的字样。这里要提醒一下即使静默安装正常结束程序最后还是会提示你需要用root账号去执行两个脚本orainstRoot.sh和root.sh。这两个脚本必须在安装结束后立刻执行否则Oracle的初始化和权限设置不完整。/u01/app/oraInventory/orainstRoot.sh /u01/app/oracle/product/11.2.0/dbhome_1/root.shroot.sh执行的时候会询问是否把Oracle的二进制链接到/usr/local/bin问y即可。这是Oracle 11g很经典的一步别跳过。4.4 静默配置监听器和实例软件装完之后数据库还处于“没实例、没监听”的状态。下一步就是配置监听器。直接用netca静默模式跑一下netca -silent -responseFile $ORACLE_HOME/assistants/netca/netca.rspnetca会自动读取/etc/hosts里的主机名和IP信息生成listener.ora文件。它默认监听的是1521端口。如果客户内网端口被占用了之后可以手改$ORACLE_HOME/network/admin/listener.ora把PORT换成空闲端口然后重启监听。监听启动后用它来建库。建库用dbca静默模式一次命令直接生成一个完整实例dbca -silent -createDatabase \ -templateName General_Purpose.dbc \ -gdbname orcl -sid orcl \ -responseFile NO_VALUE \ -characterSet AL32UTF8 \ -memoryPercentage 40 \ -emConfiguration NONE这里面-characterSet AL32UTF8是我个人的习惯字符集一定要在建库前指定好因为建库之后改字符集非常痛苦不光是ALTER DATABASE一句命令的问题还涉及到已有数据的转码风险。-memoryPercentage 40表示用服务器物理内存的40%来分配SGA和PGA具体比例根据业务调整一般OLTP系统给50%左右比较合适。建库过程根据机器性能大约需要10到30分钟。完成后日志中会出现Database creation complete然后就可以用sqlplus / as sysdba连接验证了。5. 常见问题与排查技巧实录5.1 环境检查不通过报依赖缺失这是离线安装中被问得最多的一个问题。静默安装如果遇到环境不符合要求默认会直接终止日志里会明确提示缺失的软件包。比如最常见的是Checking for compat-libstdc-33... not found Checking for libaio-devel... not found解决办法就是前面说的提前把rpm包准备好在安装Oracle之前rpm -ivh装好。这里有个技巧如果yum本地源配好了直接yum install -y compat-libstdc-33 libaio-devel也是可以的不需要手动一个个装。如果不确定缺哪些包可以先把Oracle安装包里的runInstaller用-prereqChecker参数跑一遍它会只检查环境不安装软件直接把缺少的依赖列出来./runInstaller -silent -responseFile /home/oracle/db_install.rsp -prereqChecker输出结果中Passed表示通过Failed列出异常项。这个方式比猜要快得多。5.2 磁盘空间不足或swap偏小Oracle安装时会检查两个空间一是/tmp目录至少需要1GB以上可用空间否则安装程序在解压临时文件时会报Not enough space二是swap交换分区11g建议至少2GB如果内存2GB以下swap至少要是内存的2倍。服务器配置比较老的情况下swap不足是常见问题。扩容swap的办法dd if/dev/zero of/swapfile bs1G count4 chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo /swapfile swap swap defaults 0 0 /etc/fstab这个临时swap文件在生产环境不建议长期使用速度不如独立swap分区但作为安装期的应急手段完全够用。5.3 监听服务启动失败监听器是数据库对外连接的第一道关口没它客户端根本连不进来。常见的监听启动失败原因有三个一是listener.ora里的主机名解析不了二是端口被占用三是防火墙拦截。排查思路很简单先看监听状态lsnrctl status如果提示TNS-12545: Connect failed because target host or object does not exist基本就是/etc/hosts的问题。确认主机名和IP对应关系hostname grep 主机名 /etc/hosts/etc/hosts里必须有本机IP和主机名的映射否则监听器和数据库实例之间通信会异常。这个坑在DNS配置不当的内网环境中尤其常见。先把它抓好再重启监听lsnrctl stop lsnrctl start防火墙方面如果是CentOS 7默认使用firewalld需要放行1521端口firewall-cmd --permanent --add-port1521/tcp firewall-cmd --reload5.4 数据库实例启动报ORA-27102或ORA-00064启动数据库的时候偶尔会碰到这类报错ORA-27102: out of memory Linux-x86_64 Error: 28: No space left on device如果你确定磁盘没有满那多半是/dev/shm共享内存太小。Oracle 11g默认使用共享内存来管理SGA如果/dev/shm的大小小于SGA的分配值实例就无法启动。查看当前共享内存大小df -h /dev/shm默认情况下/dev/shm是物理内存的一半。解决办法要么调整SGA大小让数据库在共享内存限制内运行要么把共享内存挂载扩大。临时扩大mount -o remount,size8G /dev/shm如果是虚拟机内存本来就小更合理的方案是在初始化参数中把memory_target或sga_target调小。5.5 远程客户端连不上数据库如果监听和实例都正常但远程客户端就是用SQL Developer或pl/sql连接不上重点检查这几项lsnrctl services看是否有对应服务数据库是否处于OPEN状态防火墙是否放行1821端口刚才提过sqlnet.ora里是否设置了TCP.INVITED_NODES之类的限制有一种情况很隐蔽数据库装好后listener.ora里的HOST写成127.0.0.1而不是实际内网IP导致远程客户端能到服务器但监听只监听回环地址连不上。遇到这种情况直接修改listener.ora把HOST改成服务器实际IP或主机名重启监听即可。5.6 oracle用户环境下sqlplus中文乱码对于需要UTF-8中文支持的环境在/home/oracle/.bash_profile里加一行export NLS_LANGAMERICAN_AMERICA.AL32UTF8这个设置和数据库字符集要一致否则从客户端查询中文字段会出现乱码。大部分公司项目建库时用的都是AL32UTF8这一行建议从一开始就配好免得后面被业务半路问起来。6. 安装完成后的必要固化和后续扩展建议6.1 把系统参数和配置固化到开机自启Oracle数据库装好之后服务器一旦重启数据库实例和监听器不会自动起来需要手工操作。生产环境不可能每次重启都人工去启库所以这一步一定要做。用root用户的systemctl创建一个服务或者传统的方式在/etc/rc.local里加上su - oracle -c /u01/app/oracle/product/11.2.0/dbhome_1/bin/lsnrctl start su - oracle -c /u01/app/oracle/product/11.2.0/dbhome_1/bin/dbstart $ORACLE_HOME注意dbstart启动数据库依赖/etc/oratab文件。Oracle在安装的时候会生成这个文件里面记录了orcl:/u01/app/oracle/product/11.2.0/dbhome_1:N其中最后的标志符如果是Ndbstart就不会管这个实例。把它改成Y才能实现开机自动启库sed -i s/dbhome_1:N/dbhome_1:Y/ /etc/oratab另外别忘了一提交修改/etc/rc.local后要给执行权限chmod x /etc/rc.local6.2 补丁升级与后续运维的离线准备Oracle 11.2.0.4之后有大量的PSU补丁集更新如果你在客户内网环境绝对不能指望在线补丁。这类补丁也是通过OPatch工具离线打的核心是提前准备好p6880880这是OPatch工具本身和其他补丁包上传到服务器后按以下流程操作# 替换OPatch版本 unzip p6880880_112000_Linux-x86-64.zip -d $ORACLE_HOME # 检查补丁冲突 $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /home/oracle/patch/ # 打补丁 $ORACLE_HOME/OPatch/opatch apply /home/oracle/patch/实测下来11g打补丁比19c要麻烦一点主要在于需要重启数据库到migrate模式执行SQL脚本。这部分如果客户没强制要求很少会有团队去主动打补丁。但如果在金融或者医疗行业合规审计会查补丁情况这个流程建议在部署文档里留一份备用。6.3 备份策略的快速落地离线环境同样要解决备份问题。最小可行方案是开启归档模式配合每天的rman增量备份。作为刚装完库的初级固化至少要把归档模式打开sqlplus / as sysdba shutdown immediate startup mount alter database archivelog; alter database open;然后写个简单的rman备份脚本全库加归档日志备份到另一块磁盘或NFS挂载目录。这一步不一定在当天完成但至少在交付给客户前要把备份通道验证跑通别等数据丢了才想起这茬。6.4 从11g升级到19c时的注意差异如果你是为了新项目直接装19c静默安装的思路完全一样但有几处细节不同。第一19c的runInstaller对glibc版本要求更高建议CentOS 7.9以上或者直接用Rocky Linux 8第二19c安装包建议用LINUX.X64_193000_db_home.zip解压后可以直接通过./runInstaller -silent安装不再需要分成database目录第三19c的响应文件参数命名略有调整但总体结构还是oracle.install.xx.xx的形式。内核参数里vm.max_map_count必须放大到262144以上这一点和11g不同很容易被忽略。另外19c默认使用CDB/PDB架构如果还是习惯于11g的非容器数据库可以在建库时指定-createAsContainerDatabase false或者建好CDB后再创建独立的PDB。多租户架构对运维习惯的冲击不小建议初次接触19c的朋友先建一个PDB练手再上生产。7. 我的经验总结离线安装Oracle这件事说难也难说简单也简单。难在环境差异大每台服务器的操作系统纯净度不一样依赖缺失情况也不同简单在于流程高度标准化只要介质和依赖准备好了静默安装基本一次过。我个人做了这么多套之后最大的体会是——前期准备工作占整个安装过程70%的精力真正执行安装的时间其实很短。再分享一个小技巧每做完一套环境把rpm -qa的完整包列表和/etc/sysctl.conf、/etc/security/limits.conf这两个配置文件备份到一个文档里。下次做第二套时直接对照这个清单缺失一目了然。这套基线模板的方法我在批量交付项目时大大降低了翻车概率。还有第一次做的时候建议全程开着script命令记录终端日志一旦安装失败可以从日志里快速定位到底卡在哪一步不用凭记忆排查。离线环境不像在线环境一样有个搜索引擎随时查答案自己留下的记录就是最可靠的排查依据。