为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Java

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

简述


16-7月,一大型在线业务系统服务器突然一个个挂掉,重启后不到撑不到五分钟就牺牲,导致生产系统业务故障https://img1.sycdn.imooc.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
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消