ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Oracle 11gR2 Linux部署全链路避坑指南:内核参数、RPM依赖与权限配置

Oracle 11gR2 Linux部署全链路避坑指南:内核参数、RPM依赖与权限配置

简介:本资源是一份面向Linux系统管理员与Oracle数据库初学者的实战安装指南,聚焦在CentOS/Red Hat等主流Linux发行版上部署Oracle 11g Release 2单机数据库的全流程图解。内容覆盖从系统环境准备(如gcc、glibc-devel等依赖包安装)、Oracle用户与环境变量配置,到runInstaller启动、Inventory目录设置、监听器netca与数据库dbca创建等关键环节,并特别说明虚拟机分辨率调整、错误日志解读及常见忽略项(如内存/空间不足提示)等实操细节。资源为1个1.73MB的Word文档(.doc),图文并茂,步骤编号清晰,含20个以上带注释的操作截图与配置要点提示,便于边学边练、快速复现。目前已有133人学习下载,适合需在测试或开发环境中快速落地Oracle 11gR2、同时夯实Linux+数据库交叉技能的中级运维与DBA入门者。

1. Linux下Oracle 11gR2单机部署:不是点下一步就完事,而是37个系统级参数、12个rpm包、4类内核限制的协同落地

你手头有一台刚装好的CentOS 6.5(或RHEL 6.x),想跑个Oracle 11gR2做开发测试——别急着双击runInstaller。这不是Windows上点“下一步→我接受→完成”的图形化安装,而是一场对Linux底层能力的全面压力测试:内存锁页(memlock)没调够?安装中途静默失败;/tmp空间不足2G?解压阶段直接卡死在unzip;semmsl设成250而Oracle要求256?DBCA建库时连监听都起不来。我见过太多人卡在第15步“系统检查失败”后反复重装系统,其实问题就藏在/etc/sysctl.conf里一行被注释掉的kernel.shmall配置。这份资源不是教你怎么点鼠标,而是把Oracle官方Installation Guide里分散在5个章节、3份附录里的硬性约束,全拧进一个可验证、可回滚、可批量复现的Shell脚本流程里。适合两类人:一是正被生产环境迁移任务压着、需要当天交付可用实例的DBA;二是刚学完《Linux系统管理》想动手搭真实数据库的新手——但请先扔掉“图形界面很友好”的错觉,这里每一处“Next”背后,都是ulimit -s和/proc/sys/kernel/sem的无声博弈。


2. 系统级预检:从uname -r到getconf PAGE_SIZE,为什么必须手动验这11项

Oracle 11gR2对Linux内核版本、内存模型、IPC机制有硬性依赖。官方文档写“RHEL 6.1+ supported”,但实际部署中,RHEL 6.9和6.10的glibc补丁差异会导致libaio.so.1加载失败。不能只信cat /etc/redhat-release,得用组合命令交叉验证。

2.1 内核与硬件兼容性:三道关卡缺一不可

先确认内核主版本是否在支持列表内:

# 必须输出 2.6.32-x.el6 或 2.6.39-x(仅限特定补丁集) uname -r # 输出示例:2.6.32-754.35.1.el6.x86_64 → ✅ 合规 # 若输出 2.6.32-220.el6.x86_64 → ❌ 太旧,需升级内核

再查CPU是否支持PAE(物理地址扩展),这是Oracle共享内存段的基础:

# 必须返回 'pae' 字样,否则无法分配>4GB SGA grep -i pae /proc/cpuinfo | head -1 # 无输出?说明是纯32位CPU或VM未开启PAE支持

最后验证页面大小(Page Size),Oracle 11gR2要求getconf PAGE_SIZE必须为4096:

# 必须严格等于4096,某些定制内核会设为65536导致ORA-27123 getconf PAGE_SIZE # 若返回65536 → 需重编译内核或换发行版

提示:虚拟机用户务必在VMware Workstation/ESXi中启用“Enable PAE/NX”选项,且关闭“Memory Hot Plug”——后者会干扰Oracle内存锁定机制。

2.2 RPM包依赖:12个包一个都不能少,yum install oracle-rdbms-server-11gR2-preinstall只是障眼法

Oracle官方预装包(oracle-rdbms-server-11gR2-preinstall)看似一键解决依赖,但它在RHEL 6.5+上会强制降级glibc,引发后续sqlplus段错误。必须手动逐个安装并验证版本:

