http://blog.csdn.net/jojo52013145/article/details/7470812

在数据库的开发过程中,经常碰到包、存储过程、函数无法编译或编译时会导致PL/SQL 无法响应的问题。碰到这种问题,基本上都要重启数据库解决,严重浪费开发时间。本文将就产生这种现象的原因和解决方案做基本的介绍。

  • 问题分析

从事数据库开发的都知道锁的概念,如:执行 Update Table xxx Where xxx 的时候就会产生锁。这种常见的锁在Oracle里面被称为DML锁。在Oracle中还有一种DDL锁,主要用来保证存储过程、表结构、视图、包等数据库对象的完整性,这种锁的信息可以在DBA_DDL_LOCKS中查到。注意:V$LOCKED_OBJECT记录的是DML锁信息,DDL锁的信息不在里面。

对应DDL锁的是DDL语句,DDL语句全称数据定义语句(Data Define Language)。用于定义数据的结构或Schema,如:CREATE、ALTER、DROP、TRUNCATE、COMMENT、RENAME。当我们在执行某个存储过程、或者编译它的时候Oracle会自动给这个对象加上DDL锁,同时也会对这个存储过程所引用的对象加锁。

了解了以上知识以后,我们可以得出结论:编译包长时间无响应说明产生了死锁。我们可以轻易的让这种死锁发生,举例:

1、     打开一个PL/SQL,开始调试某个函数(假设为:FUN_CORE_SERVICECALL),并保持在调试状态

2、     打开一个SQL Window,输入Select *From dba_ddl_locks aWhere a.name ='FUN_CORE_SERVICECALL'会发现一行记录:

3、     打开一个新的PL/SQL,重新编译这个函数。我们会发现此时已经无法响应了

4、     回到第一个PL/SQL ,重新执行Select *From dba_ddl_locks aWhere a.name ='FUN_CORE_SERVICECALL'我们将会看到如下记录:

5、     上述的情况表明发生了锁等待的情况。

在Oracle中DDL锁分为:Exclusive DDL Locks(排他的DDL)、Share DDL Locks(共享DDL锁)、Breakable Parse Locks(可被打破的解析锁)几类。篇幅所限,这里就不再详细介绍了。根据这个例子推理一下,当我们试图编译、修改存储过程、函数、包等对数据对象的时候,如果别人也正在编译或修改他们时就会产生锁等待;或者我们在编译某个存储过程的时候,如果它所引用的数据库对象正在被修改应该也会产生锁等待。这种假设有兴趣的兄弟可以测试下,不过比较困难。

  • 解决方案

碰到这种问题,如果知道是被谁锁定了(可以查出来的),可以让对方尽快把锁释放掉;实在查不出来只能手工将这个锁杀掉了。步骤如下:

1、     首先查出哪些进程锁住了这个对象,语句如下:

Select b.SID,b.SERIAL#

From dba_ddl_locks a, v$session b

Where a.session_id= b.SID

And a.name ='FUN_CORE_SERVICECALL';

2、     执行如下语句杀进程:alter system kill session 'sid,serial#'

3、     执行了以上的语句后,有的时候不一定能够将进程杀掉。这个时候就需要连到数据库服务器上杀掉服务器端的进程了,查询语句:

Select spid, osuser, s.program

From v$session s, v$process p

Where s.paddr= p.addr

And s.sid =(上面查出来的SID)

4、     在服务器上执行如下语句:

#kill -9 spid(UNIX平台)

orakill sid thread(Windows平台SID是Oracle的实例名,thread是上面查出来的SID)

5、     执行完4步以后基本上就可以杀掉这些锁死的进程了,不放心的话可以再执行第一步确认下。

本文只能是说对这个问题做了初步分析,产生此问题的原因及解决方案涉及到很多Oracle的基本知识。如:DML语句,DDL语句;Oracle锁的机制;v$session 与 v$process之间关系等。有兴趣的兄弟可以更加深入的研究,欢迎跟我交流!

死锁是数据库经常发生的问题,数据库一般不会无缘无故产生死锁,死锁通常都是由于我们应用程序的设计本身造成的。产生死锁时,如何解决呢,下面是常规的解决办法:

