亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

SQL Server鎖分區特性引發死鎖解析

系統 2277 0
原文: SQL Server鎖分區特性引發死鎖解析

鎖分區技術使得SQL Server可以更好地應對并發情形,但也有可能帶來負面影響,這里通過實例為大家介紹,分析由于鎖分區造成的死鎖情形.

前段時間園友 @JentleWang 在我的博客 鎖分區提升并發,以及鎖等待實例 中問及鎖分區的一些特性造成死鎖的問題,這類死鎖并不常見,我們在這里仔細分析下.不了解鎖分區技術的朋友請先看下我的鎖分區那篇實例.

Code(執行測試腳本時請注意執行順序,說明)

步驟1 創建測試數據

      
        use
      
      
         tempdb


      
      
        go
      
      
        create
      
      
        table
      
      
         testdlk

(

id 
      
      
        int
      
      
        identity
      
      (
      
        1
      
      ,
      
        1
      
      ) 
      
        primary
      
      
        key
      
      
        ,

str1 
      
      
        char
      
      (
      
        3000
      
      
        )

)


      
      
        go
      
      
        insert
      
      
        into
      
       testdlk(str1) 
      
        select
      
      
        '
      
      
        aaa
      
      
        '
      
      
        insert
      
      
        into
      
       testdlk(str1) 
      
        select
      
      
        '
      
      
        bbb
      
      
        '
      
      
        insert
      
      
        into
      
       testdlk(str1) 
      
        select
      
      
        '
      
      
        ccc
      
      
        '
      
      
        insert
      
      
        into
      
       testdlk(str1) 
      
        select
      
      
        '
      
      
        ddd
      
      
        '
      
    

步驟2 開啟 session 1 執行語句

      
        --
      
      
        session 1 
      
      
        begin
      
      
        tran
      
      
        update
      
       testdlk 
      
        set
      
       str1
      
        =
      
      
        '
      
      
        ttt
      
      
        '
      
      
        where
      
       id
      
        =
      
      
        1
      
      
        --
      
      
        -session id 55 this example
      
      
        

--
      
      
        -rollback tran 
      
      
        

--
      
      
        -manual after session 3 rollback session 1
      
    

步驟3 開啟session 2 執行語句

      
        --
      
      
        session 2
      
      
        BEGIN
      
      
        TRAN
      
      
        update
      
       testdlk 
      
        set
      
       str1
      
        =
      
      
        '
      
      
        abc
      
      
        '
      
      
        where
      
       id
      
        =
      
      
        2
      
      
        --
      
      
        -update the content of id=2
      
      
        SELECT
      
      
        *
      
      
        FROM
      
       testdlk 
      
        WITH
      
      (TABLOCKX)
      
        --
      
      
        ---- try to get X lock on the object testdlk
      
      
        rollback
      
      
        tran
      
      
        --
      
      
        -session id 58 this example
      
    

步驟4 開啟session 3執行數據

      
        --
      
      
        session 3
      
      
        BEGIN
      
      
        TRAN
      
      
        update
      
       testdlk 
      
        set
      
       str1
      
        =
      
      
        '
      
      
        abc
      
      
        '
      
      
        where
      
       id
      
        =
      
      
        3
      
      
        --
      
      
        -----update the content of id=3 
      
      
        SELECT
      
      
        *
      
      
        FROM
      
       testdlk 
      
        WITH
      
      (TABLOCKX)
      
        --
      
      
        - try to get X lock on the object testdlk
      
      
        rollback
      
      
        tran
      
      
        --
      
      
        -session id 59 this example
      
    

步驟5 創建腳本的session中執行語句

      
        select
      
      
         request_session_id,resource_lock_partition,resource_type,


      
      
        object_name
      
      (resource_associated_entity_id) 
      
        as
      
      
        object_name
      
      
        ,request_mode,request_status 


      
      
        from
      
       sys.dm_tran_locks 
      
        where
      
       resource_database_id
      
        =
      
      
        2
      
      
        and
      
       resource_type
      
        =
      
      
        '
      
      
        OBJECT
      
      
        '
      
      
        select
      
      
         session_id,blocking_session_id,wait_type,resource_description 


      
      
        from
      
       sys.dm_os_waiting_tasks 
      
        where
      
       blocking_session_id 
      
        is
      
      
        not
      
      
        null
      
    

步驟6 session 1中rollback

      
        Rollback
      
       session 
      
        1
      
      
        --
      
      
        when session 1 rollback then session 3 deadlock
      
    

當session 1回滾時,session2 session 3造成死鎖,session 3犧牲.

原因分析.

通過步驟四我們可以得到相應的會話的鎖,及相關等待情況如圖1-1

??????????????????????????????????????????????????????????????? 圖1-1

