今天在解决一个问题时数据库hang住了。日志也没有啥错误,用sqlplus ‘/as sysdba'登陆进去后就一直卡在哪里了,很是郁闷。
迫不得已强制登陆sqlplus,
$sqlplus -prelim /as sysdba
如果可以查询sql语句,可以先生成killsession脚本,然后kill掉session后在关闭数据库。
1. 生成OS级kill -9脚本
set head off
set feedback off
set pagesize 0
spool /tmp/kill_9_1.sh
select ' kill -9 ' || spid from (select spid from v$process where addr in(select paddr from v$session where status='ACTIVE' and username is not null));
spool off
2.生成DB级kill session脚本
set head off
set feedback off
set pagesize 0
spool /tmp/kill_sess_1.sql
select 'alter system kill session ' || '''' || sid || ',' || serial# || '''' || ';'from v$session where status='ACTIVE' and username is not null;
spool off
3.执行kill_sess.sql脚本
SQL>@/tmp/kill_sess_1.sql
如果session kill之后不能2分钟内不能释放执行OS级kill -9脚本
sh /tmp/kill_9_1.sh
如果kill session无效,无法恢复应用,进行后续操作5-15步:
4. 如果发现有异常进程,在OS级进行truss:
truss -o /tmp/mytruss -p <pid of process>
5. alter system set job_queue_processes=0;
alter system set aq_tm_processes=0;
6. lsnrctl stop listener_xxx
7. sqlplus “/as sysdba”
oradebug setmypid
oradebug unlimit
oradebug dump systemstate 10
等1分钟
oradebug dump systemstate 10
等1分钟
oradebug dump systemstate 10
Exit
如果数据库处于HANG状态:
sqlplus “/as sysdba”
oradebug setmypid
oradebug unlimit
oradebug hanganalyze 3
等1分钟
oradebug hanganalyze 3
oradebug dump systemstate 10
等1分钟
oradebug dump systemstate 10
等1分钟
oradebug dump systemstate 10
Exit
该步骤超过15分钟,停止做systemstate dump
8. 再次生成OS级kill -9脚本,KILL所有ORACLE用户进程
set head off
set feedback off
set pagesize 0
spool /tmp/kill_9_2.sh
select ' kill -9 ' || spid from (select spid from v$process where addr in(select paddr from v$session where username is not null));
spool off
9.再次生成DB级kill session脚本,kill所有ORACLE用户进程
set head off
set feedback off
set pagesize 0
spool /tmp/kill_sess_2.sql
select 'alter system kill session ' || '''' || sid || ',' || serial# || '''' || ';'from v$session where username is not null;
spool off
10.再次执行kill_sess.sql脚本
SQL>@/tmp/kill_sess_2.sql
如果session kill之后不能2分钟内不能释放执行OS级kill -9脚本
sh /tmp/kill_9_2.sh
11. Select group#, status, archived from v$log where status in ('ACTIVE', 'CURRENT');
select RECOVERY_ESTIMATED_IOS,ACTUAL_REDO_BLKS,TARGET_REDO_BLKS,LOG_FILE_SIZE_REDO_BLKS,TARGET_MTtr,ESTIMATED_MTTR from v$Instance_recovery;
如果group处于active 状态的个数超过1个,并且v$instance_recovery.estimated_mttr大于600秒则最好延迟数据库的关闭,等待I/O量下降,
等到v$instance_recovery.estimated_mttr小于v$instance_recovery.target_mttr,否则数据库启动的时间会达到v$instance_recovery.estimated_mttr的时间。
(如果v$instance_recovery.estimated_mttr小于600秒,启动数据库采用方法一,否则采用方法二。)
12. Alter system checkpoint
Alter system switch logfile;
Shutdown immediate
13. 等5分钟,关闭还未结束,alert.log中没有相关的关闭信息
shutdown abort
14. ps -ef|grep LOCAL|grep oracle"$ORACLE_SID"
ps -ef|grep ora_|grep "$ORACLE_SID"
使用kill -9 pid
15. ipcs –a |grep ORACLE_USER
查找信号灯是否未释放,如果未释放,使用ipcrm清理信号灯:
ipcrm -m shmid
ipcrm -s semid
我没有安装步骤做,直接就从第7步开始的,然后做第八步二次后,shutdown immediate依然不行,所以就直接shutdown abort了,幸运的是起库很顺利的起起来了。