sqlserver大数据量频繁锁表的问题

发布于:2023-01-21 ⋅ 阅读:(285) ⋅ 点赞:(0)

问题分析

  1. 排除是否事务导致表锁死的问题
  2. 调查表数据表是否过大(一般以百万为单位,过千万肯定需要缩减,未到百万问题不大)
  3. 是否存在同时间边修改边读的问题
  4. 是否存在同时间多个sql同时修改一条记录的情况
  5. 修改语句where条件中是否是主键

为什么需要排查这些问题

事务导致表锁死

这个问题很简单,自己写的代码把自己锁上了,那能怎么办,快删库跑路吧

数据量大

单个表数据量过大会导致增删改查都会变慢,高并发大数据时会导致大堵车,肯定会出问题。考虑分库分表添加索引加快检索速度解决一下

是否存在边写边读的问题

新手会很好奇,这俩操作有什么关系呢?
其实在查询时,sqlserver自动创建了共享锁(s锁),共享锁与共享锁之间并不冲突。但修改时需要创建独占锁,独占锁与共享锁之间是冲突的。所以会出现问题。在查询时表后面加nolock解决

多个sql同时修改一条记录

更新锁是一种中继锁。当同一项资源从原来的查询操作转换为更新操作时,锁定机制会从共享锁变为更新锁,再进一步变成独占锁。
而独占锁与独占锁之间会冲突,所以会出现问题

修改语句where条件中是否是主键

在修改语句执行中会出现锁,如果where条件是主键那么只会出现行锁,如果不是主键那就是页锁(甚至会直接锁表)。

参考资料

SQLSERVER的锁机制:点击查看

如何捕获死锁信息:点击查看

sqlserver update 锁:点击查看

辅助sql

-查询锁表session

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

--杀死锁表进程
declare @spid  int 
    Set @spid  = 78 --锁表进程
    declare @sql varchar(1000)
    set @sql='kill '+cast(@spid  as varchar)
    exec(@sql);
--查看死锁列表
SELECT XEvent.query('(event/data/value/deadlock)[1]') AS DeadlockGraph
FROM (
    SELECT XEvent.query('.') AS XEvent
    FROM (
        SELECT CAST(target_data AS XML) AS TargetData
        FROM sys.dm_xe_session_targets st
        INNER JOIN sys.dm_xe_sessions s 
        ON s.address = st.event_session_address
        WHERE s.NAME = 'system_health'
        AND st.target_name = 'ring_buffer'
        ) AS Data
CROSS APPLY TargetData.nodes('RingBufferTarget/event[@name="xml_deadlock_report"]') AS XEventData(XEvent)
) AS source;

网站公告

今日签到

点亮在社区的每一天
去签到