zoukankan      html  css  js  c++  java
  • 查看sqlserver被锁的表以及如何解锁

    查看被锁表:

    select   request_session_id   spid,OBJECT_NAME(resource_associated_entity_id) tableName   
    from   sys.dm_tran_locks where resource_type='OBJECT'

    spid   锁表进程 
    tableName   被锁表名

    解锁:

    declare @spid  int 
    Set @spid  = 57 --锁表进程
    declare @sql varchar(1000)
    set @sql='kill '+cast(@spid  as varchar)
    exec(@sql)

    死锁和堵塞一直是性能测试执行中关注的重点。

    下面是我整理的监控sql server数据库,在性能测试过程中是否出现死锁、堵塞的SQL语句,还算比较准备,留下来备用。

    --每秒死锁数量
    
    SELECT  *
    FROM    sys.dm_os_performance_counters
    WHERE   counter_name LIKE 'Number of Deadlocksc%';
    
    --查询当前阻塞
    
    WITH    CTE_SID ( BSID, SID, sql_handle )
              AS ( SELECT   blocking_session_id ,
                            session_id ,
                            sql_handle
                   FROM     sys.dm_exec_requests
                   WHERE    blocking_session_id <> 0
                   UNION ALL
                   SELECT   A.blocking_session_id ,
                            A.session_id ,
                            A.sql_handle
                   FROM     sys.dm_exec_requests A
                            JOIN CTE_SID B ON A.SESSION_ID = B.BSID
                 )
        SELECT  C.BSID ,
                C.SID ,
                S.login_name ,
                S.host_name ,
                S.status ,
                S.cpu_time ,
                S.memory_usage ,
                S.last_request_start_time ,
                S.last_request_end_time ,
                S.logical_reads ,
                S.row_count ,
                q.text
        FROM    CTE_SID C 
                JOIN sys.dm_exec_sessions S ON C.sid = s.session_id
                CROSS APPLY sys.dm_exec_sql_text(C.sql_handle) Q
        ORDER BY sid

    复制代码

    在压力测试过程中,不间断的按F5键执行上面的SQL语句,如果出现死锁或者堵塞现象,就会在执行结果中罗列出来。如果每次连续执行SQL,都有死锁或者堵塞出现,说明死锁或者堵塞的比较严重。

     在生产环境下,有时公司客服反映网页半天打不到,除了在浏览器按F12的Network响应来排查,确定web服务器无故障后。就需要检查数据库是否有出现阻塞

    当时数据库的生产环境中主表数据量超过2000w,子表数据量超过1亿,且更新和新增频繁。再加上做了同步镜像,很消耗资源。

    这时就要新建一个会话,大概需要了解以下几点:

    1.当前活动会话量有多少?

    2.会话运行时间?

    3.会话之间有没有阻塞?

    4.阻塞时间 ?

    查询阻塞的方法有很多。有sql 2000 的sp_lock, 有sql 2005及以上的dmv

    一. 阻塞查询 sp_lock

          执行 exec sp_lock  下面列下关键字段

          spid 是指进程ID,这个过滤掉了系统进程,只展示了用户进程spid>50。

          dbid 指当前实例下的哪个数据库 , 使用DB_NAME() 函数来标识数据库

          type 请求锁住的模式

          mode 锁的请求状态

                         GRANT:已获取锁。

                         CNVRT:锁正在从另一种模式进行转换,但是转换被另一个持有锁(模式相冲突)的进程阻塞。
                         WAIT:锁被另一个持有锁(模式相冲突)的进程阻塞。

         总结:当mode 不为GRANT状态时, 需要了解当前锁的模式,以及通过进程ID查找当前sql 语句 

                    例如当前进程ID是416,且mode状态为WAIT 时,查看方式 DBCC INPUTBUFFER(416)

                   用sp_lock查询显示的信息量很少,也很难看出谁被谁阻塞。所以当数据库版本为2005及以上时不建议使用。

     二.阻塞查询  dm_tran_locks         

    复制代码
     1 SELECT 
     2 t1.resource_type,
     3 t1.resource_database_id,
     4 t1.resource_associated_entity_id,
     5 t1.request_mode,
     6 t1.request_session_id,
     7 t2.blocking_session_id
     8 FROM sys.dm_tran_locks as t1
     9 INNER JOIN sys.dm_os_waiting_tasks as t2
    10 ON t1.lock_owner_address = t2.resource_address;
    复制代码

         上面查询只显示有阻塞的会话, 关注blocking_session_id 也就是被阻塞的会话ID,同样使用DBCC INPUTBUFFER来查询sql语句

    三.阻塞查询 sys.sysprocesses

    复制代码
     1 SELECT 
     2 spid,
     3 kpid,
     4 blocked,
     5 waittime AS 'waitms', 
     6 lastwaittype, 
     7 DB_NAME(dbid)AS DB,  
     8 waitresource, 
     9 open_tran,
    10 hostname,[program_name],
    11 hostprocess,loginame,
    12 [status]
    13 FROM sys.sysprocesses WITH(NOLOCK) 
    14 WHERE    kpid>0  AND  [status]<>'sleeping'  AND spid>50
    复制代码

      sys.sysprocesses  能显示会话进程有多少, 等待时间, open_tran有多少事务, 阻塞会话是多少. 整体内容更为详细。
      关键字段说明:

           spid 会话ID(进程ID),SQL内部对一个连接的编号,一般来讲小于50

      kipid 线程ID
      blocked: 阻塞的进程ID, 值大于0表示阻塞, 值为本身进程ID表示io操作
      waittime:当前等待时间(以毫秒为单位)。
      open_tran: 进程的打开事务数
      hostname:建立连接的客户端工作站的名称
      program_name 应用程序的名称。 
      hostprocess 工作站进程 ID 号。
      loginame 登录名。
      [status]
        running = 会话正在运行一个或多个批
        background = 会话正在运行一个后台任务,例如死锁检测
        rollback = 会话具有正在处理的事务回滚
        pending = 会话正在等待工作线程变为可用
        runnable = 会话中的任务在等待,由scheduler来运行的可执行队列中。(重要)
        spinloop = 会话中的任务正在等待调节锁变为可用。
        suspended = 会话正在等待事件(如 I/O)完成。(重要)
        sleeping = 连接空闲

                  wait resource 格式为 fileid:pagenumber:rid 如(5:1:8235440)

                  kpid=0, waittime=0 空闲连接

                  kpid>0, waittime=0 运行状态
                  kpid>0, waittime>0 需要等待某个资源,才能继续执行,一般会是suspended(等待io)
                  kpid=0, waittime=0 但它还是阻塞的源头,查看open_tran>0 事务没有及时提交。

                  如果blocked>0,但waittime时间很短,说明阻塞时间不长,不严重
                  如果status 上有好几个runnable状态任务,需要认真对待。 cpu负荷过重没有及时处理用户的并发请求

  • 相关阅读:
    leetcode Super Ugly Number
    leetcode Find Median from Data Stream
    leetcode Remove Invalid Parentheses
    leetcode Range Sum Query
    leetcode Range Sum Query
    leetcode Minimum Height Trees
    hdu 3836 Equivalent Sets
    hdu 1269 迷宫城堡
    hud 2586 How far away ?
    poj 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/Alex80/p/9403530.html
Copyright © 2011-2022 走看看