包名最低版本验证命令关键作用
binutils2.20.51.0.2-5.36.el6rpm -q binutils符号解析与链接器
gcc4.4.4-13.el6rpm -q gcc安装时编译临时组件
glibc2.12-1.7.el6rpm -q glibc严禁用preinstall降级!
libaio0.3.107-10.el6rpm -q libaio异步I/O核心库
sysstat9.0.4-11.el6rpm -q sysstatiostat用于性能监控

执行安装(注意顺序,glibc必须保持原版本):

# 先装基础工具链 sudo yum install -y binutils compat-libcap1 gcc gcc-c++ ksh libgcc libstdc++ make # 单独装libaio(避免preinstall污染glibc) sudo yum install -y libaio-0.3.107-10.el6.x86_64 # 验证所有包已就位 rpm -q binutils gcc gcc-c++ libaio ksh make | grep "not installed" && echo "缺包!" || echo "RPM依赖齐备"

2.3 内存与交换空间:free -g看到的数字,不等于Oracle能用的数字

Oracle要求物理内存≥1GB,但实际部署中,若/proc/meminfo中MemAvailable低于1.5G,runInstaller会因JVM堆内存不足直接退出。更隐蔽的是交换分区(swap)策略:

  • 规则1:swap空间必须≥RAM,且不能是swap文件(/swapfile),必须是独立swap分区(/dev/sda2)。Oracle安装程序会拒绝识别swap文件。
  • 规则2:swappiness必须设为1(非0),否则内核过度回收缓存导致SGA分配失败。

验证与修复:

# 检查swap类型(输出应含/dev/xxx,不含file) swapon --show=NAME,TYPE | grep "partition" # 若为file,立即停用并重建swap分区(此处省略fdisk步骤) sudo swapoff /swapfile # 设置swappiness echo 'vm.swappiness = 1' | sudo tee -a /etc/sysctl.conf sudo sysctl -p # 验证 cat /proc/sys/vm/swappiness # 必须输出1

3. 内核参数调优:/etc/sysctl.conf里8行配置,决定DBCA能否创建第一个表空间

Oracle 11gR2的共享内存(SGA)和信号量(Semaphore)完全依赖Linux内核参数。官方文档写的数值是“最低要求”,但生产环境必须按公式计算:shmmax = max(4GB, 0.5 * 物理内存)。很多人照抄kernel.shmmax = 4294967296,结果在32GB内存机器上SGA只能分到4GB,性能断崖式下跌。

3.1 共享内存参数:shmmax、shmall、shmmni的三角关系

三者必须满足数学约束:

  • shmall ≥ shmmax / PAGE_SIZE
  • shmmni ≥ 4096(Oracle硬性要求)
  • shmmax建议值 =物理内存(GB) × 0.5 × 1024 × 1024 × 1024

以16GB内存为例:

# 计算shmall:16GB × 0.5 = 8GB → 8×1024×1024×1024 / 4096 = 2097152 echo "kernel.shmmax = 8589934592" | sudo tee -a /etc/sysctl.conf echo "kernel.shmall = 2097152" | sudo tee -a /etc/sysctl.conf echo "kernel.shmmni = 4096" | sudo tee -a /etc/sysctl.conf sudo sysctl -p

验证是否生效:

# 必须与sysctl.conf中设置值一致 ipcs -lm | grep "max total shared memory" # 输出示例:max total shared memory (kbytes) = 8388608 → 即8GB ✅

3.2 信号量参数:sem四元组的致命陷阱

Oracle用信号量控制并发连接数,kernel.sem格式为SEMMSL SEMMNS SEMOPM SEMMNI。常见错误是只改SEMMSL(单个信号量集最大信号量数),却忽略SEMMNS(系统总信号量数):

  • SEMMSL≥processes参数(默认150,建库时可调)
  • SEMMNS≥SEMMSL × SEMMNI(必须≥65536)
  • SEMOPM≥ 100(Oracle硬性要求)
  • SEMMNI≥ 4096(同上)

正确配置(适配150进程):

# SEMMSL=256(留余量),SEMMNS=32768,SEMOPM=100,SEMMNI=4096 echo "kernel.sem = 256 32768 100 4096" | sudo tee -a /etc/sysctl.conf sudo sysctl -p

验证:

# 输出必须与设置完全一致 cat /proc/sys/kernel/sem # 示例:256 32768 100 4096 ✅ # 若输出:250 32000 100 4096 → ❌ SEMMSL和SEMMNS不足

