`
13594135
  • 浏览: 193104 次
  • 性别: 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
分享到:
评论

相关推荐

    表是否被锁住

    在Oracle数据库管理中,了解如何查询表是否被锁定以及如何执行解锁操作是至关重要的技能,尤其是在处理并发事务、性能调优或解决死锁问题时。本文将深入探讨Oracle中的表锁机制,包括如何识别锁定的表,理解不同类型...

    SQL数据库中的锁问题

    SQL数据库中的锁问题

    oracle数据库锁表处理

    ### Oracle数据库锁表处理 在Oracle数据库管理过程中,锁表是一种常见的现象,它通常发生在多用户并发访问同一数据对象时。锁表会导致其他用户无法访问该数据对象,从而影响系统的正常运行。本文将详细介绍如何处理...

    oracle数据库锁使用

    Oracle 数据库锁是确保数据完整性、一致性以及并发操作的关键机制。在Oracle中,锁主要分为两类:数据锁(DML锁)和字典锁。字典锁主要用于内部管理,特别是语法分析和DDL操作,用户无法直接控制。而数据锁则是我们...

    编程或数据库表及字段命名可以用到各种英文缩写

    ABS是一种汽车制动系统,用于防止车辆在紧急制动时轮胎锁死,从而保持车辆的方向控制能力。在编程或数据库设计中,如果涉及到汽车安全系统或相关功能模块的命名,可以考虑使用“ABS”。 ### 2. B2B - Business to ...

    数据库锁表问题解决方法

    ### 数据库锁表问题解决方法 #### 一、问题背景 在进行数据库操作时,比如对数据表进行插入(INSERT)、更新(UPDATE)或删除(DELETE)操作,或者是添加主键(PRIMARY KEY)或索引(INDEX)时,可能会遇到ORA-...

    通过数据库给文件加锁

    数据库锁是数据库管理系统(DBMS)用于控制对数据的并发访问的一种机制。它们可以防止两个事务同时修改同一数据,从而避免数据不一致。锁有多种类型,包括共享锁(读锁)、排他锁(写锁)、行级锁、表级锁等,可以...

    数据库死锁检测工具

    同时,DBA还可以通过调整事务隔离级别、合理设计锁粒度、避免长时间持有锁等方式预防死锁。 总的来说,"数据库死锁检测工具"对于数据库管理至关重要,它能帮助我们及时发现和解决死锁问题,提高数据库的并发性能和...

    oracle中判断表是否被锁

    ### Oracle中判断表是否被锁及解锁方法 在Oracle数据库管理过程中,经常会出现表或行被锁定的情况,这可能会导致应用程序出现性能问题甚至挂起。因此,了解如何判断表是否被锁以及如何解锁是非常重要的技能。 ####...

    oracle锁表及解锁

    ### Oracle锁表与解锁详解 在Oracle数据库管理中,锁是一种关键机制,用于控制多个用户对数据资源的并发访问,防止数据冲突和不一致。本文将深入探讨Oracle中检查锁表的方法以及如何对表进行解锁。 #### Oracle锁...

    查看Oracle锁表

    如果发现某个表被错误地锁定了,可以通过以下命令来解锁: ```sql -- 示例解锁命令 ALTER SYSTEM KILL SESSION '68,10026'; ``` 其中: - **68**:会话SID。 - **10026**:会话序列号。 需要注意的是,在执行解锁...

    MYSQL锁表问题的解决方法

    MySQL数据库在处理并发事务时,可能会出现锁表的问题,这通常发生在多个事务同时访问和修改同一数据时。当一个事务尚未完成,其他事务无法进行相关操作,就会导致锁表现象,影响数据库性能和应用的正常运行。本文将...

    mysql数据库锁的产生原因及解决办法

    2. **不可升级的锁死锁**:事务A持有共享锁,尝试升级为排他锁,但事务B已持有排他锁,反之亦然,导致死锁。 解决死锁通常需要通过预防、检测和恢复策略。预防死锁是通过设置事务执行的顺序规则,例如统一表操作...

    数据库通用操作命令

    在创建表空间之前,确保已经通过正确的身份验证登录到了Oracle数据库。这通常涉及使用`sqlplus`工具并指定以`sysdba`模式登录。 1. **打开CMD窗口** 打开Windows的命令提示符窗口(CMD),可以通过搜索栏输入...

    orcale查看锁表与解表语句

    "orcale查看锁表与解表语句"这个主题主要涉及到如何检查Oracle数据库中的锁情况以及如何解除可能存在的死锁。以下是一些关键知识点的详细解释: 1. **`v$lock`表**:这是Oracle提供的一张动态性能视图,用于显示...

    杀死正在使用数据库的线程

    "杀死正在使用数据库的线程"是一个关键的操作,用于恢复数据库的正常运行和服务性能。本文将深入探讨这个主题,讲解如何在不同的数据库系统中进行线程的管理和终止。 1. **MySQL中的线程管理** 在MySQL中,可以...

    oracle查看被锁的表和解锁

    在Oracle数据库管理及开发过程中,有时会遇到表被锁的问题,这种情况可能会导致应用程序出现性能瓶颈甚至完全无法执行某些操作。因此,掌握如何查看哪些表被锁以及如何解锁变得尤为重要。下面将详细介绍相关的查询...

    oracle锁表解决

    当一个表被锁定时,其他用户或进程可能无法访问该表,从而导致应用程序出现延迟或者错误。因此,了解如何有效地解锁表是每个Oracle数据库管理员必备的技能之一。 #### 1. 识别锁定的表 在解决锁定问题之前,首先...

Global site tag (gtag.js) - Google Analytics