?

可以看到session 1(圖中55)由于只是更新id=1的列,所以它會在key上加排它鎖(圖中未列出,感興趣朋友可以自行查看),而在Object testdlk中某個鎖分區中圖中為鎖分區1加上意向排它鎖.

Session 2(圖中58)由于更新了id=2的列,所以會在相應Key上加排他鎖,并在某個鎖分區中加意向排他鎖(IX),于此同時由于此事務下面查詢有表級TABLOCKX Hint,此時58會嘗試在表級上排他鎖(X鎖).由于X鎖需要在所有鎖分區中獲得,此時58在鎖分區0中獲得X鎖,但由于鎖分區1中有55獲得了意向排他鎖(IX),所以58在鎖分區1中嘗試獲取X鎖時狀態未Convert,被55阻塞.

Session 3(圖中59)由于更新了id=3的列,所以會在相應key上加排他鎖,同時在某個鎖分區中加意向排他鎖(IX),于此同時由于此事務下面查詢同樣有表級TABLOCKX Hint,這時59也會嘗試在表的所有分區中獲取X鎖.由于58已經獲得鎖分區0的X鎖,所以當59嘗試獲取鎖分區0的X鎖時,就會被58阻塞,狀態為Wait.

問題來了,當55回滾時,其上面的鎖也將被釋放.此時58,59都試圖獲得表級的所有分區X鎖,而又同時在鎖分區中持有IX鎖,這時死鎖就不可避免了.

死鎖視圖如圖1-2所示.

?

????????????????????????????????????????????? 圖1-2

?

問題解決

經過分析,可以看出是由于鎖分區的特性導致IX與不同spid中的X互斥導致,那如果能禁用鎖分區特性不就沒有在個別分區上的IX這回事兒了嗎.這里介紹一個啟動標記 trace flag 1229,可以禁用鎖分區特性.我們可以通過配置管理器中添加啟動標記,也可以在command啟動時加上響應參數.應當注意當使用配置管理器時,我們應在啟動參數末尾配置”-T1229”,如果使用command,這時是t1229(大小寫區分)

這里我用win中command啟用

Code

      Net start mssqlserver /t1229
    

重新啟動后重復上述實例,死鎖就不在出現了.

注: 此實例只為說明由于鎖分區造成的死鎖情形,實際生產中此類情形卻是罕見的,除非遇到這類情形并且沒有更好的規避方式,一般我們還是建議默認此特性.這對提升并發是很有幫助的.

關于鎖分區特性.

通過微軟的在線文檔可以得知,只有當CPU的邏輯數大于等于16時,才會默認開啟此特性,而授權又是按照CPU收費的.問題來了,當CPU小于16我如果想利用此特性是否可以呢?這個再給大家介紹一個啟動跟蹤標記 trace flag 1228.當有兩個及以上邏輯CPU時就會啟動鎖分區特性.不過我們使用時清楚自己的使用場景,是否會因此TF得到好處.由于這是無官方文檔記錄的特性,使用應只針對特定需求,并應慎重.

結語: SQL Server或是其他數據庫系統中任何一個特性的引入總會適應大多數場景,但也會伴隨著特定場景的弊端出現,清楚其所帶來的利弊并合理使用,使得SQL Server適應場景,我們也能適應SQL Server.

SQL Server鎖分區特性引發死鎖解析


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 搡女人免费的视频 | 久久伊人影院 | 国产成人精品在视频 | 97免费看| 久久精品国产免费观看99 | 麻豆精品久久精品色综合 | 99久久久久国产精品免费 | 老司机深夜免费福利 | 亚洲网站在线看 | 成人网18免费网站 | 俄罗斯老妇性欧美毛茸茸孕交 | 日韩一级欧美一级毛片在线 | 亚洲午夜一级毛片 | 91精品国产人成网站 | 青青青免费手机版视频在线观看 | 国产偷怕自拍 | 九九爱国产 | 99热精品成人免费观看 | 99这里有精品视频 | 欧美伊香蕉久久综合类网站 | 九九热久久免费视频 | 欧美性生活一级 | 国产免费播放一区二区三区 | 国产亚洲美女精品久久久2020 | 午夜精品久久影院蜜桃 | 欧美激情(一区二区三区) | 午夜剧| 国产亚洲精品在天天在线麻豆 | 色偷偷91综合久久噜噜 | 一级黄色网 | 国产在线一区二区三区在线 | 色综合久久中文字幕网 | 国自产拍在线天天更新2019 | 一级做a爱片久久蜜桃 | 波多野结衣久久精品免费播放 | 爱性网| 久久久这里只有精品加勒比 | 91国内精品久久久久影院优播 | www.欧美| 久久久久久久久久久96av | 狠狠舔 |