3.3 文件句柄与进程限制:ulimit不是脚本里一句ulimit -n 65536就能搞定

Oracle进程(ora_pmon_、ora_d000_等)启动时会继承shell的ulimit,但/etc/security/limits.conf的配置需配合PAM模块才生效。常见翻车点:只改了limits.conf,却忘了/etc/pam.d/login里没有pam_limits.so。

完整配置流程:

# 编辑limits.conf(注意:oracle用户必须存在) echo "oracle soft nofile 65536" | sudo tee -a /etc/security/limits.conf echo "oracle hard nofile 65536" | sudo tee -a /etc/security/limits.conf echo "oracle soft nproc 16384" | sudo tee -a /etc/security/limits.conf echo "oracle hard nproc 16384" | sudo tee -a /etc/security/limits.conf # 确保PAM加载limits模块(检查是否存在该行) if ! grep -q "pam_limits.so" /etc/pam.d/login; then echo "session required pam_limits.so" | sudo tee -a /etc/pam.d/login fi

验证(必须用oracle用户登录新shell):

# 切换到oracle用户并验证 sudo su - oracle -c "ulimit -n; ulimit -u" # 输出应为:65536 和 16384 ✅

4. Oracle用户与环境变量:/home/oracle不是家目录,而是权限控制的雷区

创建oracle用户不是useradd oracle就完事。Oracle安装要求/home/oracle必须由oracle用户完全拥有,且umask必须为022。曾有人因/home/oracle属主是root,导致$ORACLE_HOME/inventory目录权限错误,runInstaller写入失败却报“磁盘空间不足”。

4.1 用户组与UID规划:oinstall和dba组的权限边界

Oracle 11gR2强制要求两个组:

  • oinstall:拥有$ORACLE_HOME目录所有权,负责软件安装
  • dba:拥有数据库实例控制权,可执行sqlplus / as sysdba

关键规则:oinstall组不能包含除oracle外的任何用户,否则runInstaller会拒绝启动(安全策略)。

创建命令(严格按此顺序):

# 创建组(GID固定为501/502,避免冲突) sudo groupadd -g 501 oinstall sudo groupadd -g 502 dba # 创建oracle用户(UID固定为501,主组oinstall,附加组dba) sudo useradd -u 501 -g oinstall -G dba -d /home/oracle -s /bin/bash oracle # 设置密码(生产环境禁用空密码!) echo "oracle:password123" | sudo chpasswd # 创建家目录并赋权 sudo mkdir -p /home/oracle sudo chown -R oracle:oinstall /home/oracle sudo chmod -R 755 /home/oracle

4.2 环境变量配置:ORACLE_SID不是随便起的字符串

ORACLE_SID是数据库实例的唯一标识,它将绑定到$ORACLE_HOME/dbs/init<SID>.ora和监听器配置。错误实践:建库时填orcl,但环境变量设ORACLE_SID=ORCL(大小写不一致),导致lsnrctl start找不到实例。

.bash_profile标准模板(必须用oracle用户执行):

# 切换到oracle用户 sudo su - oracle # 写入环境变量(注意:ORACLE_BASE和ORACLE_HOME路径必须与安装时一致) cat >> ~/.bash_profile << 'EOF' export ORACLE_BASE=/u01/app/oracle export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1 export ORACLE_SID=orcl export PATH=$ORACLE_HOME/bin:$PATH export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib export NLS_LANG=AMERICAN_AMERICA.AL32UTF8 export NLS_DATE_FORMAT='YYYY-MM-DD HH24:MI:SS' EOF # 生效配置 source ~/.bash_profile # 验证(必须全部输出非空) env | grep -E "ORACLE_|NLS_" | sort

注意:NLS_LANG必须设为AL32UTF8,否则建库时选UTF-8字符集会失败。NLS_DATE_FORMAT影响TO_DATE函数行为,开发环境建议统一。

4.3 目录结构初始化:/u01不是挂载点,而是Oracle的“根文件系统”

Oracle强烈建议将$ORACLE_BASE放在独立挂载点(如/u01),而非/home或/opt。原因:/u01/app/oracle下会生成diag(诊断日志)、fast_recovery_area(归档日志)等大容量目录,需单独监控磁盘使用率。

创建与挂载(假设已有/dev/sdb1):

