`
13594135
  • 浏览: 190512 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

数据库表被锁死

阅读更多
  3月3日下午,系统发生了严重故障,后台程序大量抛出如下异常:
DBCP object created 2011-03-03 12:35:19 by the following code was never closed:
java.lang.Exception
        at org.apache.commons.dbcp.AbandonedTrace.setStackTrace(AbandonedTrace.java:157)
        at org.apache.commons.dbcp.AbandonedObjectPool.borrowObject(AbandonedObjectPool.java:76)
        at org.apache.commons.dbcp.PoolingDataSource.getConnection(PoolingDataSource.java:95)
        at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:540)
        at org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider.getConnection(LocalDataSourceConnectionProvider.java
:82)
        at org.hibernate.jdbc.ConnectionManager.openConnection(ConnectionManager.java:423)
        at org.hibernate.jdbc.ConnectionManager.getConnection(ConnectionManager.java:144)
        at org.hibernate.jdbc.JDBCContext.connection(JDBCContext.java:119)
        at org.hibernate.transaction.JDBCTransaction.begin(JDBCTransaction.java:57)
        at org.hibernate.impl.SessionImpl.beginTransaction(SessionImpl.java:1326)
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:509)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionMana
ger.java:377)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary(TransactionAspectSuppor
t.java:263)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:101)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:50)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:50)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
        at $Proxy44.saveContentSync(Unknown Source)
        at com.wondertek.mobiletv.sync.SyncCMSDataSQLOperate.saveObjectBean(SyncCMSDataSQLOperate.java:1


运维人员初步认定是连接池耗尽引起的,重启系统几次,每次过几分钟之后又出同样问题。通过google,网上提供解决方案如下:
引用
分析:
这是removeAbandoned=true导致的,使用这个配置的时候将会使用AbandonedObjectPool.
而AbandonedObjectPool只在开发阶段使用,因为AbandonedObjectPool能帮你发现占用连接过长的代码.

log信息说明了getCustomerOnline占用连接超过removeAbandonedTimeout设定的时间.所以设置removeAbandoned=false就行了。
AbandonedObjectPool只在开发使用,在后续版本会去掉,现在api都deprecated了


我们参照此方法修改配置文件,重启后还是没有解决问题。运营组那边报过来说模板一直不能保存,也不能给栏目分配模板。我们通过本地运行系统,直接连接生产数据库进行调试,同样不能保存模板。这样得出一个结论系统没有问题,数据库出问题。通过debug,代码里调用下列语句的时候一直过不去。
select body from template_file where tplid=9441 for update

用这个语句在plsql里模拟调用,一直处于等待之中。这样得出结论template_file表被锁了。
用下列语句查行锁定情况,并进行解锁。
select b.owner,b.object_name,l.session_id,l.locked_mode 
from v$locked_object l, dba_objects b 
where  b.object_id=l.object_id and l.LOCKED_MODE > 0 
and (b.OBJECT_NAME = 'NODE_TEMPLATE' or b.OBJECT_NAME = 'CONTENT_TEMPLATE'
 or b.OBJECT_NAME = 'TEMPLATE_FILE')

select t2.sid,t2.serial#
from v$locked_object t1,v$session t2 
where t1.session_id=t2.sid order by t2.logon_time;
--解锁
alter system kill session 'sid,serial' alter system kill session '146,21177';


将所有的锁打开后几分钟后,还是没有改善,又产生很多锁。最后经过一段时间,因为业务量少了,锁自动解开了,系统恢复正常。

事后通过生成awr report查看数据库的健康情况。


可以看出enq: TM - contention等待事件很高。网上说外键约束上没有建立索引引起的问题。
SELECT * FROM (
   SELECT c.table_name, cc.column_name, cc.position column_position
   FROM   user_constraints c, user_cons_columns cc
   WHERE  c.constraint_name = cc.constraint_name
   AND    c.constraint_type = 'R'
   MINUS
   SELECT i.table_name, ic.column_name, ic.column_position
   FROM   user_indexes i, user_ind_columns ic
   WHERE  i.index_name = ic.index_name
   )
ORDER BY table_name, column_position;

同时从awr report上发现了很多执行效率很差的语句,经过了优化,并对调用频率很高的表建立了索引,系统性能得到了很大的提高 。

引用

最近一个客户反映数据库在执行远程INSERT的时候应用反映很慢,在做AWR后发现enq: TM - contention等待事件很高,应该是外键约束上没有建立索引的问题。
下面我来做个实验还原一下当时的现象。

CREATE TABLE supplier
    (     supplier_id     number(10)     not null,
        supplier_name     varchar2(50)     not null,
        contact_name     varchar2(50),   
        CONSTRAINT supplier_pk PRIMARY KEY (supplier_id)
    );

INSERT INTO supplier VALUES (1, 'Supplier 1', 'Contact 1');
INSERT INTO supplier VALUES (2, 'Supplier 2', 'Contact 2');
COMMIT;

CREATE TABLE product
    (     product_id     number(10)     not null,
        product_name    varchar2(50)    not null,
        supplier_id     number(10)     not null,
        CONSTRAINT fk_supplier
          FOREIGN KEY (supplier_id)
         REFERENCES supplier(supplier_id)
         ON DELETE CASCADE
    );

INSERT INTO product VALUES (1, 'Product 1', 1);
INSERT INTO product VALUES (2, 'Product 2', 1);
INSERT INTO product VALUES (3, 'Product 3', 2);
COMMIT;

然后去执行几条相关的语句
User 1: DELETE supplier WHERE supplier_id = 1;
User 2: DELETE supplier WHERE supplier_id = 2;(现象HANG住)
User 3: INSERT INTO supplier VALUES (5, 'Supplier 5', 'Contact 5');(现象HANG住)

现在检查锁的情况

col event format a20
col type format a10
col object_name a15
col object_type a15
SELECT l.sid, s.blocking_session blocker, s.event, l.type, l.lmode, l.request, o.object_name, o.object_type
FROM v$lock l, dba_objects o, v$session s
WHERE UPPER(s.username) = UPPER('&User')
AND   l.id1        = o.object_id (+)
AND   l.sid        = s.sid
ORDER BY sid, type;
输入 user 的值:  test
原值    3: WHERE UPPER(s.username) = UPPER('&User')
新值    3: WHERE UPPER(s.username) = UPPER('test')

       SID    BLOCKER EVENT                TYPE            LMODE    REQUEST
---------- ---------- -------------------- ---------- ---------- ----------
OBJECT_NAME     OBJECT_TYPE
--------------- ---------------
       144        158 enq: TM - contention TM                  3          0
SUPPLIER        TABLE

       144        158 enq: TM - contention TM                  0          2
PRODUCT         TABLE

       153            SQL*Net message from TM                  3          0
                       client
SUPPLIER        TABLE

       SID    BLOCKER EVENT                TYPE            LMODE    REQUEST
---------- ---------- -------------------- ---------- ---------- ----------
OBJECT_NAME     OBJECT_TYPE
--------------- ---------------

       153            SQL*Net message from TM                  3          0
                       client
PRODUCT         TABLE

       153            SQL*Net message from TX                  6          0
                       client



       SID    BLOCKER EVENT                TYPE            LMODE    REQUEST
---------- ---------- -------------------- ---------- ---------- ----------
OBJECT_NAME     OBJECT_TYPE
--------------- ---------------
       158        153 enq: TM - contention TM                  0          5
PRODUCT         TABLE

       158        153 enq: TM - contention TM                  3          0
SUPPLIER        TABLE

已选择7行。

SQL>

能看到enq: TM - contention TM  等待事件

检查没有索引的外键

SELECT * FROM (
   SELECT c.table_name, cc.column_name, cc.position column_position
   FROM   user_constraints c, user_cons_columns cc
   WHERE  c.constraint_name = cc.constraint_name
   AND    c.constraint_type = 'R'
   MINUS
   SELECT i.table_name, ic.column_name, ic.column_position
   FROM   user_indexes i, user_ind_columns ic
   WHERE  i.index_name = ic.index_name
   )
ORDER BY table_name, column_position;
TABLE_NAME
------------------------------
COLUMN_NAME
--------------------------------------------------------------------------------

COLUMN_POSITION
---------------
PRODUCT
SUPPLIER_ID
              1

建立索引后:

CREATE INDEX fk_supplier ON product (supplier_id);

INSERT INTO supplier VALUES (6, 'Supplier 6', 'Contact 6');

INSERT INTO supplier VALUES (7, 'Supplier 7', 'Contact 7');

User 1: DELETE supplier WHERE supplier_id = 6;
User 2: DELETE supplier WHERE supplier_id = 7;
User 3: INSERT INTO supplier VALUES (8, 'Supplier 8', 'Contact 8');

相关的等待事件消失。


awr入门
http://blog.csdn.net/netbios333/archive/2009/06/12/4264114.aspx
分享到:
评论

相关推荐

    SQL数据库中的锁问题

    SQL数据库中的锁问题

    数据库死锁检测工具

    通过这个工具可以检测到数据库中是否存在死锁!

    SQL数据库死锁知识

    SQL Server死锁总结,死锁原理、死锁排查、避免死锁及死锁处理方法,有死锁实例及解决方法

    Oracle锁表处理,Oracle表解锁

    数据库死锁的概念, 所谓死锁,是指两个会话,每个会话都持有另外一个会话想要的资源,因争夺资源而造成...对于锁死的会话,我们可以直接删掉该会话,等事物回滚完成,也可以找出锁死进程的spid,从服务器中删掉该进程。

    sql删除表锁死.txt

    在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上排它锁时,其他的事务不能对它读取和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改...

    在Linux下,MySQL数据库的启动、停止和重启

    Mysql启动、停止、重启常用命令(都是在root背景下)  a、启动方式  1、使用 service 启动:  [root@localhost /]# service mysqld start (5.0版本是mysqld)  [root@szxdb etc]# service mysql start (5.5.7...

    Oracle日常维护故障定位故障排除

    17由于没有COMMIT,导致数据库表被锁住 18索引创建不合理,导致数据库查询特别慢 19 由于BUFFER参数设置不合理导致EXP失败 20由于EXP不向上兼容,语言不兼容,导致不同版本、不同字符集的数据库无法导入 21 由于创建...

    sql数据库死锁查询工具

    数据库死锁,阻塞查询,杀死死锁,阻塞进程

    zabbix进行数据库备份以及表分区的方法

    主要是以前使用的那个备份数据库的脚本是对zabbix数据库进行全备的,使用的又是mysql自带的工具mysqldump,当数据量大了之后进行全备所花的时间比较长,这样将会造成数据库的锁读。。。从而使zabbix服务以为mysql死...

    esale3.85数据库破解

    此软件能够恢复3.85免狗、授权版数据锁死的问题。并且不会损坏数据库,请放心使用。

    ORACLE 如何查询被锁定表及如何解锁释放session

    ORACLE EBS操作某一个FORM界面,或者后台数据库操作某一个表时发现一直出于”假死”状态,可能是该表被某一用户锁定,导致其他用户无法继续操作 代码如下: –锁表查询SQLSELECT object_name, machine, s.sid, s....

    数据库设计约定.pdf

    数据库设计约定 ⼀、公共部分 ⼀、公共部分 1、存储引擎 、存储引擎 默认Innodb,⾮特殊要求⼀律使⽤此引擎 2、字符集 、字符集 Database Server 字符集统⼀默认UTF-8,table和column从server继承 ⼆、表设计约定 ⼆...

    oracle杀死锁,寻PIDKILL进程

    oracle杀死锁 ,在批量导入数据的时候,在数据库中很容易就碰到锁表了,导致长时间数据库卡死,此脚本方便找寻数据库被锁对象,如果在oracle中不能alter kill掉 说明该session已过期需要进入后台去杀掉进程

    oracle 不小心把表数据锁掉,sys查询被锁对象和解锁SQL语句

    一些ORACLE中的进程被杀掉后,状态被置为killed,但是锁定的资源很长时间不释放,有时实在没办法,只好重启数据库。现在提供一种方法解决这种问题,那是在ORACLE中杀不掉的,在OS一级再杀。  1.下面的语句用来查询...

    sql表死锁解决办法

    除了解决 SQL 表死锁问题外,还可以使用其他 SQL 语句来查询当前活动的锁管理器资源信息和数据库进程信息。 1. 查询当前活动的锁管理器资源信息: SELECT resource_type ' 资 源 类 型 ',request_mode ' 请 求 模 ...

    SQL杀死锁.txt

    SQL数据库由于开发过或DEBUG过程中,出现表死锁,此时要找出死锁的表,并杀死,才能解决问题,这个很重要

    sql处理数据库锁的存储过程分享

    查看当前进程,或死锁进程,并能自动杀掉死进程,因为是针对死的,所以如果有死锁进程,只能查看死锁进程,当然,你可以通过参数控制,不管有没有死锁,都只查看死锁进程

    安防网细化_网络细化调试_

    提交命令可以解决锁表,解决sql数据库运行过程中出现锁死

    查看 oracle 死锁程序

    查看 oracle 死锁程序 本程序可轻松查看oracle数据库是否有表锁死

Global site tag (gtag.js) - Google Analytics