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

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條評論
主站蜘蛛池模板: 欧美成人禁片在线www | 99久久精品无码一区二区毛片 | 久久一区二区三区免费 | 亚洲精品视频观看 | 四虎网站最新地址 | 99国产福利 | 四虎国产精品永久在线 | 日日爱影院| 97色老99久久九九爱精品 | 久在线精品视频 | 成人在线综合 | 狠狠综合久久久久综合 | 视频免费1区二区三区 | 伊人中文字幕 | 久久激情综合色丁香 | 国产欧美视频一区二区三区 | 欧美日韩亚洲国产一区二区三区 | 久草视频首页 | 精品久久网站 | 国产精品亚洲欧美 | 一级一级女人18毛片 | 国产综合精品一区二区 | 狠狠色伊人亚洲综合第8页 狠狠色综合久久丁香婷婷 狠狠色综合久久婷婷 | 国产日韩欧美亚洲 | 天堂网在线观看 | 狠狠色噜狠狠狠狠 | 日韩在线一区视频 | 日本不卡高清视频 | 久久国产精品视频一区 | 久久99久久精品久久久久久 | 亚洲一区二区三区精品国产 | 97色精品视频在线观看免费 | 99久久99热久久精品免 | 一区在线看 | 亚洲国产高清视频在线观看 | 日本叼嘿 | 999视频在线观看 | 日本人xxxxxxx中国 | 99热在线精品观看 | 夜精品a一区二区三区 | 国内永久第一免费福利视频 |