
先说一个现实Oracle 11g 已经 EOL 很久了但在不少企业的核心环境里它还在顽强地跑着。尤其是 Linux Oracle 11g 这套组合接手的运维和开发根本绕不开。这篇文章基于我在 CentOS 6 和 CentOS 7 上多次安装 Oracle 11gR2 的真实记录写成内容包括安装包怎么获取、静默安装的全流程、监听和实例的创建以及我在实际安装中踩过、后来整理成笔记的一批典型问题。想直接照着做的人从第一节环境准备开始跟着走就行只想看排错的同学可以直接跳到常见问题那节。1. 为什么还在折腾 Oracle 11g存量环境下的现实选型1.1 不是我们想用老古董是业务系统不答应很多人不理解为什么现在还有人在装 Oracle 11g。答案很简单存量业务系统。不少企业的 ERP、MES、OA 系统从十多年前就跑在 Oracle 11g 上数据库升级意味着应用要重新做兼容性测试有些核心系统的存储过程写得比较原始升级到 12c、19c 后很可能出现性能回退甚至直接跑不起来。业务部门不会同意为了“技术先进性”承担宕机风险。所以这类环境通常只有两条路要么继续在老硬件上维护要么在全新的 Linux 服务器上重新安装一套 11g然后做数据迁移。后者其实很常见尤其是虚拟化往信创环境迁移的项目经常要求在新机器上重新搭一套一模一样的 Oracle 11g 环境。1.2 选 CentOS 6 还是 CentOS 7先想清楚Oracle 11gR2 官方认证的操作系统是 RHEL 4、RHEL 5、RHEL 6 这一代。如果项目允许自由选择我强烈建议优先用 CentOS 6.x比如 6.10整个安装过程几乎不会碰到兼容性问题。CentOS 6 虽然也 EOL但在离线环境里跑 Oracle 11g 反而最省心。但现实是现在很多新采购的服务器预装的就是 CentOS 7甚至 8、9。CentOS 7 上装 Oracle 11g 不是不行我实测过很多次完全能装起来跑稳定但必须处理两个额外问题一是系统仓库里没有compat-libstdc-33这个兼容包需要手动找 RPM 安装二是glibc版本偏高跑 root.sh 时可能遇到一些无关紧要的告警需要加参数跳过。这篇文章的主流程我按 CentOS 6 来讲同时单独列了一节说明 CentOS 7 的差异方便两边都能照做。2. 安装前的系统准备把这些坑提前填掉2.1 依赖包、SELinux 和主机名解析Oracle 11g 在 Linux 上安装时最劝退新手的往往不是 Oracle 本身而是前置环境不干净。以 CentOS 6 为例用 root 登录后先做这几件事。关闭 SELinuxsed -i s/SELINUXenforcing/SELINUXdisabled/ /etc/selinux/config setenforce 0SELinux 不关Oracle 安装完以后经常出现权限类的玄学问题比如监听进程起不来、sqlplus 报权限错误。生产环境我都是直接关掉省得后面查问题查到怀疑人生。然后安装依赖包一条命令搞定yum -y install binutils compat-libstdc-33 compat-libstdc33 \ elfutils-libelf elfutils-libelf-devel gcc gcc-c glibc glibc-common \ glibc-devel glibc-headers ksh libaio libaio-devel libgcc libstdc \ libstdc-devel make sysstat unixODBC unixODBC-devel有同学会问为什么要装这么多包因为 Oracle 的安装程序会对系统做预检prereq缺一个都会直接不让你往下走。这里比较关键的是compat-libstdc-33它提供libstdc.so.5Oracle 11g 的二进制文件依赖这个老版本运行库。CentOS 6 的默认源里带这个包CentOS 7 的默认源里已经没了需要单独找。最后确认主机名解析。Oracle 在安装过程中会反复解析本机主机名如果/etc/hosts里没有对应记录安装程序会报PRVF-0002之类的错误。检查方法hostname cat /etc/hosts确保 hosts 文件里有这样一行192.168.1.10 oradb而不是只写成192.168.1.10 localhost我把这个坑单独拎出来说是因为十个安装报错里至少有三个和主机名解析有关。2.2 内核参数和用户限制每项参数背后是在做什么接下来调内核参数。编辑/etc/sysctl.conf追加或修改以下内容fs.aio-max-nr 1048576 fs.file-max 6815744 kernel.shmall 1073741824 kernel.shmmax 4294967295 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让配置立即生效。这里我重点解释两个总有人问的参数。kernel.shmmax是单个共享内存段允许的最大字节数Oracle 的 SGA 就放在共享内存里这个值如果小于你给 SGA 分配的大小数据库启动会直接报ORA-27102: out of memory。我常设的 4GB 只是起点具体应该设置为物理内存的一半左右比如物理内存 32GB 就设 17179869184。kernel.sem第四个数SEMMNI是系统允许的最大信号量组数Oracle 对它有硬性要求不能低于 128不然数据库内部的进程通信会出问题。然后是用户资源限制。编辑/etc/security/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.sonproc限制进程数nofile限制打开文件数。Oracle 在跑并发连接时文件描述符用得很凶默认 1024 肯定不够。当年我遇到过一个诡异问题数据库跑一段时间后新连接全部超时查半天发现是 nofile 太小连接进程的文件句柄耗尽。这类问题不提前配好上线后很难排查。2.3 创建 oracle 用户和目录Swap 与 /dev/shm 的处理官方推荐的安装用户是独立的 oracle 用户不要用 root 装虽然能装但后患无穷。创建用户和组groupadd oinstall groupadd dba useradd -g oinstall -G dba oracle passwd oracle然后规划安装目录。我习惯把数据库软件和数据文件都放在/u01下mkdir -p /u01/app/oracle/product/11.2.0/dbhome_1 mkdir -p /u01/app/oracle/oradata mkdir -p /u01/app/oracle/flash_recovery_area chown -R oracle:oinstall /u01 chmod -R 775 /u01这里顺便说下 swap 和 /dev/shm。Oracle 官方要求 swap 大小至少等于物理内存物理内存在 2GB 以上时 swap 至少为 1.5 倍。实际项目中我遇到过内存 64GB 的机器只给了 8GB swap安装时预检虽然过了跑大数据量排序时 P60 就明显变慢。swap 不够就动态加一个dd if/dev/zero of/swapfile bs1M count16384 mkswap /swapfile swapon /swapfile echo /swapfile swap swap defaults 0 0 /etc/fstab再检查/dev/shm。Oracle 11g 默认启用 Memory Target需要在共享内存/dev/shm里分配 SGA如果/dev/shm太小数据库启动会报ORA-00845: MEMORY_TARGET not supported on this system。虚拟机里特别容易遇到这个问题因为默认 /dev/shm 可能只有几百 MB。解决办法mount -o remount,size8G /dev/shm并写入/etc/fstab确保重启后依然生效tmpfs /dev/shm tmpfs defaults,size8G 0 03. 安装包获取与解压别在第一步就翻车3.1 官方下载渠道和文件校验标题里说了提供安装包链接这里我必须先说明一下Oracle 11g 已经从官方免费下载页上挪到了历史版本归档区。访问 Oracle 官网下载页登录 Oracle 账号并接受协议后才能找到 Oracle Database 11g Release 2 的下载入口。64 位 Linux 环境下需要下载两个 zip 文件linux.x64_11gR2_database_1of2.zip约 1.2GBlinux.x64_11gR2_database_2of2.zip约 1.1GB两个文件都必须下载缺一个解压会报错。下载完成后强烈建议做一次 md5 校验把文件完整性和官网公布的校验值比对一下别嫌麻烦。文件在传输过程中损坏比缺文件更难排查解压时不报错跑到安装到一半突然说某个包校验失败那才叫难受。校验命令md5sum linux.x64_11gR2_database_1of2.zip linux.x64_11gR2_database_2of2.zip顺便说一句如果你的环境是 32 位系统对应文件名是linux_11gR2_database_1of2.zip和linux_11gR2_database_2of2.zip不过现在 64 位已经是绝对主流除非你的机器实在太老否则不用考虑 32 位。3.2 zip 解压与常见乱码问题把两个 zip 放在同一个目录下解压它们会自动合并到同一个database目录中unzip linux.x64_11gR2_database_1of2.zip unzip linux.x64_11gR2_database_2of2.zip解压完成后确认目录结构cd database ./runInstallerOracle 的 zip 包里文件名基本都是英文一般不会遇到乱码。但如果你在 Linux 上解压其他来源的 zip 包时遇到中文文件名乱码通常是编码不一致导致的——Windows 下压缩时用的是 GBK/GB18030Linux 默认按 UTF-8 解压。解决办法是用unzip -O CP936指定编码比如unzip -O CP936 某个windows打包的zip文件.zip或者干脆用 7z7z x 某个windows打包的zip文件.zip这个知识点虽然和 Oracle 没直接关系但我在网上看到太多人在问“linux 解压文件乱码”顺手放在这里作为一个通用处理方案。4. 静默安装 Oracle 数据库软件一条命令跑完4.1 修改 db_install.rsp 响应文件安装包解压后database/response/目录下有一个db_install.rsp模板文件。生产环境没有图形界面我建议直接走静默安装修改这个响应文件就可以。把模板复制到 oracle 用户目录下再改cp database/response/db_install.rsp /home/oracle/ chown oracle:oinstall /home/oracle/db_install.rsp su - oracle vi /home/oracle/db_install.rsp关键参数按下面这些改。注意模板里每一行默认都是带值的需要逐项改成适合自己的oracle.install.optionINSTALL_DB_SWONLY ORACLE_BASE/u01/app/oracle ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 oracle.install.db.InstallEditionEE oracle.install.db.DBA_GROUPdba oracle.install.db.OPER_GROUPdba DECLINE_SECURITY_UPDATEStrue解释一下几个容易改错的点。oracle.install.option有三个可选值分别是INSTALL_DB_SWONLY只装数据库软件、INSTALL_DB_AND_CONFIG装软件并直接创建一个数据库、UPGRADE_DB升级。第一次装我建议选INSTALL_DB_SWONLY先只装软件成功后再用 dbca 单独创建实例。这样安装过程和建库过程分开排错哪一步出问题一眼就能定位。InstallEdition可以选EE企业版或SE标准版前提是你下载的安装包支持对应的版本授权。没有特殊需求就EE。DECLINE_SECURITY_UPDATEStrue表示不接受安全更新配置。这个必须设为 true否则安装程序会死等一个邮箱地址而且邮箱不填就直接报错退出。第一次静默安装的人经常挂在这一步。如果你在这个响应文件里配置了数据库相关参数比如oracle.install.db.config.starterdb.*但安装选项是INSTALL_DB_SWONLY这些参数会被全部忽略。也就是说响应文件里的很多段是可以共存的怎么生效取决于最上面的oracle.install.option。4.2 执行安装与 root 脚本用 oracle 用户执行安装命令cd /home/oracle/database ./runInstaller -silent -responseFile /home/oracle/db_install.rsp -ignorePrereq-silent是静默模式-responseFile指定响应文件路径-ignorePrereq跳过系统预检。CentOS 7 上这个参数必须加因为在系统版本检测那一关过不去CentOS 6 上理论可以不加但为了省事我一般也加上。安装过程持续五到十分钟不等取决于服务器磁盘性能。安装结束后终端会输出两行关键信息提示你用 root 身份执行两个脚本/u01/app/oracle/product/11.2.0/dbhome_1/root.sh一定要切回 root 去执行cd /u01/app/oracle/product/11.2.0/dbhome_1 ./root.sh这个脚本主要做三件事更新/etc/oratab、设置一些二进制文件的属主权限、创建 Oracle Inventory 目录。很多新手装完以后直接就建库跳过 root.sh结果后面起监听、起库全都没权限报错。这个步骤没有回退必须做。4.3 验证安装是否完整软件装完以后先别急着建库花两分钟验证一下环境。用 oracle 用户执行ls -l $ORACLE_HOME/bin/sqlplus $ORACLE_HOME/bin/sqlplus -v能正常输出版本号就说明软件本体已经安装完整SQL*Plus: Release 11.2.0.1.0 Production再检查一下环境变量因为root.sh执行以后会修改一些配置可能导致之前的 shell 环境变量失效。确认当前 oracle 用户的变量echo $ORACLE_BASE echo $ORACLE_HOME echo $ORACLE_SID如果没有输出编辑/home/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然后重新加载source /home/oracle/.bash_profile5. 监听配置与实例创建等数据库能报上名才算完成5.1 netca 静默配置监听软件装完只是万里长征走了一半Oracle 不像 MySQL装完就能直接用。你必须先配置监听器Listener再创建数据库实例。用 netca 静默配置监听$ORACLE_HOME/bin/netca -silent -responsefile $ORACLE_HOME/network/response/netca.rsp执行成功后$ORACLE_HOME/network/admin/下会生成listener.ora、sqlnet.ora两个文件。看到Oracle Net Services 配置成功的字样就说明监听配置好了。验证监听状态lsnrctl status如果输出中包含Service orcl has 1 instance(s)之类的内容说明监听已经起来了。这里要注意执行lsnrctl时 shell 工作目录必须是$ORACLE_HOME/network/admin可读的位置否则可能报找不到 listener.ora。5.2 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/flash_recovery_area \ -characterSet AL32UTF8 \ -memoryPercentage 40 \ -emConfiguration NONE解释几个参数。-templateName General_Purpose.dbc是通用业务模板适合绝大多数 OLTP 场景。-gdbname是全局数据库名-sid是实例名一般保持一致即可。-sysPassword和-systemPassword是内置管理员密码建议包含字母和数字长度不少于 8 位太简单 Oracle 会拒绝执行。-characterSet指定字符集这一项特别重要后面单独说。-emConfiguration NONE表示不配置 Enterprise Manager因为 11g 的 EM 组件在生产环境用处不大还能省掉一个端口和一组进程资源。创建过程大约十到二十分钟主要耗时在数据字典和 PL/SQL 包的编译上。中间如果报错日志文件位置通常会在终端输出的最后几行里默认在$ORACLE_BASE/cfgtoollogs/dbca/下按时间戳命名的日志文件里记录了具体错误。创建完成后测试能否登录sqlplus / as sysdba SQL select status from v$instance;返回OPEN就说明数据库已经正常打开。5.3 本地临时表和字符集的抉择字符集是建库时最影响后续使用的决定。-characterSet选AL32UTF8还是ZHS16GBK不同场景有不同选法。我以前在老项目里习惯选ZHS16GBK因为 GBK 编码对中文兼容好单字节能覆盖 ASCII 和中文存储占用比 UTF8 小而且很多老应用的 JDBC 连接串在 GBK 库上跑得很顺。但问题是 GBK 不是 Unicode 全集如果将来要接入外部系统处理扩展字符、emoji 或多语言数据会非常痛苦而且数据库字符集一旦建成再改就是一次大动干戈的迁移。所以现在的项目只要不是必须兼容十年前的旧库我都建议无脑选AL32UTF8。虽然中文字符在 UTF8 编码下占用的存储空间比 GBK 略大但现代磁盘不差这点空间。更关键的是Oracle 在 12c 之后已经强烈推荐并且默认使用AL32UTF8早点切过去后续迁移升级都省事。create完成后用下面这条 SQL 确认字符集是否符合预期SELECT name, value$ FROM props$ WHERE name NLS_CHARACTERSET;如果已经是目标字符集就不用再折腾了。6. 常见问题注解安装文档不会告诉你的那些坑6.1 ORA-27125、ORA-00845 等内存相关错误内存类错误在 Oracle 11g 安装和启动阶段遇到频率最高。ORA-00845: MEMORY_TARGET not supported on this system这个错前面提到过本质是/dev/shm太小而 Oracle 11g 用的是 AMMAutomatic Memory ManagementSGA 和 PGA 都会在共享内存里分配。解决方式有两个一是把/dev/shm调大二是改掉 AMM在参数文件里手动设置固定的 SGA_TARGET 和 PGA_AGGREGATE_TARGET。生产环境我反而推荐后者因为 AMM 在负载波动较大的系统上会导致频繁的共享内存扩缩容对稳定性和性能都不友好。ORA-27125: unable to create shared memory segment则是/dev/shm存在但权限或大小限制不对。检查一下挂载情况df -h /dev/shm如果显示容量只有几百 MB按照本文前面写的方法重新挂载。如果显示tmpfs挂载了但容量正常那就是内核参数kernel.shmmax或kernel.shmall设置偏小回头检查 sysctl.conf。还有一个常见场景服务器物理内存不大比如 4GB但你给 SGA 分配了 3GB启动时系统内存被其他进程占满就会报ORA-27102: out of memory。解决思路是压低 SGA或者调大 swap。我的经验是在 4GB 内存的测试机上跑 11gSGA 控制在 1.5GB 以内最稳。6.2 ORA-12547 TNS lost contact 的权限陷阱ORA-12547: TNS:lost contact是我遇到过的比较隐蔽的问题。表面上看是网络断开实际上大概率是 oracle 用户的umask配置不对导致二进制文件在安装或后续操作时生成了错误的权限位。Oracle 官方要求 oracle 用户的umask为022这样创建出来的文件权限是 755 或 644如果 umask 是002文件权限变成 775/664Oracle 的某些可执行文件在运行时因为权限问题直接被杀掉客户端表现就是连接中断。检查当前用户的 umaskumask如果不是022编辑 oracle 用户的.bash_profile在开头加上umask 022然后重新登录。还有个隐藏问题证书或 wallet 文件权限不对也会报这个错检查$ORACLE_HOME/network/admin及其下所有文件的属主是否为oracle:oinstall。6.3 监听起不来和客户端连不上的排查链路监听器报TNS-12541、TNS-01189这类错误别急着删掉重配按下面这个链路排查。第一步看监听进程在不在ps -ef | grep tnslsnr第二步看监听日志默认在$ORACLE_HOME/network/log/listener.log里面会有具体报错。如果是TNS-12545: Connect failed because target host or object does not exist九成是主机名解析问题。检查/etc/hosts确保本机 hostname 能解析到本机 IP。第三步防火墙。很多人装完 Oracle本机能连、其他机器连不上基本都是防火墙拦截了 1521 端口。CentOS 6 上执行iptables -I INPUT -p tcp --dport 1521 -j ACCEPT service iptables saveCentOS 7 上使用 firewalldfirewall-cmd --permanent --add-port1521/tcp firewall-cmd --reload最后一步如果客户端还是报ORA-12514: TNS:listener does not currently know of service requested说明监听已经起来了但数据库实例的动态注册没有完成。执行alter system register;手动触发注册再查lsnrctl status看服务名是否出现。6.4 CentOS 7 缺少 compat-libstdc-33 的处理CentOS 7 装 11g 时预检会卡在缺少compat-libstdc-33。这个包在 CentOS 7 的默认源里已经移除必须手动找 RPM 装上。我常用的办法是去 CentOS 6 的仓库包里头找这个 RPM比如compat-libstdc-33-3.2.3-69.el6.x86_64.rpm。下载后用 rpm 直接装rpm -ivh compat-libstdc-33-3.2.3-69.el6.x86_64.rpm装完以后验证一下ls -l /usr/lib64/libstdc.so.5确认文件存在即可。如果不方便去网上下载也可以找一台已经装好 Oracle 的旧机器把这个 RPM 从缓存目录里拷出来。安装时如果提示依赖缺失一般加--nodeps也能装因为说白了它只是一个运行库没有复杂的依赖关系。装完这个包CentOS 7 上的预检应该就能过了。其他预检告警比如物理内存、可用内存之类根据实际情况调整一下就行。7. 安装后的基础运维让数据库关机后也能自己起来7.1 oratab 和环境变量数据库创建完成后还需要做一件容易被忽略的事配置/etc/oratab。这个文件是 Oracle 在安装时自动生成的格式是orcl:/u01/app/oracle/product/11.2.0/dbhome_1:N每行代表一个实例字段依次是 SID、ORACLE_HOME、是否允许关机时自动启停。想把数据库加入开机自启就把最后一列的N改成Yorcl:/u01/app/oracle/product/11.2.0/dbhome_1:Y这里要提个醒修改 oratab 时建议用 root 权限编辑如果你以 oracle 用户创建修改权限可能引起 dbstart 读取失败。另外有些发行版的 Oracle 安装完成后oratab 文件里默认只有一行注释必须手动追加实例配置。环境变量方面除了前面写的.bash_profile最好再检查一下 oracle 用户的.bashrc是否干净避免系统级 profile 覆盖了ORACLE_HOME。我有一个习惯在.bash_profile末尾加一行export NLS_LANGAMERICAN_AMERICA.AL32UTF8NLS_LANG是客户端连接时用的字符集配置不配的话SQL 工具显示中文可能出现乱码。7.2 SysV 和 systemd 两种自启方案CentOS 6 使用 SysV 方式创建一个/etc/init.d/dbora脚本#!/bin/sh # chkconfig: 345 99 10 # description: Oracle Database auto start-stop ORA_HOME/u01/app/oracle/product/11.2.0/dbhome_1 ORA_OWNERoracle case $1 in start) su - $ORA_OWNER -c $ORA_HOME/bin/dbstart $ORA_HOME ;; stop) su - $ORA_OWNER -c $ORA_HOME/bin/dbshut $ORA_HOME ;; *) echo Usage: $0 {start|stop} exit 1 esac赋权并加入开机启动chmod 750 /etc/init.d/dbora chkconfig --add dbora chkconfig dbora onCentOS 7 用 systemd创建一个/etc/systemd/system/oracle.service文件[Unit] DescriptionOracle Database 11g Afternetwork.target [Service] Typeforking Useroracle Groupoinstall EnvORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 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 [Install] WantedBymulti-user.target启用服务systemctl daemon-reload systemctl enable oracle第一次配置完最好用reboot重启验证一次确认数据库和监听都能自动起来。这一步我每次装机都不会跳过因为测试环境看不出问题生产环境如果重启后起不来影响面就大了。7.3 日常启停的推荐姿势日常维护中我不建议直接用kill杀数据库进程而是用官方脚本lsnrctl stop sqlplus / as sysdba SQL shutdown immediate; SQL exit;启动顺序正好反过来sqlplus / as sysdba SQL startup这里说一下shutdown immediate和shutdown abort的区别。日常维护一律用immediate它会回滚未提交事务并释放资源。如果数据库卡死、回滚可能耗很久才考虑abort强制终止但这种操作有概率导致实例恢复时花费更长时间还会让控制文件和数据文件产生不一致风险。另外生产环境上我强烈建议开启归档模式SQL shutdown immediate; SQL startup mount; SQL alter database archivelog; SQL alter database open;然后在$ORACLE_HOME/dbs/init.ora或者对应的文本参数文件里确认db_recovery_file_dest设置正确。归档模式可以保证你误删数据、误执行 UPDATE 时还有最后一根救命稻草。既然数据库都装好了这一步顺手做了别等到出事故再补。装多了之后我发现真正决定这套系统后续好不好用的往往不是安装那一下而是安装前系统预检是否细致。我个人在批量部署前会先写好一份预检脚本把内存、swap、依赖包、内核参数、/dev/shm、防火墙、主机名解析全部查一遍再开始跑安装。这个习惯帮我省掉了绝大多数返工。如果你是按着这篇文章装第一套库建议也在动手之前把这些检查项过一遍后面会省心很多。