1、原因分析:出现这种卡顿的情况,一般是由于阻塞造成的,找到阻塞的源头的事务,提交或者回滚。可以参考下面几项步骤:
2、 通过下面语句查询有没有阻塞 select * from v$lock where blocked = 1; 存在结果集,则表示存在被阻塞的事务。
3、 然后,可以通过上面结果中的 table_id 看是哪个事务导致的阻塞select * from v$lock where table_id = 2493 ::
4、一般涉及到两个事务的多行结果 其中 blocked = 1 的表示,这是个被阻塞的事务,就是我们执行时间很长的sql 对刂茗岚羟应的事务; 其中 blocked = 0 的表示,这是导致上述事务被阻塞的事务,可能是一个正在执行的事务,或者是已经执行完但是没有提交(和被阻塞事务处理到同一条数据了) (是正在执行,还是执行完没有提交,可以通过 v$session 进行判断)
5、 接下面,通过 2 中获取到的 trx_id ,可以在 v$session 中间 获取到 session 的相关信息,进行相关判断:status = RUNNING 表示 正在执行 —— 可能是这个 sql 执行效率太差,执行时间太久了。 status = IDEL 表示 已经执行完 —— 可能是谁处理了数据,忘记提交了;或者是应用的处理逻辑有欠妥当的地方。
6、找到阻塞的源头事物,我们就可以旅邯佤践进行处理了,可以选择:继续等待(比如,如果是重要业务的执行语句,不应该处理,等它执行完后,统潇瘵侃就会提交 —— 那在它执行完 提交后,就不会阻塞我们了)或者找到 manager 窗口,点提交 或者回滚 (有时候,是我们自己 或者 他人 处理了数据,“忘记”提交或者回滚导致的)或者通过 sp_close_session(id) 给对应的 session 关闭消息(也就是 我们俗称的 “杀掉会话”)
7、因为有时候是应用异常导致的,我们“等”不到 它结束,而且也不方面处理应用,那么我们就可以在数据库上,通过数据库数据库提供的函数接口,如此处理。
8、但是要知道,这个进度并不一定能够杀掉(大部分时候能杀掉)。因为有时候,这个只是葛激握颟发送一个关闭消息, 如磨营稼刻果这个 session 上的和这个 sql 在等待其他的 “资源”时, 无法处理发给它的消息,那么它就不会立即被关闭。这个时候,就只能选择等等,或者 (紧急的话)重启数据库 (等 这个 处理 sql 的线程 处理 发给他的 ”关闭消息“的时候,就能够 ”杀掉“ 这个会话了。)