kill等待session的方法 - 引申自恩墨面试题的一些思考

Kamus曾在微信公众号发表了一篇文章《删繁就简 - 云和恩墨的一道面试题解析》,恩墨的新书《Oracle性能优化与诊断案例精选》第五章引用了相同的文章,来自恩墨的一道面试题,乍一看其中涉及的知识点,大部分比较眼熟,但开始解决的时候,能否清晰地完成,就因人而异了。

从我的认识来看,对于日常的工作,有一些值得总结和借鉴的,因此写出来分享一下,欢迎各位提出其他的建议,共同完善。

一、原文描述

题目是:请将 emp.empno=7369 的记录 ename 字段修改为“ENMOTECH”并提交,你可能会遇到各种故障,请尝试解决。

其实题目的设计非常简单,一个 RAC 双节点的实例环境,面试人员使用的是实例2,而我们在实例1中使用 select for update 将 EMP 表加锁:
SQL> SELECT * FROM emp FOR UPDATE;
此时在实例2中,如果执行以下 SQL 语句尝试更新 ename 字段,必然会被行锁堵塞:
SQL> UPDATE emp SET ename='ENMOTECH' WHERE empno=7369;

这道面试题中包含的知识点有:
如何在另外一个 session 中查找被堵塞的 session 信息;
如何找到产生行锁的 blocker;
在杀掉 blocker 进程之前会不会向面试监考人员询问,我已经找到了产生堵塞的会话,是不是可以kill掉;
在获得可以 kill 掉进程的确认回复后,正确杀掉另一个实例上的进程。

这道题我们期待可以在5分钟之内获得解决,实际上大部分应试者在15分钟以后都完全没有头绪。

创建测试表,

session 1执行更新empno=7902行记录的SQL语句,

此时session 2执行相同的SQL语句,由于session 1更新的事务未提交,因此行锁未释放,session 2处于hang,

根据v$session和v$sql,检索包含'update bisal_emp'的语句正等待什么,

得知session id是35,用户名为BISAL,update bisal_emp这条SQL语句,正等待行锁争用的事件,等待的是TX锁。

检索gv$session,了解35号session被什么session阻碍,由于原文使用的是RAC,因此使用了gv$session且inst_id不同,我这实验用的是单实例,因此虽然可以使用gv$session视图,但inst_id默认为1,

得知35号session等待的是54号session。

根据sid信息,检索其serial#,使用alter system kill session 'sid, serial#'来kill阻碍的session,

此时session 1执行任何SQL,会提示ORA-00028,需要重新登录。

session 2则会提示SQL执行完成,说明session 2已经有了该行的TX锁,

以上是原文整体的实验,略有出入,基本保持一致。

二、引申-检索等待的对象

原文中已知了具体SQL有等待,要是不知道具体SQL,只是说明有一个session执行SQL处于hang,是否可以知道等待的是什么?

当然可以,v$locked_object中存储了等待的对象信息,

进一步我们可以根据v$locked_object和dba_objects,了解等待的对象是什么,

三、引申-一键解决等待

原文Kamus总结了一句,

忽然感觉网上那些一气呵成的故障诊断脚本其实挺误人的,只需要给一个参数,运行一下脚本就列出故障原因。所以很少人愿意再去研究这个脚本为什么这么写,各个视图之间的联系是如何环环相扣的。所以当你不再使用自己的笔记本,不再能迅速找到你赖以生存的那些脚本,你还能一步一步地解决故障吗?

说的很有道理,工具有时候简化了我们的工作,但往往屏蔽了技术细节,如果不了解背后的原理,我们只是工具的使用者,机械的执行,但若了解了背后的原理,不用工具,我们同样可以处理问题,或者改进工具,更适合我们的实际需求。

根据上面的实验,其实我们可以将过程封装,一键解决SQL等待的问题,如下是脚本,其实比较唬人,仔细看一下,和上面实验中用到的SQL基本一致,略有调整。

脚本首先执行set serveroutput on打开存储过程输出控制。

接着提示'SQL TEXT',接受SQL语句的部分字符串为输入。

第一条SQL,根据输入的SQL_TEXT,得到包含SQL_TEXT的SQL等待什么,注意由于SQL_TEXT是模糊匹配,这需要使用sid<>的方式来屏蔽执行本脚本的session,得到的SQL就是需要的语句。

第二条SQL则找出阻碍session的信息。

第三条SQL根据前面两条SQL的信息,拼接出alter system kill session 'sid, serial#'语句。

直接copy执行这条SQL,就可以完成阻碍进程的kill,完成需求。

如下是执行脚本的输出,

脚本原文可以从我的GitHub上下载,

https://github.com/bisal-liu/oracle/blob/master/lock.sql

总结:

1. 看似简单的问题,要有清晰的思路,才能完美的解决,这需要具备扎实的基本功,以及沉着冷静的心态。

