包编译卡住的终极解决办法
来源:互联网 发布:一键截图软件 编辑:程序博客网 时间:2024/05/16 11:18
在数据库开发过程中,经常遇到一个很烦躁的现象:刚修改好的包一编译就卡死了,PL/SQL变成一片空白,又不忍心关闭,这可是耗死多少脑细胞才写出来的!!!只好去求DBA帮忙解决,可是人家也不是每次都会耐心帮你解决,结果经常碰一鼻子灰,所以了,求人不如求己,下面就让我们自己学会去解决这个烦人的问题。。
首先我们先了解下与这种卡死现象相关的几个视图:
1)v$access
V$ACCESS
displays information about locks that are currently imposed on library cache objects. The locks are imposed to ensure that they are not aged out of the library cache while they are required for SQL execution.
v$access里存放的是数据字典缓存中的对象,包括表,包,游标等(库缓存缓存的是最近执行的代码),所以你当前编译的包是可以查到的,执行完毕后一般就会v$access中消失。不过有种情况要注意下,如果一个session执行了包A后就停下来了(session对应的状态为INACTIVE),执行完毕后,session与包A可能还是存在于v$access中,直到这个session再次执行另外的sql,这种情况是不会影响你包的编译。所以当你看到v$access中有你要编译的包,不要惊慌,它不一定是凶手,去v$session中确认下状态再做判断。
2)DBA_DDL_LOCKS
DBA_DDL_LOCKS
lists all DDL locks held in the database and all outstanding requests for a DDL lock.
当你编译包时,oracle就会对这个包加个DDL锁,同时也会这个包所引用的对象加DDL锁(与DDL锁对应的是DML锁,记录在V$locked_object里,sql语句执行完毕后,DML锁不会消失,必须commit或rollback)
下面我们做几个实验来验证上面的理论(其实上面也是我从别处看到的,对不对还得自己去验证)
1. 用PL/SQL随便调试个sp,让它停在调试状态;
2. 看看在两个视图中的情况:
--注意这里用了/*+rule*/可以解决查询 v$access慢的情况
SQL> SELECT/*+rule*/ * FROM v$access t WHERE t.OWNER='ORACLE' AND OBJECT='TEST_FOR_DDL';
151 ORACLE TEST_FOR_DDL PROCEDURE
SQL> SELECT * FROM dba_ddl_locks t WHERE t.owner='ORACLE' AND NAME='TEST_FOR_DDL';
151 ORACLE TEST_FOR_DDL Table/Procedure/Type Null None
3.再开一个窗口,编译TEST_FOR_DDL,开始卡死;
4.再查两个视图中的情况:发现v$access中显示的认识持有DDL锁的session,而dba_ddl_locks显示了持有锁和请求锁的session
SQL> SELECT/*+rule*/ * FROM v$access t WHERE t.OWNER='ORACLE' AND OBJECT='TEST_FOR_DDL';
151 ORACLE TEST_FOR_DDL PROCEDURE
SQL> SELECT * FROM dba_ddl_locks t WHERE t.owner='ORACLE' AND NAME='TEST_FOR_DDL';
151 ORACLE TEST_FOR_DDL Table/Procedure/Type Null None
158 ORACLE TEST_FOR_DDL Table/Procedure/Type Exclusive None --排他锁
5.让调试的session跑完,再来看。编译卡死的session死而复生
--v$access记录没了
SQL> SELECT/*+rule*/ * FROM v$access t WHERE t.OWNER='ORACLE' AND OBJECT='TEST_FOR_DDL';
no rows selected
--只剩调试的session,此时仍可以正常编译sp
SQL> SELECT * FROM dba_ddl_locks t WHEREt.owner='ORACLE' AND NAME='TEST_FOR_DDL';
151 ORACLE TEST_FOR_DDL Table/Procedure/Type Null None
通过上面的实验,我们可以得出这样的结论:v$access,dba_ddl_locks 中有你要编译的对象,都不能说明会影响你的编译。对于v$access,你要确认其对应的session是否ACTIVE,对于dba_ddl_locks,你要确认其对应的锁类型是否为Exclusive。这样就可以准确找到卡死你编译的真凶。。
找到卡死你真凶的sid后,下面就开始准备干掉它:
1. 找出其对应的serial#:
SQL> SELECT SID,SERIAL# FROM v$session WHERE SID IN (150);
150 20
2. 杀掉:
SQL> alter system kill session'150,20';
System altered.
3. 杀掉后一切恢复正常,编译卡住的sp也编译过去了
SQL> SELECT SID,SERIAL#,status FROM v$session WHERE SID IN (150);
no rows selected
不过我这是很幸运的情况,很多时候你kill会话后,PMON并不能及时清除该会话的资源,在V$session中的状态是KILLED,还是会卡住你要编译的包。要是你是开发人员的话,只能求助DBA帮你把session对应的操作系统线程杀掉(因为开发人员通常是没有对操作系统进行操作的权限),不过我们还是应该了解DBA是怎么操作的,其实很简单的:
1. 找出进程地址
SELECT PADDR FROM v$session WHERE SID IN (147);
2. 找操作系统对应的SPID
SELECT spid FROM V$process WHERE addr='30E1C924'
3.在操作系统杀
linux: kill pid
windows: orakill sid spid
这下就肯定没人阻止你编译了,不过小心要是你把别人正在用的session杀掉了,小心挨揍
- 包编译卡住的终极解决办法
- maven卡住的解决办法
- myeclipse 启动卡住的解决办法
- 已导入jar包,但是总包类找不到的终极解决办法
- Delphi 的DFM文件乱码无法编译的终极解决办法
- xcode编译的时候卡住
- VS2010安装到 "VsaEnv_Setup_x86_chs" 卡住的解决办法
- VS2010安装到 "VsaEnv_Setup_x86_chs" 卡住的解决办法
- ubuntu死机 卡住时的解决办法
- 关于cocoaPods pod update 卡住的解决办法
- 命令行创建maven项目卡住的解决办法
- 独立显卡笔记本 VMware 安装 ubuntu开机启动后卡住不动黑屏 终极解决办法
- IE问题的终极解决办法
- 电脑屏幕黑屏的终极解决办法
- eclipse在启动的时候卡住很久的解决办法
- 桌面右键就系统变慢,卡住的解决办法!!!
- 安装centos7系统装不上,进度条卡住问题的解决办法。
- eclipse中tomcat启动卡住的原因和解决办法
- b2evlution构建的博客太可怕,每次登陆信息都要记录数据库
- hibernate-3.2.5各个包的作用
- 如何卸载kb2670838补丁
- 学习Linux的几点忠告(转贴)
- 将SQL Server 2005中的数据导出为Excel
- 包编译卡住的终极解决办法
- android通过HTTP协议上传文件至远程服务器
- [WIKIOI 1316]文化之旅(队列深度优先搜索)
- ZOJ 1905 Power Strings
- 软件开发基础知识
- TCP保活
- windows核心编程-获取系统中进程的信息
- 最长公共子序列
- 《弟子规》