继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

简露一手-一次大型业务系统的突发故障-有必要知道一点点Oracle锁故障精简处理。

ibeautiful
关注TA
已关注
手记 343
粉丝 107
获赞 529

复杂的故事简单说,复杂的问题简单做,您好,这里是简露一手,欢迎浏览。

简述


16-7月,一大型在线业务系统服务器突然一个个挂掉,重启后不到撑不到五分钟就牺牲,导致生产系统业务故障https://img2.mukewang.com/5d5e3bdb000193ee07940501.pngoracle锁

定位


因所有应用都有问题,且在未发布版本情况下突然发生,预备进行三个步骤排查定位。

  • 检查数据库情况.

  • 检查服务器日志.

  • 检查服务器网络情况.

数据库情况

这里不说其它的检查项,直奔这次事因:“数据库锁”

根据经验,我们进行了数据库的检查,幸运的是直接找到了问题点。
有一个业务表锁的数量超过100,根据sql_id找出了所有sql,发现了全表锁和锁全表语句,是一条更新全表的update语句。

查询锁:
select object_name as 对象名称,s.sid,s.serial#,p.spid as 系统进程号,s.SQL_ID from v$locked_object l , dba_objects o , v$session s , v$process p where l.object_id=o.object_id and l.session_id=s.sid and s.paddr=p.addr;
查询锁表的语句:
select * from v$sql where sql_id='65gmqgahz6jp8'

处理


锁一旦出现 ,最简单的办思路就是杀[kill]。
kill 分两种:

  • oracle 命令kill
    ALTER SYSTEM KILL SESSION 'sid,serial#';

  • 后台杀oracle语句kill
    kill -9 spid

<small>sid,serial#,spid 取值于 查询锁查询结果。

开始杀

首杀

使用[oracle 命令]kill后 新的锁又多了起来,改用[后台杀]kill后,新的锁仍在继续。

再查

分析锁全部的update语句会话是oracle自己产生的,来源于存储过程的概率比较大,在排查存储过程中找到了它,并根据它找到了一个job,是job的重复执行 导致了全表锁的不断产生。

二杀

删除job后重新kill,第二次杀进程后,情况并没有好转,没有了全表锁,但是行锁仍然多,问题变得更为复杂。

再查

经过漫长的分析百种尝试,最终找到来问题.这是一个大意遗漏的点。生产机器一般做了rac,有多个实例,通过tns连接过去的会话一直在一个实例上,查看锁情况始终只查看了一个实例的锁情况,而oracle的job执行 在两个实例上都有可能存在。修改tns地址为第二个实例后,在第二个实例上找到了好几个全表锁的进程。

三杀

登陆到第二个实例上,kill掉锁的进程后1分钟不到,所有的锁都降下去了,重启应用,恢复正常。

总结

事情错综,所以总结一下为两点来将整体内容再简化一下。

  • 因: 生产业务表在业务繁忙期间执行了全表更新语句,与应用上更新单条记录的进程形成循环锁、阻塞,导致整体应用和数据库问题。所以,生产业务表在业务繁忙期间应禁止执行全表更新语句。碰到必须在业务期间全表执行则需采用分批更新和提交,来减小冲突的产生概率,这里说的全表更新包括更新语句没有where条件和where条件的结果有大量数据的两种情况。

  • 果: 找出所有锁,杀掉所有锁。需要注意的是:Job会不停产生更新任务。生产环境一般都做了rac,需检查数据库的多个实例,都进行kill。

实际上这次事故处理时间有点长,中间停起应用、分析日志这些都有做,还有迁移接口、排查代码这些,处理的内容也相当多。回想起来做的事情就一项是有用的:找到所有锁,然后kill



作者:georgekaren
链接:https://www.jianshu.com/p/f84a6b7ef195
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP