对生产系统,特别是大型系统的正式环境,停机、升级和配置动作都是相当慎重的事情。shutdown命令虽然简单,但对于运维部门来讲,有时候一些shutdown过程中出现的问题也的确是让人挠头。
笔者的同事就遇到了这样的难题。同事维护一套很老的网站系统,后台使用Oracle数据库10gR1,具体版本是10.2.0.1,前台是J2EE框架的Web网站应用。由于系统比较老,一些长期的运行bug补丁没有处理。由于网站很快就要被替换,所以也没有过多进行干预,遇到问题往往见招拆招。
同事联系笔者,说关闭数据库出现长时间等待,类似hang住状态。前端应用是公司网站,长时间不能访问是很大麻烦。
1、故障现象
系统版本10.2.0.1。
LICENSE_MAX_USERS = 0
SYS auditing is disabled
ksdpec: called for event 13740 prior to event group initialization
Starting up ORACLE RDBMS Version: 10.2.0.1.0.
同事希望将数据库完整关闭后重启,解决一个出现的bug问题。但是在sqlplus命令行提示中输入shutdown immediate之后,就一直在等待状态。持续时间已经超过半个小时,让同事比较揪心。
说明:由于环境所限,后续笔者采取的操作没有记录下来,以步骤方式进行描述。
1) 后台单独启动一个命令行连接,使用ps –ef | grep pmon命令,确定Oracle pmon进程是否存在。这个进程是Oracle实例的标记进程;
2) 从ps –ef命令,可以看到Oracle实例的pmon进程还存在,还在后台运行;
3) 从另外的sqlplus /nolog登录,使用conn / as sysdba进入系统。结果显示connect to idle instance;
从上面的情况看,Oracle Instance应该还处在终止状态,没有完成shutdown过程。Oracle shutdown immediate过程包括终止回滚当前运行事务transaction,不允许新连接连入。当前Oracle处在“半死半活”状态。
2、问题解决
正常处理策略,应该是定位系统的alert log日志,确定当前数据库运行状态和是否有错误信息。如果有错误信息,就可以进行见招拆招的处理。但是时间有限,笔者也没有条件进行精细分析。于是,采用强制策略。
对数据库进行startup force操作。startup force包括两部分操作,shutdown abort和startup。之后,系统启动,各项操作运行正常。
事后,笔者和同事索要了alert log记录,进行进一步分析,希望发现问题关键。
3、Alert Log日志分析
在日志中,笔者很快定位到了最后一次关闭数据库动作。
--停止开始,关闭实例
Fri Aug 14 12:47:45 2015
ERROR: Emon failed to start.
Shutting down instance: further logons disabled
Fri Aug 14 12:47:45 2015
Stopping background process QMNC
Fri Aug 14 12:47:45 2015
Stopping background process CJQ0
Fri Aug 14 12:47:47 2015
Stopping background process MMNL
Fri Aug 14 12:47:48 2015
Stopping background process MMON
--进一步关闭后台进程
Fri Aug 14 12:47:49 2015
Shutting down instance (immediate)
License high water mark = 40
Fri Aug 14 12:47:49 2015
Stopping Job queue slave processes
Fri Aug 14 12:47:49 2015
Job queue slave processes stopped
Waiting for shared server 'S000' to die
All dispatchers and shared servers shutdown
--7分钟之后,定位问题进程
Fri Aug 14 12:54:05 2015
Active process 5640 user 'oracle' program 'oracle@mcw (J000)'
Active process 20559 user 'oracle' program 'oraclemmweb@mcw'
Active process 20561 user 'oracle' program 'oraclemmweb@mcw'
Active process 20569 user 'oracle' program 'oraclemmweb@mcw'
Active process 20557 user 'oracle' program 'oraclemmweb@mcw'
Active process 20555 user 'oracle' program 'oraclemmweb@mcw'
Active process 20563 user 'oracle' program 'oraclemmweb@mcw'
Active process 20565 user 'oracle' program 'oraclemmweb@mcw'
Active process 20567 user 'oracle' program 'oraclemmweb@mcw'
Active process 20571 user 'oracle' program 'oraclemmweb@mcw'
Active process 6808 user 'oracle' program 'oraclemmweb@mcw'
Active process 6795 user 'oracle' program 'oraclemmweb@mcw'
Active process 6786 user 'oracle' program 'oraclemmweb@mcw'
Active process 20553 user 'oracle' program 'oraclemmweb@mcw'
Active process 6730 user 'oracle' program 'oraclemmweb@mcw'
Active process 6775 user 'oracle' program 'oraclemmweb@mcw'
SHUTDOWN: waiting for logins to complete.
Fri Aug 14 13:07:49 2015
MMNL absent for 1218 secs; Foregrounds taking over
Fri Aug 14 13:34:50 2015
Shutting down instance (abort)
License high water mark = 40
Instance terminated by USER, pid = 7652
每条log日志,都可以看到对应的时间。消耗最多的是两个部分,第一个是终止dispatcher和s000共享连接进程关闭,消耗7分钟左右。另一部分是等待一系列active的活动进程中断连接,持续接近30分钟,直到笔者接入操作。
从进程格式来看,应该是前端网站系统连接进入的server process信息。链接数量上还是比较接近应用设置连接池的。
这就有问题了,我们直到Oracle的shutdown有几个选项。分别为:shutdown normal、transaction、immediate和abort,分别应对不同的操作动作。
- normal:禁止新连接连入,等待原有连入连接自行关闭断开后才关闭数据库;
- transaction:禁止新连接连入,原有空闲连接被强行断开,正在运行的事务等待结束之后,才关闭数据库;
- immediate:禁止新连接连入,原有空闲连接断开,正在运行事务强行中断,并且等待回滚结束后,才关闭数据库;
- abort:禁止新连接连入,如同突发断电;
同事使用的immediate关闭方式,如果有事务也被断开回滚,怎么还会等某些连接呢?
问题出现在已经连接的那些server process上,如果这些连接在运行长时间的查询操作,的确是要等待的。同事在进行关闭数据库操作的时候,似乎没有关闭前台应用,这样的话,原来连入的server process依然可以运行长作业。
那么,我们应该怎么使用shutdown immediate呢?在过去,笔者读过一位前辈的经验:
1) 根据对应用系统的了解,确定“先关应用,后关库”的操作顺序;
2) 通过v$transaction,确定系统中时候有“大会滚”作业存在,如果有,要联系事务的用户,进行系统外沟通;
3) 通过v$session_longops,确定系统中是否有长时间的查询动作;
4) 关闭OEM。10g之后,OEM以Web应用的方式存在,OEM与数据库的连接,也往往是阻断shutdown immediate的一个重要因素;
经过这些确认,才能进行稳妥的shutdown immediate操作。注意:shutdown immedaite虽然可以进行回滚,但是长时间hang住也可能是在进行大事务操作的回滚操作。
4、结论
最后,我们讨论一下如果已经进行shutdown immediate被hang住,从alert log中看到了进程信息怎么处理呢?
解决的方法是通过进程编号,分析进程性质和状态,逐个解决。如果是前台进程,可以考虑是应用连接断开或者加速回滚过程。如果是后台进程,可以考虑是数据库bug或者内部运行问题。
: