• 查看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负荷过重没有及时处理用户的并发请求

  • 相关阅读:
    Delphi DbgridEh实现鼠标拖动选中列,并使复选框选中
    什么是运行期包与设计期包
    组件事件大全
    sql: 查找约束
    delphi Ctrl+鼠标左键或者Find Declaration不能定位到源文件
    delphi7 编译的程序在win7下请求获得管理员权限的方法
    DELPHI中build和compile有什么区别?
    线程安全的单件模式(单例模式)
    [Selenium]通过Selenium实现在当前浏览器窗口点击一个图标之后,弹出另外一个窗口,关闭这个窗口,再回到原来的窗口进行操作
    两种读写配置文件的方案(app.config与web.config通用)
  • 原文地址:https://www.cnblogs.com/Alex80/p/9403530.html
Copyright © 2020-2023  润新知