Oracle shutdown immediate关不掉------一次排坑实录
Oracle执行
shutdown immediate半天关不掉。监控IO发现只有控制文件在读写,其他数据文件全部静默。最终强制关库,重启后一切正常。这个案例值得记录,因为"关不掉"比"打不开"更让人慌。
文章目录
- [Oracle shutdown immediate关不掉------一次排坑实录](#Oracle shutdown immediate关不掉——一次排坑实录)
-
- 背景
- [一、shutdown immediate卡住了](#一、shutdown immediate卡住了)
- 二、监控IO,发现异常
- 三、判断:继续等还是强杀?
- 四、强制关库
- 五、验证业务
- 六、复盘:为什么卡住了?
- 七、几点经验
背景
某天,运维通知配合云厂商做服务器降配------内存从64G降到32G,CPU也相应减少。需要先把数据库停掉再操作。
数据库是Oracle 11g,跑了几年,数据量不大(几百GB),平时运行正常。
计划很简单:停应用 → shutdown immediate → 等云厂商降配 → 启动数据库 → 启动应用。
前三步出了问题。
一、shutdown immediate卡住了
sql
SQL> shutdown immediate;
敲完回车,等了5分钟,没反应。正常情况下这个库shutdown最多两三分钟。
又等了10分钟,还是没有返回。光标就停在那儿,什么都不输出。
shutdown immediate的行为是:
- 不让新会话登录
- 等活跃事务提交或回滚
- 把buffer cache里的脏块写盘(checkpoint)
- 关闭所有文件,退出
如果卡住,通常是第2步或第3步。要么有大事务在回滚,要么脏块太多写不完。
二、监控IO,发现异常
开另一个终端,用iostat看磁盘IO:
bash
iostat -x 2 5
发现:只有控制文件所在的磁盘有IO活动,数据文件、redo日志、归档日志全部静默。
又查了Oracle的等待事件:
sql
select event, wait_class, count(*)
from v$session
group by event, wait_class
order by count(*) desc;
等待事件显示的是control file sequential read和control file parallel write,反复出现。
这个现象说明:
- checkpoint已经做完了------数据文件没有IO就是证据,脏块已经写完了
- shutdown在等其他东西------不是IO瓶颈,是某个内部流程卡住了
控制文件在shutdown immediate期间被反复读写,这是Oracle在做检查点推进和SCN更新。正常情况下这个过程很快,但如果实例状态有点脏(比如有大事务还没清理完,或者SMON在后台做事务恢复),这个过程就会反复刷控制文件。
三、判断:继续等还是强杀?
两个选择:
- 继续等------不确定要等多久,可能是几分钟,也可能是几小时。而且降配窗口有时间限制,不能无限等下去。
- shutdown abort------强制关库,不等了。风险是实例恢复(instance recovery)需要时间,但Oracle的崩溃恢复机制是成熟的。
想了想,决定强杀。理由:
- checkpoint已经完成了(数据文件没有IO)
- redo日志也是静默的,说明没有活跃事务在产生redo
- 唯一的风险是SMON可能还在回滚某些东西,但重启后SMON会继续做,不丢数据
四、强制关库
sql
SQL> shutdown abort;
ORACLE instance shut down.
秒关。
然后启动:
sql
SQL> startup;
ORACLE instance started.
Total System Global Area xxx bytes
Fixed Size xxx bytes
Variable Size xxx bytes
Database Buffers xxx bytes
Redo Buffers xxx bytes
Database mounted.
Database opened.
启动过程中,alert日志里可以看到SMON在做实例恢复(instance recovery):
SMON: enabling cache recovery
SMON: enabling tx recovery
Completed crash recovery at ... (scn ...)
整个过程十几秒,没有报错。
五、验证业务
数据库打开后,检查了一下:
sql
select status from v$instance;
STATUS
------------
OPEN
select count(*) from v$recover_file;
COUNT(*)
----------
0
实例状态OPEN,没有需要恢复的文件。通知应用启动,业务验证正常。
六、复盘:为什么卡住了?
事后分析,最可能的原因:
降配前,服务器资源已经开始被限制了。 云厂商在窗口期之前可能已经做了部分资源限制(比如IOPS上限降低),导致Oracle在做最后的清理工作时,控制文件的IO变慢。shutdown immediate要反复更新控制文件中的检查点SCN,在IO受限的情况下就卡在那里了。
加上shutdown immediate本身是一个同步阻塞操作------它不告诉你进度,你也不知道它卡在哪一步,只能干等。
七、几点经验
1. shutdown immediate卡住不要慌,先看IO。
用iostat或v$session_wait看等待在哪里。如果数据文件有IO,说明checkpoint还在做,可以等。如果只有控制文件有IO,大概率是内部清理工作,可以考虑shutdown abort。
2. shutdown abort没有想象中那么可怕。
很多人一听abort就怕数据丢失。实际上Oracle的WAL(Write Ahead Logging)机制保证了:只要redo日志没坏,shutdown abort后重启,SMON会自动做前滚(roll forward)和回滚(rollback),数据不会丢。
3. 维护前,提前做一次checkpoint。
sql
alter system checkpoint;
alter system switch logfile;
手动触发一次checkpoint和日志切换,把脏块提前刷盘。这样shutdown immediate时需要做的工作量会小很多。
4. 给shutdown加个超时意识。
如果5分钟还没关掉,不要再傻等了。去看等待事件,判断是在做有用的事还是在空转。
相关阅读:
- 《Oracle数据库无备份强制恢复:SCN不一致、oradebug与ORA-600[2662]》
- 《Oracle Undo回滚段损坏修复:用系统表空间绕过损坏的undo》
- 《Oracle Redo日志损坏恢复:_allow_resetlogs_corruption与open resetlogs》