1)执行下面SQL,先查看哪些表被锁住了: 
select b.owner,b.object_name,a.session_id,a.locked_mode
from v$locked_object a,dba_objects b
where b.object_id = a.object_id;

2)查处引起死锁的会话
select b.username,b.sid,b.serial#,logon_time 
from v$locked_object a,v$session b
where a.session_id = b.sid order by b.logon_time;
这里会列出SID

3) 查出SID和SERIAL#: 
查V$SESSION视图: 
SELECT SID,SERIAL#,PADDR FROM V$SESSION WHERE SID='刚才查到的SID'; 
这一步将得到PADDR

4)查V$PROCESS视图: 
SELECT SPID FROM V$PROCESS WHERE ADDR='刚才查到的PADDR'; 
这一步得到SPID

5)杀死进程 
(1)在数据库中,杀掉ORACLE进程: 
ALTER SYSTEM KILL SESSION '查出的SID,查出的SERIAL#';

执行存储过程更新一个表中的数据的时候产生如下的错误:

SQL> exec update_jc_kxx_yxrq;

begin update_jc_kxx_yxrq; end;

ORA-20998: Err=-2049,Msg=0-ORA-02049: 超时: 分布式事务处理等待锁定
ORA-06512: 在"ICUSER.UPDATE_JC_KXX_YXRQ", line 36
ORA-06512: 在line 2

以sys用户登陆数据库查询死锁

SQL> select username,lockwait,status,machine,program from v$session where sid in
(select session_id from v$locked_object);

USERNAME LOCKWAIT STATUS
------------------------------ ---------------- --------
MACHINE
----------------------------------------------------------------
PROGRAM
------------------------------------------------
icdb
JDBC Thin Client

ICUSER 000000038A37C0C8 ACTIVE
icdb
JDBC Thin Client

说明数据库有死锁

然后使用一下语句查找被死锁的语句

SQL> select sql_text from v$sql where hash_value in
(select sql_hash_value from v$session where sid in
(select session_id from v$locked_object));

SQL_TEXT
--------------------------------------------------------------------------------
update JC_KXX SET LJXF =NVL ( LJXF , 0 ) + :1 , YE =:2 WHERE KH =:3
update jc_kxx set zt='07' where kh='1000530330'

再使用以下语句查找被死锁的进程

SQL> SELECT s.username,l.OBJECT_ID,l.SESSION_ID,s.SERIAL#,
l.ORACLE_USERNAME,l.OS_USER_NAME,l.PROCESS
FROM V$LOCKED_OBJECT l,V$SESSION S WHERE l.SESSION_ID=S.SID;

USERNAME OBJECT_ID SESSION_ID SERIAL#
------------------------------ ---------- ---------- ----------
ORACLE_USERNAME OS_USER_NAME PROCESS
------------------------------ ------------------------------ ------------
ICUSER 30523 32 42463
ICUSER oracle

ICUSER 30523 28 25508
ICUSER oracle

ICUSER 30523 76 14781
ICUSER oracle

USERNAME OBJECT_ID SESSION_ID SERIAL#
------------------------------ ---------- ---------- ----------
ORACLE_USERNAME OS_USER_NAME PROCESS
------------------------------ ------------------------------ ------------
ICUSER 30523 24 37522
ICUSER oracle

使用一下语句把死锁的进程kill

alter system kill session ‘sid,serial#’; (其中sid=l.session_id)

如:SQL> alter system kill session '24,37522';

再次执行存储过程,错误没有了。语句执行成功!

Oracle包被锁定的原因分析及解决方案

