十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ORA-01034报错排查全攻略:从实例失联到快速恢复

ORA-01034报错排查全攻略:从实例失联到快速恢复 做Oracle运维的谁没见过ORA-01034但有意思的是这个报错几乎人人都遇过可真要快速定位到根因能一次搞对的却没几个。ORA-01034英文全称是“ORACLE not available”翻译过来就是“Oracle不可用”。它不是一个独立的故障而是一个结果——客户端或者本地进程根本找不到一个健康的Oracle实例自然也就没法连接了。这篇就围绕ORA-01034把整条排查链路讲透从环境变量、监听、实例启动状态到alert日志每一步都会给出实操命令和判断依据。无论你是刚装完Oracle才几天的新手还是在生产环境被这个报错恶心过无数次的运维老手都能在里面找到可以直接照着做的方案。1. 认识ORA-01034先搞清楚它到底在说什么1.1 报错背后是实例“失联”而不是数据丢了ORA-01034报错时很多人第一反应是“数据库挂了”“数据是不是没了”。我可以负责任地说绝大多数情况下你的数据文件、控制文件、联机日志都完好无损问题出在“实例”这一层。Oracle的架构里有两个容易混淆的概念实例和数据库。实例指的是SGA内存区加上那堆后台进程比如PMON、SMON、DBWn、LGWR这些数据库则是磁盘上的物理文件集合包括数据文件、控制文件、参数文件、归档日志等。平时我们连接Oracle实际是连接“实例”由实例去读写磁盘上的数据库文件。用个生活里的类比实例就像一台发电机组数据库文件就像电网线路。ORA-01034报错相当于调度中心联系不上发电机组了——但这并不代表电厂不存在了只是机组当前没在运转。所以遇到这个报错你先别慌着脑补“数据全没了”的灾难场景绝大多数时候数据都安安稳稳躺在磁盘上只需要把实例重新拉起来就完事了。另外要注意一个细节ORA-01034的出现时机不同排查方向是完全不同的。比如你用sqlplus / as sysdba能登录但一执行SQL就报ORA-01034和你在Navicat里连远程数据库直接弹出ORA-01034这两种场景对应的原因范围差异很大。前者多半是实例没启动或者启动到一半后者还要叠加考虑网络、监听、服务名解析、防火墙这些因素。这篇后面的排查顺序就是按照“本地实例优先、网络监听其次”的思路来安排的。1.2 为什么ORA-01034总跟“一堆错误”一起出现单独出现ORA-01034的情况其实不多更多时候它是和ORA-27101、ORA-12541、ORA-12560、ORA-12514这些报错组合出现的。很多新手一看到屏幕上好几个ORA-开头的错误就头皮发麻其实Oracle的报错机制是分层的最外层告诉你“ORACLE not available”这只是一个笼统的总结论再往下看才会暴露具体原因。比如最常见的组合是ORA-01034: ORACLE not available和ORA-27101: shared memory realm does not exist一起出现。ORA-27101的意思是“共享内存段不存在”翻译成人话就是客户端试图去找Oracle实例在操作系统里创建的那块共享内存结果发现压根没有这个内存段。这通常意味着实例根本没启动或者刚启动就因为某种原因崩了。明白了这层关系你就会发现一个关键思路**遇到ORA-01034不要只盯着它本身要把它当成一条排查线索一层一层往下挖。**后面我会专门用一个章节讲常见组合错误的辨别方法这里先带大家把Oracle的基础排查框架建立起来。2. 手把手排查从环境变量到告警日志2.1 第一板斧确认ORACLE_SID与登录方式ORA-01034有个非常容易踩的坑——根本不是数据库坏了而是你连错了实例名SID。尤其是在一台服务器上装了多个Oracle实例的环境里环境变量一搞错后面全乱套。先检查当前会话的SID# Linux / Unix echo $ORACLE_SID # Windows 命令行 echo %ORACLE_SID%输出应该是你打算连接的实例名比如ORCL、PDB1。如果输出为空或者指向了别的实例那你连的时候自然就找不到目标实例报ORA-01034也就不奇怪了。确认SID之后用最高权限登录试试sqlplus / as sysdba正常情况下会进入SQL提示符。如果这里直接报ORA-01031: insufficient privileges说明当前操作系统用户不在dba组Linux或ora_dba组Windows里连管理入口都进不去。此时先用系统管理员身份把用户加进组再重新登录。注意sqlplus / as sysdba走的是操作系统认证不需要用户名密码。如果你是用sqlplus system/xxx这种方式登录那就得确认密码是否正确以及账号是否被锁。但通常排查ORA-01034时/ as sysdba是第一条路。还有一种容易混淆的情况SQL*Plus能登录但执行任意查询都报ORA-01034。这说明你的会话已经连上了某个进程但它不是一个完整可用的实例——比如实例正卡在NOMOUNT或MOUNT状态或者刚启动到一半就崩了。这时候往下走直接查alert日志。2.2 第二板斧定位并阅读alert日志alert日志是Oracle的“黑匣子”每一次实例启动、关闭、控制文件变更、严重错误都会在这里留下记录。遇到ORA-01034alert日志基本就是我们判断根因的第一手资料。不同版本路径不一样先分清# Oracle 11g及之后版本默认路径基于ADR $ORACLE_BASE/diag/rdbms/{DB_UNIQUE_NAME}/{SID}/trace/alert_{SID}.log # Oracle 9i/10g 老版本 $ORACLE_HOME/admin/{SID}/bdump/alert_{SID}.log大多数情况下$ORACLE_BASE可以通过echo $ORACLE_BASE查出来DB_UNIQUE_NAME通常和SID相同如果没配过也不会差太远。查看日志末尾内容tail -200 $ORACLE_BASE/diag/rdbms/*/ORCL/trace/alert_ORCL.log重点关注最后的ORA-错误码和Errors in file字段。比如看到ORA-01157: cannot identify/lock data file说明有数据文件缺失或无法锁定看到ORA-00257: archiver error说明归档目录满了导致实例hang住看到ORA-07445这类内部错误则要考虑Bug或补丁问题。这里分享一个实操习惯**每次排查时先把alert日志里最后50行复制到一个临时文件里然后按时间线把错误前后的记录串起来读一遍。**很多根因不是那个错误码本身而是它前几行的某个Warning信息。比如“Shutting down instance”后面跟着“Terminating instance”和“ORA-01034”往往说明是有人手动执行了shutdown abort或者操作系统OS进程被kill了。2.3 第三板斧检查操作系统层面的资源实例起不来很多时候不是Oracle配置的问题而是操作系统层面被“卡住”了。下面这几条命令属于检查清单按顺序过一遍基本能把OS层面的坑排除干净。# 内存是否充足 free -h # 共享内存段和信号量情况 ipcs -a # 磁盘空间是否打满重点看ORACLE_HOME和ORACLE_BASE所在分区 df -h # Oracle可执行文件的属主和权限 ls -l $ORACLE_HOME/bin/oracle # 当前进程数限制、打开文件数限制 ulimit -u ulimit -n磁盘满是个很隐蔽的坑。如果$ORACLE_BASE所在分区被归档日志或diag目录撑爆了Oracle可能连写alert日志的余地都没有实例启动到一半都会失败。还有一种情况是/tmp分区满了安装或启动时写入临时文件失败也会导致各种莫名其妙的错误。我在生产环境就碰过/tmp爆满导致SQL*Plus直接起不来的情况排查到最后才发现是临时文件目录的问题。如果看到ipcs -a里Oracle用户对应的共享内存段数量为0而ps -ef | grep ora_ | grep -v grep也查不到任何后台进程那基本可以判定实例没有在运行。接下来要做的不是抓瞎重启而是先搞清楚它为什么没起来——是人为shutdown了还是崩了此刻再看一眼alert日志的结尾就能得到答案。2.4 快速判断实例到底起来没有有三招可以快速判断实例状态适合任何场景下“先探个底”# 1. 查后台进程 ps -ef | grep pmon | grep -v grep # 2. 查监听服务状态 lsnrctl status # 3. 登录后查看实例状态 sqlplus / as sysdba SQL select status, instance_name from v$instance;ps -ef | grep pmon是最直观的如果能看到ora_pmon_ORCL这样的进程说明实例进程至少还活着。lsnrctl status能看到实例有没有动态注册到监听器上。而v$instance查询的结果更精确——状态返回OPEN说明数据库完全打开返回MOUNTED说明控制文件已加载但数据文件未打开返回STARTED说明实例刚启动连控制文件都没加载如果查询直接报错或超时那就是实例没有正常运行。这里插一句有些人喜欢用tnsping来判断数据库是否可用这其实是个常见误区。tnsping只能测试网络通不通、监听在不在它并不能确认实例是否真的可用。监听起来了实例照样可能处于半死不活的状态。真正的连接测试还是要靠实际发起一个数据库会话。3. 实例启动实操从shutdown到open的完整过程3.1 常规startup流程确认实例确实没起来且alert日志里没有明显的“致命伤”就可以尝试启动了。最常规的做法sqlplus / as sysdba SQL startup正常的输出是这样ORACLE instance started. Total System Global Area 1073741824 bytes Fixed Size 4569416 bytes Variable Size 872417336 bytes Database Buffers 184549376 bytes Redo Buffers 12173312 bytes Database mounted. Database opened.这3行状态依次说明实例分配了SGA并启动了后台进程、加载了控制文件、打开了数据文件和联机日志。只要走到Database opened数据库就可以对外提供服务了。但实际操作中startup直接成功的场景反而少见更多时候它会甩给你一段新的错误。比如ORA-01157: cannot identify/lock data file 4 - see DBWR trace file ORA-01110: data file 4: /oradata/users01.dbf这个报错说明数据文件users01.dbf有问题——可能被误删了也可能权限不对。又比如ORA-00257: archiver error. Connect internal only, until freed.这是归档目录满了实例拒绝打开。处理方式就两个字清盘。清理掉旧的归档日志后再alter database open基本就能恢复。3.2 分步启动mount和open的适用场景直接startup相当于“一把梭”如果中间某步出问题你得从头排查。更稳妥、也更能看清楚问题的做法是分步走SQL startup nomount; SQL alter database mount; SQL alter database open;每一步都有它的应用场景。startup nomount只做三件事读取参数文件、按参数分配SGA、拉起后台进程。它不读取控制文件也不打开数据文件。这个模式适合做控制文件重建、恢复参数文件验证、创建新数据库等场景。如果你怀疑是参数文件或内存参数出了问题先停在nomount阶段能快速验证“实例本身能不能拉起来”。alter database mount会读取控制文件并把实例与数据库文件关联起来但此时依然不打开数据文件。这个模式是做数据文件更名、重定位、控制文件备份恢复、归档模式切换、做不完全恢复的标配起点。alter database open才是最后一步打开数据文件和联机日志数据库正式对外服务。如果卡在这一步说明物理文件层面的完整性有问题比如某个数据文件损坏、联机日志丢失、或控制文件与数据文件不一致。这个分步启动的思路在排查ORA-01034时特别有用。比如你startup报错但不知道具体卡在哪一步就可以先startup nomount如果这一步就报错那问题100%在参数文件或内存配置如果nomount成功但mount报错问题在控制文件或参数中指定的文件路径如果mount成功但open报错问题在数据文件或联机日志。这样一把就把故障范围缩小了一大半。3.3 Windows平台与Linux平台的差异处理Windows平台上处理ORA-01034思路和Linux不完全一样。首先Windows上的Oracle实例通常绑定为系统服务服务名叫OracleService{SID}比如OracleServiceORCL。这个服务没起来或者启动失败实例就不可能运行。查看服务状态# Windows命令行管理员权限 net start | findstr Oracle如果列表里没有OracleServiceORCL说明服务没启动可以用net start OracleServiceORCL或者干脆在“服务”管理工具里手动启动。同理监听器也有对应的服务比如OracleOraDB19Home1TNSListener名字里的Home名随版本不同而不同。很多网友吐槽“oracle监听服务无法启动”多半是监听配置文件listener.ora有问题或者端口被占用了——这个话题我会在后面监听章节详细说。Linux平台则没有这个“服务”概念实例启动完全靠手动或自启动脚本。如果你希望重启服务器后数据库能自动起来得修改/etc/oratab文件把对应SID那一行的最后一个N改成Y# /etc/oratab ORCL:/u01/app/oracle/product/19.3.0/dbhome_1:Y改完后可以用dbstart脚本尝试启动。不过需要提醒的是dbstart的可靠性因版本和环境而异生产环境我更推荐用systemd或自定义启动脚本来管理避免依赖遗漏导致开机起不来。Crontab搭配reboot也是一种轻量方案总之别让Oracle的启动完全听天由命。3.4 特殊场景归档模式与DG环境下的启动注意事项如果你的数据库开了归档模式启动时还要留意归档日志目录的容量。我在startup实战中经常遇到这样的情况明明数据文件都正常但alter database open执行后数据库一直处于RECOVER状态查询视图卡住连接又报ORA-01034最后发现是归档目录满了LGWR后台进程没法写归档整个实例处于停滞状态。处理方式先给归档目录腾空间——清理掉已经备份过的归档日志再重新尝试打开数据库。如果多次清理后空间仍然紧张就要考虑调整归档策略或扩展目录容量了否则“启动成功-运行一天-又满”的死循环会反复折磨人。DG环境Data Guard里也有一个常见的ORA-01034“假象”。比如主库正常但备库某天被别人误操作shutdown过此时你去连备库可能就会报ORA-01034。对于物理备库正常状态是实例处于MOUNTED状态如果是Active Data Guard则处于READ ONLY并且MRP日志应用进程在跑。需要重现看备库状态可以用sqlplus / as sysdba SQL select process, status, thread#, sequence# from v$managed_standby;如果MRP0进程不存在说明日志应用停了备库自然会有数据延迟甚至某些查询也连不上。这时候你在主备切换、双DG库的环境中要特别仔细别把正常的备库状态误判为故障。4. 与ORA-01034形影不离的“姊妹错误”4.1 ORA-01034 ORA-27101共享内存问题这对组合是排查ORA-01034时最常碰到的。错误信息长这样ORA-01034: ORACLE not available ORA-27101: shared memory realm does not existORA-27101直译是“共享内存域不存在”。在Linux/Unix平台Oracle实例启动时会创建一段共享内存命字为sga或类似所有连接到这个实例的进程通过共享内存来通信。如果找不到这段共享内存说明实例压根没有在运行。处理思路分两步。第一步用ipcs -m查看系统里有没有Oracle创建的共享内存段如果没有确认实例是否启动失败如果实例的确正在运行但报这个错那可能是SGA参数超出了内核限制。第二步检查内核参数sysctl -a | grep kernel.shm重点看kernel.shmmax和kernel.shmall这两个值。shmmax代表单个共享内存段的最大字节数如果它小于你设置的SGA_TARGETOracle就可能无法创建共享内存。解决办法要么减小SGA要么调大内核参数。修改内核参数后用sysctl -p立即生效但生产环境记得评估影响再操作。4.2 ORA-01034 ORA-12541/ORA-12560监听与连接层远程连接时ORA-01034常常跟ORA-12541或ORA-12560搭伴出现。ORA-12541: TNS:no listener字面意思是“没有监听器”。也就是说客户端根本找不到在目标IP端口上监听的进程。常见原因监听进程没起来、监听端口被防火墙挡了、listener.ora配置的IP和实际不一致。先用lsnrctl status看看监听当前状态如果提示TNS-12541: TNS:no listener或者没有任何输出用lsnrctl start启动。ORA-12560: TNS:protocol adapter error在Windows上出现得多往往和Oracle服务没启动有关。数据库服务都没起来的情况下连接时协议适配器自然无法工作。这类错误经常出现在“明明装了Oracle却怎么也连不上”的新手场景里模拟的就是Oracle安装后忘了启动服务/实例的状况。解决方式是先把OracleService{SID}和OracleOraDB19Home1TNSListener这两个服务都确认一遍再尝试连接。4.3 ORA-01034 ORA-12514服务名解析故障还有一种常见的组合是ORA-01034: ORACLE not available ORA-12514: TNS:listener does not currently know of service requested in connect descriptorORA-12514的意思是监听器不知道你要连接的那个服务名。它和ORA-12541的区别在于监听是活着的但监听里没注册这个服务。最常见的原因就是——实例没有启动。因为实例没起来动态注册机制就没有机会把服务名注册到监听器上。所以很多时候ORA-12514只是表象根源还是实例没运行。先启动实例服务名会自动注册到监听器。如果实例已经在运行但监听还是不识别服务可以在SQL*Plus里手动注册一下SQL alter system register;或者检查local_listener参数是否指向了正确的监听地址。还有种情况是你在连接串里写的SERVICE_NAME和实例实际的DB_NAME、SERVICE_NAME不一致也会触发ORA-12514这时候检查tnsnames.ora里的配置就行。4.4 报错组合速查表组合报错核心问题排查方向ORA-01034 ORA-27101实例未启动或共享内存不存在检查pmon进程、共享内存、SGA参数ORA-01034 ORA-12541监听未启动或端口不通检查监听进程、listener.ora、防火墙ORA-01034 ORA-12560服务停止或协议适配器异常Windows检查Oracle服务Linux检查socketORA-01034 ORA-12514服务名未注册到监听启动实例、alter system register、检查tnsnamesORA-01034 ORA-01157数据文件缺失或无法锁住检查数据文件路径、权限、磁盘空间ORA-01034 ORA-00257归档目录满清理归档日志、调整归档策略这张表是我自己做故障标签用的遇到组合报错先看眼表的“排查方向”基本能少走一半弯路。特别提醒一句ORA-01034后面跟的那个错误往往才是真正的问题——它就像一串报警器里那个最响的值得你多花点时间去深挖它。5. 真实场景复盘三个我踩过的坑5.1 场景一服务器重启后数据库“消失”第一天下午正常关机第二天早上业务方急吼吼跑过来“数据库连不上了报ORA-01034”我第一反应不是马上启动数据库而是先查alert日志。tail -200后看到实例最后停止的原因是Shutting down instance (immediate) ... Instance shutdown complete这段说明数据库不是崩溃而是优雅地关闭了。再查/etc/oratab发现对应SID的那一行末尾还是N也就是没有配置开机自启。说白了服务器重启后Oracle实例压根没被拉起来。解决很简单先手动启动实例再把oratab里改成Y。顺手写了个systemd服务确保今后开机自动拉起数据库。这个案例的教训是服务器重启后ORA-01034先别急着用“数据库坏了”的思路去查优先确认是不是没有配置自启这一步能省下大量时间。5.2 场景二内存参数调太大实例起不来这事发生在一台测试环境的Oracle 19c上。当时为了测性能把SGA_TARGET调到了32GB结果实例重启后直接报ORA-01034加ORA-27101。查ipcs -m共享内存段确实不存在再用free -h一看服务器物理内存总共才24GB。问题很清楚了参数配得比物理内存还大实例能起来才怪。由于SGA_TARGET存在spfile里而spfile已经导致实例无法启动这时候最有效的办法是绕过spfile用pfile先拉起来sqlplus / as sysdba SQL startup pfile$ORACLE_HOME/dbs/initORCL.ora;pfile里如果没有显式设置SGA_TARGETOracle会使用默认值。实例起来后再通过alter system set sga_target16G scopeboth;调整妥当。关键是记住改内存参数这种事一定要先确认机器物理内存和张量再动手。有了pfile备份sga调坏也能救回来。5.3 场景三DG备库的“假象”某客户环境是主库加两套DG备库某天监控平台报警说有台备库实例状态异常。登录一看主库好好的但备库连接报ORA-01034检查ps -ef | grep pmon备库的ora_pmon_standby进程竟然不存在了。一开始以为备库挂了准备重新startup。但想了想先看/u01/app/oracle/diag/rdbms/standby/STANDBY/trace/alert_standby.log结果发现是备库执行过shutdown后来因为某个环节没跟上没有自动恢复MRP进程。这里要特别提醒物理备库正常状态本来就是MOUNTED或READ ONLY WITH APPLY不能按普通单机库的标准去要求它处于OPEN状态。对备库做了错误的重启操作后要么先恢复MRP要么根据主备切换流程重新初始化。在DG环境里误判备库状态导致的“假故障”比真的故障还多。排查时多看看v$archive_dest_status、v$managed_standby这些视图比瞎重启靠谱得多。5.4 避坑经验清单每次操作前先看alert日志别急着startup日志里会告诉你上一次发生了什么。改参数前备份spfile生成pfile只需要一句话create pfile/tmp/initORCL.ora from spfile;服务器重启后第一时间确认/etc/oratab和远程连接依赖的服务状态别等告警出来再补。检查Oracle实例之前顺手df -h看一眼磁盘归档满、/tmp满都够喝一壶的。遇到组合错误永远先解析ORA-01034后面的那个错误那才是真正的原因所在。在DG环境里分清主库和备库的正常状态别把备库的MOUNTED误判成故障。6. 常见问题与排查技巧实录6.1 照表操作最常见报错组合与处理方案这里整理一个高频问题速查表是我平时排查时对照用的遇到类似现象可以直接按行列执行。现象可能原因操作步骤本地sqlplus登录后查表报ORA-01034实例没有启动检查pmon进程执行startup远程客户端连接报ORA-01034ORA-12541监听未启动lsnrctl start确认端口和防火墙远程客户端连接报ORA-01034ORA-12514服务名未注册先startup实例再alter system register连接报ORA-01034ORA-27101共享内存段不存在检查ipcs -m、内核共享内存参数和SGA配置启动时卡在mount或open阶段物理文件或归档日志有问题查看alert日志具体ORA-错误清理归档或恢复文件Windows下连接报ORA-01034ORA-12560Oracle服务未启动net start OracleService{SID}检查监听服务服务器重启后报ORA-01034没有配置开机自启startup拉起实例修改/etc/oratab和自启脚本这张表的原则是“先看它对不对症”如果现象和原因对不上宁可多查几下也不要贸然操作。比如远程连接报ORA-12514你会先想到服务名注册但如果你先停监听、再启监听反而可能把本来的注册状态搞乱——所以对症下药很重要。6.2 多年DBA生涯的几条心得讲完技术说点实在的。我是从应用开发转行做数据库运维的头两三年没少被ORA-01034这种基础报错折磨。现在回头来看这类问题其实并不可怕它最难的地方不是解决而是“别在排查时自己吓自己”。我的经验是遇到ORA-01034先执行“三查三看”查环境变量、查pmon进程、查alert日志看磁盘空间、看共享内存、看监听状态。这一套流程走下来80%的ORA-01034都能定位清楚。真正让我后来效率变高的不是背了更多命令而是养成了“按顺序排查、保留现场、记录日志”的习惯。麻烦的时候比如一次性报好几个ORA错误我会先把所有报错信息截图或复制到文件里再逐个拆解这样比在脑海里硬扛清晰得多。另外永远给自己留一条后路。生产环境里脚本操作前先备份spfile、改参数前先记录原值、清归档前先确认备份这些看起来不起眼的习惯关键时刻能救命。最后再分享一个小技巧如果你预感要停电或者重启服务器提前把alter system checkpoint做了再优雅地shutdown immediate。这样做的好处是既缩短恢复时间也省得恢复过程中碰到那些本可避免的报错。这些年我在不同环境里被ORA-01034教育过很多次现在每次遇到它的第一反应已经不是“急着启动”而是先花两分钟把环境变量、操作系统资源、告警日志看一遍。这个习惯帮我少走了很多弯路也推荐你在生产环境试一试。
返回列表