# 格式化并挂载(生产环境用xfs,非ext4) sudo mkfs.xfs -f /dev/sdb1 sudo mkdir -p /u01 echo "/dev/sdb1 /u01 xfs defaults 0 0" | sudo tee -a /etc/fstab sudo mount -a # 设置目录权限(oracle用户必须完全控制) sudo chown -R oracle:oinstall /u01 sudo chmod -R 755 /u01

验证磁盘空间(df -h /u01必须≥10GB):

# Oracle安装介质解压后需8GB,建库至少需2GB空闲 df -h /u01 | awk 'NR==2 {print $4}' | sed 's/G//' # 输出数字必须 > 12 ✅

5. 安装过程避坑:从./runInstaller到root.sh,19个必踩雷区与绕过方案

安装界面看似简单,但每一步背后都有内核级校验。以下是最常触发、最易被忽略的19个问题,按出现顺序排列,每条给出现象→原因→解决闭环方案。

5.1 分辨率与字体渲染:runInstaller显示不全的真正元凶

  • 现象:安装界面按钮被截断,“Next”按钮看不见,或中文显示为方块
  • 原因:Java Swing界面依赖X11字体缓存,/usr/share/fonts下缺少ttf-dejavu,且LANG未设为en_US.UTF-8
  • 解决:
    # 安装字体并刷新缓存 sudo yum install -y dejavu-sans-fonts sudo fc-cache -fv # 临时切换LANG(必须在启动runInstaller前) export LANG=en_US.UTF-8 ./runInstaller

5.2 安装介质解压路径:两个ISO必须解压到同一父目录

  • 现象:点击“Next”后报错File not found: /stage/Components/oracle.rdbms.util/11.2.0.1.0/1/DataFiles/filegroup1.jar
  • 原因:linux.x64_11gR2_database_1of2.zip和2of2.zip解压后,database/stage目录结构必须完整,若分别解压到不同目录,runInstaller找不到交叉引用文件
  • 解决:
    # 统一解压到/database(注意:database是目录名,非路径) unzip linux.x64_11gR2_database_1of2.zip -d /tmp/database unzip linux.x64_11gR2_database_2of2.zip -d /tmp/database cd /tmp/database ./runInstaller

5.3 系统检查失败:Check complete. Some requirement have not been met的隐藏真相

  • 现象:第15步检查失败,日志显示Package: pdksh-5.2.14-37.el5missing,但系统已装ksh
  • 原因:Oracle检查脚本硬编码检测pdksh包名,而RHEL 6+已用ksh替代,需手动创建软链接欺骗检查器
  • 解决:
    # 创建兼容性链接 sudo ln -s /bin/ksh /bin/pdksh # 重新运行检查(无需重启runInstaller) /tmp/database/install/.oui -ignoreSysPrereqs -noconfig

5.4root.sh执行失败:Error in invoking target 'agent nmhs' of makefile

  • 现象:安装结束提示执行/u01/app/oraInventory/orainstRoot.sh和$ORACLE_HOME/root.sh,后者报错退出
  • 原因:root.sh依赖/etc/oraInst.loc中inventory_loc路径存在且可写,但该文件可能被其他Oracle安装残留污染
  • 解决:
    # 彻底清理旧inventory sudo rm -rf /u01/app/oraInventory sudo rm -f /etc/oraInst.loc # 重新运行root.sh(确保oracle用户已创建) sudo $ORACLE_HOME/root.sh

5.5 DBCA建库卡在“Creating and starting Oracle instance”

  • 现象:dbca图形界面进度条停在90%,ps -ef | grep pmon无进程,alert_orcl.log无新日志
  • 原因:/dev/shm大小不足(Oracle 11gR2要求≥2GB),而默认/dev/shm为内存的50%(16GB内存机器只有8GB,但shmmax设太小导致分配失败)
  • 解决:
    # 临时增大/dev/shm(重启失效,需写入fstab) sudo umount /dev/shm sudo mount -t tmpfs shmfs -o size=2g /dev/shm # 永久生效 echo "shmfs /dev/shm tmpfs size=2g 0 0" | sudo tee -a /etc/fstab

其他14个雷区(如netca监听配置失败因/etc/hosts未配localhost、sqlplus / as sysdba报ORA-01031因/u01/app/oracle/product/11.2.0/db_1/rdbms/lib/config.c未编译等)均已在配套脚本中固化规避逻辑,此处不赘述。


6. 建库后验证与故障自愈:用3个SQL+2个Shell命令,5分钟定位90%的启动失败

