• SQLSERVER 死锁标志


    最开始做DBA的时候,整天死锁到头痛1222,至今都能回想到这个错误窗口;

    死锁定义:死锁是指在一组进程中的各个进程均占有不会释放的资源,但因互相申请被其他进程所站用不会释放的资源而处于的一种永久等待状态。

    四个必要条件:

    互斥条件(Mutual exclusion):资源不能被共享,只能由一个进程使用。
    请求与保持条件(Hold and wait):已经得到资源的进程可以再次申请新的资源。
    非剥夺条件(No pre-emption):已经分配的资源不能从相应的进程中被强制地剥夺。
    循环等待条件(Circular wait):系统中若干进程组成环路,该环路中每个进程都在等待相邻进程正占用的资源。

    对应到SQL Server中,当在两个或多个任务中,如果每个任务锁定了其他任务试图锁定的资源,此时会造成这些任务永久阻塞,从而出现死锁;这些资源可能是:单行(RID,堆中的单行)、索引中的键(KEY,行锁)、页(PAG,8KB)、区结构(EXT,连续的8页)、堆或B树(HOBT) 、表(TAB,包括数据和索引)、文件(File,数据库文件)、应用程序专用资源(APP)、元数据(METADATA)、分配单元(Allocation_Unit)、整个数据库(DB)。

    遇到死锁,先看下sp_who 和 sp_lock

    Trace Flag  1204 和1222
    这两个跟踪标记都是将死锁写到错误日志中,不过1204是以文本格式进行,而1222是以XML格式保存。可以通过
    sp_readerrorlog查看日志
     
    DBCC TRACEON (3605,1204,1222,-1)
    3605 将DBCC结果输出到错误日志;
    1204、1222  返回锁资源和类型;
    -1    全局方式打开指定追踪标记;
     
    重启后失效,需重新创建;
    也可以在引擎启动参数中加进去
    image
    演示下错误日志报告:
    首先创建两个表:
    脚本很简单:

    CREATE TABLE A
    (
    ID INT,
    NAME CHAR(4)
    );
    CREATE TABLE B
    (
    ID INT,
    NAME CHAR(4)
    );

    INSERT INTO A VALUES (1,'KING')
    INSERT INTO A VALUES (2,'KING')
    INSERT INTO A VALUES (3,'KING')

    INSERT INTO B VALUES (1,'KING')
    INSERT INTO B VALUES (2,'KING')
    INSERT INTO B VALUES (3,'KING')

    分别开两个窗口:
    开启两个事物(51)
    BEGIN TRAN T1
    UPDATE A SET NAME='QUE' WHERE ID=1
    WAITFOR DELAY '00:00:15'
    SELECT * FROM B

    ROLLBACK TRAN T1

    开启第二个窗口:(56)

    BEGIN TRAN T2
    UPDATE B SET NAME='QUE' WHERE ID=2
    WAITFOR DELAY '00:00:15'
    SELECT * FROM A

    ROLLBACK TRAN T2

    image

    SP_READERRORLOG读取错误编号:

    image

    解决亦可以加with (nolock)隔离级别,不过会产生脏读;

  • 相关阅读:
    使用discourse 作为社区工具
    dremio schema 更新的问题
    go-mysql-server 新版本发布
    开发一个dremio user_agent 解析函数
    java 几个不错的user_agent 解析工具包
    Docker Swarm 高可用详解
    用Docker Swarm实现容器服务高可用
    Docker 1.12 :认识 Swarm 模式下的节点崩溃处理
    Linux下磁盘分区调整(在不使用LVM的情况下)
    docker-swarm----多机容器管理
  • 原文地址:https://www.cnblogs.com/kingwwz/p/5764286.html
Copyright © 2020-2023  润新知