简介这份文档面向 Oracle 数据库运维与 DBA 人员聚焦 SGA 参数调整后数据库无法启动这一典型故障提供可落地的应急恢复思路。内容围绕 PFILE 与 SPFILE 的转换关系展开涵盖用 PFILE 创建 SPFILE、直接修改 PFILE 中错误的 SGA 参数、以及调整前备份 SPFILE 三类处理办法并附有 Linux 环境下 pfile 目录定位与 startup、create spfile、show parameters 等命令的实际输出示例便于对照排查。资源包共 1 个 docx 文件约 14KB体量轻便适合作为故障现场快速查阅的手册。目前已有 326 人学习下载说明该问题在实际运维中较为常见。读者可从中获得 SGA 异常启动的完整排错路径、参数修正要点与备份恢复意识帮助在数据库宕机时缩短定位时间、降低误操作风险。1. 改完 SGA 重启就起不来一个参数引发的“血案”生产库上执行了一条ALTER SYSTEM SET sga_target...或sga_max_size...scopespfile然后shutdown immediate再startup——结果数据库卡在ORA-00821、ORA-00823、ORA-00844、ORA-00845或干脆ORA-27102: out of memory上实例根本拉不起来。这不是玄学是 Oracle 改 SGA 时最典型的一类翻车现场参数写进了 spfile但操作系统层面给不了这么多内存或者参数之间自相矛盾实例在 nomount 阶段就被自己拒绝启动。这篇笔记只讲一件事——oracle 改 sga 导致数据库启动异常之后怎么在不重装、不丢数据的前提下把库救回来以及下次改之前该看哪几个数。适合手上正压着一个起不来的实例、又不敢乱动 spfile 的 DBA也适合刚接手一套老库、想搞清楚 SGA 参数边界的人。2. 先搞清 SGA 参数之间的“连环锁”为什么改一个会崩2.1 sga_target、sga_max_size、memory_target 的依赖关系Oracle 的 SGA 自动管理不是单个参数说了算而是一组参数互相约束。核心三个sga_target当前目标 SGA 大小、sga_max_sizeSGA 可增长的上限、memory_targetSGAPGA 的总目标属于 AMM 自动内存管理。它们的关系是开了 AMMmemory_target非 0时sga_target和pga_aggregate_target是它的下位参数sga_max_size不能超过memory_max_target。只开 ASMMmemory_target0sga_target非 0时sga_max_size必须大于等于sga_target否则实例直接拒绝启动。sga_max_size一旦大于操作系统能给的共享内存nomount 阶段就报ORA-27102或ORA-00845。很多人改 SGA 只盯着sga_target忘了sga_max_size还停在旧值或者反过来把sga_max_size调大却没确认/dev/shm够不够。实例启动时先读 spfile 里的参数再做内存分配任何一步对不上就停在 nomount连控制文件都不碰。2.2 启动异常到底卡在哪一步从 nomount 到 mount 的报错定位判断卡点最直接的办法是看 alert log 和启动时的报错号。常见对应关系如下报错号含义通常卡在ORA-00821sga_target 指定值超过 sga_max_sizenomount 参数校验ORA-00823sga_target 大于 sga_max_sizenomount 参数校验ORA-00844sga_target 太小无法启动nomount 参数校验ORA-00845/dev/shm 或内存文件系统不足内存分配ORA-27102out of memoryOS 给不了内存分配ORA-01078 / LRM-00109找不到或读不了 spfile/pfile实例初始化定位命令很朴素但顺序不能乱# 1. 先确认实例当前状态和报错 sqlplus / as sysdba SQL startup # 记下报错号别急着改参数 # 2. 看 alert log 最后 50 行确认卡在哪一步 tail -n 50 $ORACLE_BASE/diag/rdbms/db_name/sid/trace/alert_sid.log # 3. 确认 spfile 位置nomount 前也能查 SQL show parameter spfile逻辑说明startup失败后实例处于 nomount 或完全没起来此时还能用sqlplus / as sysdba连到空闲实例。alert log 会明确写出是参数校验失败还是 OS 内存分配失败这两类的救法完全不同。参数说明$ORACLE_BASE/diag/rdbms/...是 11g 及以后的标准诊断路径10g 在$ORACLE_BASE/admin/sid/bdump路径不对就先用show parameter background_dump_dest查。2.3 改 SGA 前必须确认的三个系统层数值改之前不看这三个数等于闭眼开车# 1. 物理内存和可用内存 free -m # 2. /dev/shm 大小AMM 或大 SGA 关键 df -h /dev/shm # 3. 内核共享内存上限 ipcs -lm # 或 sysctl kernel.shmmax kernel.shmall逻辑说明free -m看的是物理内存余量SGA 不能把机器吃干df -h /dev/shm在 Linux 上决定 AMM 能不能用/dev/shm默认常是物理内存一半SGA 超过它就会ORA-00845ipcs -lm和sysctl看的是kernel.shmmax单段共享内存上限和kernel.shmall总页数SGA 超过shmmax就ORA-27102。参数说明shmmax单位是字节shmall单位是页通常 4KBshmall * 页大小要大于等于 SGA。这三个数任何一个不满足spfile 里的值再漂亮也起不来。3. 实例起不来时的抢救路径从 pfile 兜底到参数回退3.1 用 pfile 绕过坏 spfile 先把实例拉起来实例因为 spfile 里的 SGA 参数起不来时最稳的抢救方式是临时用 pfile 启动把参数改回去再重建 spfile。前提是你手上有一份可用的 pfile或者能从 spfile 导出一份。# 方式一如果还有一份旧的 initSID.orapfile sqlplus / as sysdba SQL startup pfile/tmp/init_temp.ora # 方式二从当前 spfile 生成一份 pfile实例完全起不来时 # 可在 nomount 下用 create pfile from spfile SQL startup nomount # 若 nomount 也失败说明参数校验就过不了直接手写最小 pfile手写最小 pfile 的模板# /tmp/init_temp.ora 最小可启动参数 db_namedb_name instance_namesid sga_target2G sga_max_size2G pga_aggregate_target512M memory_target0 control_files/u01/app/oracle/oradata/db_name/control01.ctl db_block_size8192 compatible11.2.0.4.0逻辑说明pfile 是纯文本启动时直接读不经过 spfile 的二进制校验所以能把实例先拉到 nomount 甚至 open。参数说明sga_target和sga_max_size先给一个明显小于物理内存的值比如 2G确保能起来memory_target0表示关掉 AMM避免/dev/shm限制control_files必须指向真实控制文件否则 mount 会失败compatible按实际版本写。起来之后第一件事是show parameter sga确认当前值再决定最终要设多少。3.2 从 spfile 回退参数并重建的正确顺序实例用 pfile 起来后别急着create spfile from pfile覆盖先把参数改对。-- 1. 确认当前 spfile 路径 SQL show parameter spfile; -- 2. 用 pfile 启动到 open或至少 mount SQL startup pfile/tmp/init_temp.ora; -- 3. 把 SGA 参数改回安全值写进 spfile SQL ALTER SYSTEM SET sga_target2G SCOPESPFILE; SQL ALTER SYSTEM SET sga_max_size2G SCOPESPFILE; SQL ALTER SYSTEM SET memory_target0 SCOPESPFILE; -- 4. 关闭实例 SQL shutdown immediate; -- 5. 用 spfile 重新启动验证 SQL startup;逻辑说明第 3 步的SCOPESPFILE只改 spfile 不立即生效因为当前实例是用 pfile 起的改内存参数本来也需要重启。第 5 步用 spfile 启动成功说明参数已经回到安全区。参数说明如果原库是 AMM 模式memory_target要设回原值而不是 0但前提是/dev/shm已经调够sga_max_size不能小于sga_target两个值要么相等要么后者更小。3.3 确认实例真正 open 且 SGA 生效的验证命令启动成功不等于参数生效必须逐项核对-- 当前 SGA 实际分配 SQL show parameter sga_target; SQL show parameter sga_max_size; SQL show parameter memory_target; -- 从内存视图看真实分配 SQL SELECT component, current_size/1024/1024 AS mb FROM v$sga_dynamic_components; -- 确认实例状态 SQL SELECT status FROM v$instance; SQL SELECT open_mode FROM v$database;逻辑说明show parameter读的是当前生效值v$sga_dynamic_components看的是各组件真实占用两者对不上说明参数没落到内存。参数说明current_size单位是字节除以两次 1024 得 MBstatus应为OPENopen_mode应为READ WRITE。如果status是STARTED而open_mode空说明只到 nomountmount 没成功要回去查控制文件。4. 避坑与排查改 SGA 最常见的 5 个翻车点4.1 坑一只改 sga_target 没动 sga_max_size现象startup报ORA-00821或ORA-00823提示 sga_target 超过 sga_max_size。原因sga_max_size是上限sga_target是目标目标不能大于上限改的时候只改了一个。解决两个一起改且sga_max_size sga_target如果开了 AMM还要保证sga_max_size memory_max_target。4.2 坑二/dev/shm 太小导致 ORA-00845现象AMM 模式下启动报ORA-00845: MEMORY_TARGET not supported on this system。原因Linux 的/dev/shm默认是物理内存一半memory_target超过它就分配不了。解决临时mount -o remount,size8G /dev/shm永久写进/etc/fstab或者干脆关掉 AMM用 ASMMmemory_target0只留sga_target。4.3 坑三kernel.shmmax 没调够报 ORA-27102现象启动报ORA-27102: out of memoryalert log 里带Linux-x86_64 Error: 12。原因SGA 超过kernel.shmmax或kernel.shmall上限。解决sysctl -w kernel.shmmax字节、kernel.shmall页数写进/etc/sysctl.conf后sysctl -pshmmax建议设成物理内存的一半到全部shmall按shmmax/页大小算。4.4 坑四spfile 改坏后没有 pfile 兜底现象startup报ORA-01078或LRM-00109spfile 读不了实例完全起不来。原因直接编辑 spfile 或改参数时写入了非法值二进制文件损坏。解决平时养成CREATE PFILE FROM SPFILE备份的习惯出事时用备份 pfile 启动再CREATE SPFILE FROM PFILE重建。没有备份就手写最小 pfile参考 3.1 的模板。4.5 坑五改完不验证就 shutdown回不了头现象改完参数直接shutdown immediate再启动失败生产中断。原因内存参数改动必须重启才生效但重启前没做参数合法性预检。解决改 spfile 后先用startup nomount试一次不改动数据文件确认参数校验能过再正式重启或者保留当前实例不动另起一个测试实例用同一份 spfile 验证。5. 把 SGA 改动做成可回退操作我的三条硬习惯改 SGA 这件事真正值钱的不是记住几个报错号而是把每次改动都做成能回退的操作。我自己的硬习惯有三条。第一条动 spfile 之前先CREATE PFILE FROM SPFILE/tmp/init_sid_日期.ora这份 pfile 就是后悔药实例起不来时startup pfile...能救命。第二条内存参数永远成组改sga_target、sga_max_size、memory_target三个一起看改完用startup nomount做一次参数校验通过了再shutdown正式重启别拿生产实例当试验田。第三条改之前把free -m、df -h /dev/shm、ipcs -lm三个数抄下来SGA 目标值必须同时小于物理可用内存、/dev/shm和shmmax三个里有一个不满足就先调系统层别硬改数据库参数。再补一个验证技巧如果拿不准新 SGA 值能不能起来可以在一台同配置的测试机上用同一份 spfile 副本启动或者在生产机上用startup nomount pfile/tmp/init_test.ora只做参数校验nomount 成功就说明参数本身合法剩下的才是 OS 内存够不够的问题。这个办法我用来拦下过好几次“参数写错但还没重启”的隐患。最后说个血泪教训曾经有一次改sga_max_size只改了 spfile 没同步sga_target重启直接ORA-00821好在提前备了 pfile十分钟拉回来。从那以后我改任何内存参数都先备份 pfile、再成组改、最后 nomount 预检三步一步不省。希望帮到你。本文还有配套的精品资源点击获取