安装完成不等于数据库可用。我见过太多人dbca点完“Finish”就以为大功告成,结果sqlplus / as sysdba连不上,lsnrctl status显示“TNS-12541: No listener”。真正的验收,是让数据库自己证明它活得好好的。

6.1 监听器状态验证:lsnrctl status背后的3层检查

执行lsnrctl status前,先确认监听器进程和端口:

# 1. 检查监听进程是否存在 ps -ef | grep tnslsnr | grep -v grep # 2. 检查1521端口是否监听(必须是LISTENER进程,非其他服务) sudo netstat -tlnp | grep :1521 # 3. 检查监听配置文件语法 $ORACLE_HOME/bin/tnsping orcl # 应返回OK

若lsnrctl status报“TNS-01101: Could not find service name”,说明$ORACLE_HOME/network/admin/listener.ora中SID_LIST_LISTENER未注册实例:

# 手动添加(替换orcl为你的ORACLE_SID) cat >> $ORACLE_HOME/network/admin/listener.ora << 'EOF' SID_LIST_LISTENER = (SID_LIST = (SID_DESC = (GLOBAL_DBNAME = orcl) (ORACLE_HOME = /u01/app/oracle/product/11.2.0/db_1) (SID_NAME = orcl) ) ) EOF # 重启监听 lsnrctl reload

6.2 数据库实例验证:SELECT status FROM v$instance不是万能钥匙

v$instance视图只能查已启动的实例,但实例可能“假启动”——即pmon进程存在,但alert_orcl.log里有ORA-00600内部错误。必须结合日志分析:

# 实时跟踪告警日志(Ctrl+C退出) tail -f $ORACLE_BASE/diag/rdbms/orcl/orcl/trace/alert_orcl.log # 查看最近10行错误(过滤ORA-) grep "ORA-" $ORACLE_BASE/diag/rdbms/orcl/orcl/trace/alert_orcl.log | tail -10

常见错误及修复:

  • ORA-00313: open failed for members of log group 1→ 控制文件损坏,用startup mount后recover database
  • ORA-01157: cannot identify/lock data file 1→ 数据文件路径错误,在mount状态下alter database rename file

6.3 连接性终极测试:sqlplus的3种登录方式,暴露所有权限漏洞

# 方式1:操作系统认证(必须oracle用户,且/etc/passwd中shell为/bin/bash) sqlplus / as sysdba # 方式2:网络认证(验证监听和TNS) sqlplus system/password@localhost:1521/orcl # 方式3:本地命名(验证tnsnames.ora) echo "ORCL = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = orcl)))" >> $ORACLE_HOME/network/admin/tnsnames.ora sqlplus system/password@ORCL

若方式1成功、方式2失败,说明listener.ora中HOST写成了主机名而非localhost;若全部失败但pmon存在,则检查$ORACLE_HOME/dbs/initorcl.ora中db_name=orcl是否与ORACLE_SID一致。

6.4 自动化验证脚本:把5分钟人工操作压缩成1条命令

我把上述所有验证逻辑封装成ora_health_check.sh,放在$ORACLE_HOME/bin/下:

#!/bin/bash # ora_health_check.sh - Oracle 11gR2健康检查脚本 set -e echo "=== Oracle 11gR2 Health Check ===" # 检查进程 echo -n "PMON进程: "; ps -ef | grep pmon | grep -v grep >/dev/null && echo "✅" || echo "❌" # 检查监听 echo -n "监听器: "; lsnrctl status 2>/dev/null | grep "STATUS" >/dev/null && echo "✅" || echo "❌" # 检查数据库状态 echo -n "实例状态: "; sqlplus -S / as sysdba << 'EOF' 2>/dev/null | grep "OPEN" >/dev/null && echo "✅" || echo "❌" SELECT status FROM v$instance; EXIT; EOF # 检查告警日志错误 echo -n "最近错误: "; grep "ORA-" $ORACLE_BASE/diag/rdbms/orcl/orcl/trace/alert_orcl.log 2>/dev/null | tail -1 | wc -l | grep "0" >/dev/null && echo "✅" || echo "❌" echo "=== Check Complete ==="

赋予执行权限并运行:

chmod +x $ORACLE_HOME/bin/ora_health_check.sh $ORACLE_HOME/bin/ora_health_check.sh

输出全✅,才算真正交付。从那以后我每次部署完Oracle,都强制走一遍这个脚本——它比任何文档都诚实,不会因为“我觉得应该没问题”就放过一个ORA-00600。希望帮到你。

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进