Oracle包被锁定的原因分析及解决方案的更多相关文章

  1. SQL查询速度慢的原因分析和解决方案

    SQL查询速度慢的原因分析和解决方案 查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建 ...

  2. CMMI5级——原因分析及解决方案(Causal Analysis and Resolution)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010825142/article/details/15338085 聪明的人在出现问题的时候,除了 ...

  3. IP访问频率限制不能用数组循环插入多个限制条件原因分析及解决方案

    14.IP频率限制不能用数组循环插入多个限制条件原因分析及解决方案: define("RATE_LIMITING_ARR", array('3' => 3, '6' => ...

  4. hive on spark:return code 30041 Failed to create Spark client for Spark session原因分析及解决方案探寻

    最近在Hive中使用Spark引擎进行执行时(set hive.execution.engine=spark),经常遇到return code 30041的报错,为了深入探究其原因,阅读了官方issu ...

  5. 在Android library中不能使用switch-case语句访问资源ID的原因分析及解决方案

    转自:http://www.jianshu.com/p/89687f618837 原因分析   当我们在Android依赖库中使用switch-case语句访问资源ID时会报如下图所示的错误,报的错误 ...

  6. Beforeunload打点丢失原因分析及解决方案

    淘宝的鱼相在 2012 年 8 月份发表了一篇文章,里面讲述了他们通过一个月的数据采集试验,得到的结果是:如果在浏览器的本页面刷新之前发送打点请求,各浏览器都有不同程度的点击丢失情况,具体点击丢失率统 ...

  7. window.open浏览器弹出新窗口被拦截—原因分析和解决方案

    最近在做项目的时候碰到了使用window.open被浏览器拦截的情况,在本机实验没问题,到了服务器就被拦截了,火狐有拦截提示,360浏览器拦截提示都没有,虽然在自己的环境可以对页面进行放行,但是对用户 ...

  8. 关于JVM内存溢出的原因分析及解决方案探讨

    前言:JVM中除了程序计数器,其他的区域都有可能会发生内存溢出. 0.什么是内存溢出 当程序需要申请内存的时候,由于没有足够的内存,此时就会抛出OutOfMemoryError,这就是内存溢出. 1. ...

  9. 本机未装Oracle数据库时Navicat for Oracle 报错:Cannot create oci environment 原因分析及解决方案

    因为要更新数据库加个表,远程桌面又无法连接...所以就远程到另外一台电脑,然后用navicat通过内网修改目标数据库. 一直用着navicat操作数据库,所以很速度的弄好然后新建连接进入数据库. 然而 ...

随机推荐

  1. 20172306《Java程序设计》第五周学习总结

    20172306 2016-2017-2 <Java程序设计>第五周学习总结 教材学习内容总结 第五章主要学习了if以及while的语句的运用 运算符:== 代表相等,是两个之间的内存地址 ...

  2. win8+iis8+PHP5安装配置和Zend Optimizer安装教程

    安装 Zend Optimizer       下载地址:http://www.onlinedown.net/soft/32228.htm 下载直接双击安装即可,安装过程要你选择 Web Server ...

  3. 第二周java学习收获

    JAVA学习第二周总结 教材学习内容总结 第二章:讲了标识符与关键字,以及基本数据类型:逻辑类型.整数类型.字符类型.浮点类型. 输入输出,System.in,System.out和数组. 第三章:运 ...

  4. HTML 学习杂记

    代码范例 <?php function testFunc1 () { echo 'testFunc1'; } $b = ; ?> <!DOCTYPE html PUBLIC &quo ...

  5. (xxx.55).toFixed(1) 无法正确进位处理

    参考:https://juejin.im/post/5a11a9fef265da43284073b4?utm_medium=fe&utm_source=weixinqun 根本原因在于2.55 ...

  6. GameObject.SendMessage

    Message相关有3条指令:    要接收消息的GameObject.SendMessage ("函数名",参数,SendMessageOptions)  //自身和父Objec ...

  7. html-day04

    html-day04 1.html属性的弊端 1.完成相同的功能需要不同的属性支持 2.可维护性不高2.CSS 1.什么是CSS Cascading Style Sheet 层叠样式表.级联样式表.样 ...

  8. Codeforces gym 102062 简要题解

    文章目录 A. Bob and BoB B. Vibranium Gift C. The Blood Moon D. Palindrome and Chocolate E. Jumpy Robot F ...

  9. Codeforces Round #538 (Div. 2) E 随机数生成

    https://codeforces.com/contest/1114/problem/E 题意 交互题,需要去猜一个乱序的等差数列的首项和公差,你能问两种问题 1. 数列中有没有数比x大 2. 数列 ...

  10. OSI七层模型和TCP/IP四层模型

    1)网络层负责点到点的传输(这里的“点”指主机或路由器),而传输层负责端到端的传输(这里的“端”指应用进程) 2)ARP协议介于数据链路层和网络层之间(IPv4专有,IPv6的地址映射功能在ICMPv ...