2. 了解工具背后的原理,有助于我们理解问题的解决思路,不是被动地使用工具,才能真正驾驭这些工具,为我们所用。

如果您觉得此篇文章对您有帮助,欢迎关注微信公众号:bisal的个人杂货铺,您的支持是对我最大的鼓励!共同学习,共同进步:)

时间: 2024-07-30 10:59:41

kill等待session的方法 - 引申自恩墨面试题的一些思考的相关文章

PHP实现利用MySQL保存session的方法_php技巧

session是PHP程序设计中服务器端用来保存用户信息的一个变量,具有非常广泛的应用价值.本文实例讲述了PHP实现利用MySQL保存session的方法.分享给大家供大家参考之用.具体步骤如下: 本文实例的实现环境为: PHP 5.4.24 MySQL 5.6.19 OS X 10.9.4/Apache 2.2.26 一.代码部分 1.SQL语句: CREATE TABLE `session` ( `skey` char(32) CHARACTER SET ascii NOT NULL, `d

使用无限生命期Session的方法(转)

session 使用无限生命期Session的方法 本文不敢说非常好,但是笔者相信大多数PHPer都曾经想过这些问题. 使用无限生命期Session的方法 在PHP4.0中加入了对Session的支持,方便了我们很多程序,比如购物车等等! 在很多论坛中,Session也用于处理用户的登陆,记录下用户名和密码,使得用户不必每次都输入自己的用户名和密码!但是一般的Session的生命期有限,如果用户关闭了浏览器,就不能保存Session的变量了!那么怎么样可以实现Session的永久生命期呢? 大家

asp.net网站防恶意刷新的Cookies与Session解决方法

 本文实例讲述了asp.net网站防恶意刷新的Cookies与Session解决方法,是WEB程序设计中非常实用的技巧.分享给大家供大家参考.具体实现方法如下: Session版实现方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public double time; public const in

web.py在SAE中的Session问题解决方法

  这篇文章主要介绍了web.py在SAE中的Session问题解决方法(使用mysql存储),本文直接给出实现代码,代码中包含详细注释,需要的朋友可以参考下 这段时间一直想尝试着在SAE中使用Python,初步选择了Web.py框架做为开发框架,但是可怜SAE上的资料少的可怜,有点问题基本上解决不了,今天解决一个Session在Session的存储问题,在SAE中不能直接用本地文件存储,好像是权限的原因,我现在采用的是保存在mysql中,效果也不错.希望对大家有帮助.直接上代码了. index

php清除和销毁session的方法分析

 这篇文章主要介绍了php清除和销毁session的方法,实例分析了unset()与session_destroy()清除及销毁session的技巧,需要的朋友可以参考下     本文实例分析了php清除和销毁session的方法.分享给大家供大家参考.具体分析如下: 下面的代码分别用户删除单个session值和全部session unset() 用于释放一个已经存在的session值.可以使用 session_destroy() 函数销毁全部session. ? 1 2 3 <?php uns

php保存信息到当前Session的方法

 这篇文章主要介绍了php保存信息到当前Session的方法,实例分析了php中session的使用技巧,需要的朋友可以参考下     本文实例讲述了php保存信息到当前Session的方法.分享给大家供大家参考.具体如下: php中可通过$_SESSION保存session变量,下面的代码简单演示了 $_SESSION的用法 ? 1 2 3 4 5 6 7 8 9 10 11 <?php session_start(); print("<html><b>"

php禁用cookie后session设置方法分析_php技巧

本文实例讲述了php禁用cookie后session设置方法.分享给大家供大家参考,具体如下: 我们都知道当在session 会话有基于cookie和基于url两种传递SESSIONID的方法.为了实现客户端禁止cookie发送的情况也不影响客户登陆网站,可以设置 php.ini中 session.use_trans_sid=1 ,表示当客户端浏览器禁止cookie的时候,页面上的链接会基于url传递SESSIONID.但是很多人仅仅设置了这一个选项并没有达到效果,本人也 遇到此问题,后来一番研

hibernate系列(五)Session接口方法

Session接口方法主要有save.persist.load.get.update.saveOrUpdat.merge.delete等,这里主要是对我看hibernate书籍的一个实践加总结.  首先是save()方法:  以之前的Customer和Order为例,看下类文件:  ? 1 2 3 4 5 6 7 8 9 public class Customer {       private Long id;     private String name;     private Stri

Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法_php技巧

本文实例讲述了Ubuntu server 11.04安装memcache及php使用memcache来存储session的方法.分享给大家供大家参考,具体如下: 1.首先安装memcache服务端: sudo apt-get install memcached 安装完成后系统 自动启动了 memcached服务占用11211端口 如需重新配置11211端口的服务 需要关闭已开启的memcached服务 手动启动: memcached -d -m 128 -p 11211 -u memcache