日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

研发协同平台数据库死锁处理及改进

發布時間:2023/12/4 数据库 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 研发协同平台数据库死锁处理及改进 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

源寶導讀:數據庫死鎖是高并發復雜系統都要面臨課題,處理死鎖問題沒有一招制敵的標準方法,需要具體問題具體分析。本文將基于研發協同平臺遇到的死鎖案例,介紹從監控、分析到處理的完整過程和經驗總結。

一、背景

? ? ? 研發協同平臺使用的技術棧大體是.NET Core + EFCore + SQLServer, 周邊還有一些第三方組件, 如Redis、Jenkins、Gitlab、Sonar。整體技術架構又分為前臺服務(rdc_service)、調度服務(rdc_service)、更新服務(rdc_upgrade)。其中更新服務面向所有終端用戶的服務器,用于客戶產品更新;調度服務作為后臺作業,定時對客戶的服務器進行巡檢,發現異常服務器時通知客戶;客戶和客戶服務器的數量數以萬計,接口請求量較大,更新服務和調度服務都是對客戶及其服務器數據操作,兩者之間難免會有數據上的交際,這樣一來,死鎖就有了可乘之機,本文重點介紹研發協同平臺對死鎖的監控和解決方案。

二、死鎖監控

? ? 在早期SQL Server中,通過跟蹤標志1204/1222,可以在數據庫錯誤日志中捕獲的死鎖信息。跟蹤標志1204會報告由死鎖所涉及的每個節點設置格式的死鎖信息。跟蹤標志 1222 會設置死鎖信息的格式,順序為先按進程,然后按資源。可以同時啟用這兩個跟蹤標志,以獲取同一個死鎖事件的兩種表示形式。

? ? 下面的示例顯示啟用跟蹤標志 1204 時的輸出。在此示例中,節點 1 中的表為沒有索引的堆,節點 2 中的表為具有非聚集索引的堆。節點 2 中索引鍵在發生死鎖時正在進行更新。

? ? 在工作負載密集型系統上使用跟蹤標志1204和1222可能會導致性能,為了解決這一問題,自 SQL Server 2012 (11.x) 起,SQL Server提供了xml_deadlock_report 擴展事件 (xEvent),來幫助研發人員更加便捷高效的監測及排查死鎖。下圖展示了在擴展事件中可以捕獲的deadlock相關事件:

? ? 在擴展事件啟用后,當數據庫發生死鎖時,SQL Server會自動將導致死鎖的相關會話數據,以XML的形式保存下來,下圖展示了研發協同平臺近期監控到的死鎖記錄:

三、死鎖分析

? ? 隨機查看幾個死鎖日志,所有的記錄均屬于同一場景:進程1持有表CustomerServer行A的排他(X)鎖,需要申請表Customer行B的共享(S)鎖,而進程2剛好持有Customer行B的排他(X)鎖,且正在向CustomerServer表行A申請更新(U)鎖。眾所周知,排他(X)鎖和更新(U)鎖完全互斥,故兩個進程陷入了相互等待的僵局。下圖1展示了死鎖發生時兩個進程的相關數據,圖2則顯示了雙方在資源上面的爭用情況。

? ? 除非某個外部進程斷開死鎖,否則死鎖中的兩個事務都將無限期等待下去。SQL Server 數據庫引擎死鎖監視器定期檢查陷入死鎖的任務。如果監視器檢測到循環依賴關系,將選擇其中一個任務作為犧牲品,然后終止其事務并提示錯誤。其他任務就可以完成其事務。

? ? 另外需要注意的是:死鎖經常與正常阻塞混淆。事務請求的資源被其他事務鎖定時,發出請求的事務一直等到該鎖被釋放。除非設置了 LOCK_TIMEOUT,否則 SQL Server 事務不會超時。擁有鎖的事務完成并釋放鎖后,發出請求的事務將獲取鎖并繼續執行,所以該事務是被阻塞,而不是陷入了死鎖。

? ? 默認情況下,SQL Server 數據庫引擎選擇運行回滾開銷最小的事務的會話作為死鎖犧牲品。此外,用戶也可以使用 SET DEADLOCK_PRIORITY 語句指定死鎖情況下會話的優先級。

3.1、死鎖業務場景

? ? 進一步分析死鎖報告,可以直觀的看到涉及死鎖的兩個進程來至3臺服務器,這里我們假定是服務器A、B、C。3臺服務器分別屬于進程1調度服務(服務器A)、進程2更新服務(服務器B、C)。調度服務是一組后臺作業任務的集合,其中有同時訪問表Customer\CustomerServer的任務只有一個,即客戶服務器狀態同步作業:掃描系統中所有客戶的服務器,只要客戶服務器未按照約定上報信息,則認為其離線,將離線狀態同步至客戶表(Customer)和客戶服務器表(CustomerServer),并給客戶對應的負責人發送郵件。該作業每分鐘執行一次,每次作業任務耗時50s,執行時間過長可能是導致頻繁死鎖的原因之一。

? ? 通過死鎖報告中的服務器信息可以快速的定位到進程1的業務場景,那么進程2則需要其他工具來幫助我們定位。進程2更新服務是一組API集合,供用戶更新客戶環境的相關業務,其中涉及Customer\CustomerServer兩張表的操作非常多,如果心跳接口、注冊客戶信息接口。到這一步,我們所知道的信息如下:

? ? 死鎖報告的中的SQL腳本是由EFCore生成的,表面上看不出來進程2到底是哪一個接口。這里我們借助SkyWalking 的端點埋點數據,下圖1是所有心跳接口的錯誤記錄,時間點與死鎖日志中的時間完全匹配,沒有例外;圖2是錯誤詳情,其中的事務進程Id和死鎖犧牲對象與死鎖中報告完全匹配。

3.2、主外鍵對執行計劃的影響

? ? SQL Server 數據庫引擎提供了訪問查詢執行計劃的運行時信息。出現性能問題時,最重要的操作之一是準確了解正在執行的工作負載以及如何驅動使用資源。為此,訪問實際執行計劃將很重要。這里的更新服務心跳接口,只有對客戶服務器表(CustomerServer)訪問,并沒有直接對Customer表進行訪問,通過SkyWalking的端點數據,以及死鎖報告中的SQL腳本,可以拿到心跳接口的估算執行計劃。盡管業務場景只需要更新一個Status字段,但由于未開啟EFCore的模型跟蹤(ChangeTracker),EFCore生成的SQL腳本顯示的更新了除主鍵以外所有字段。其中[CustomerId]和[PluginId]正好是外鍵字段,分別來自Customer和Plugin表,為了保證主外鍵的約束,一條簡單的單表update操作,將涉及到3張表的資源訪問。下圖展示了心跳接口在SQL Server中的執行計劃:

? ? 如果開啟的模型跟蹤,或者手動寫編寫SQL,按需更新字段,上面的死鎖將不會存在,下圖展示了單表單字段場景下的執行計劃:

四、業務改進

? ? 我們通過簡單的SQL改造,在不影響業務的情況下,將進程2的SQL資源訪問由3張表降低至單表操作,這里不敢保證說已經消除了死鎖,但至少將死鎖降低到一個可以忽略不計的范圍。為了保險起見,這里繼續對進程1(調度服務Job)優化。

? ? 上述提到客戶服務器狀態同步作業每分鐘執行一次,每次作業任務耗時50s,這里的耗時有點過長,Job在全天24小時內,有83%(50s/60s)的時間處于作業中,為了保證原子性,這里采用是的方法級事務,事務鎖定的范圍是整個作業周期,即時50s,并且不論客戶的服務器狀態是否發生改變,這里都會修改數據,下面是Job相關的代碼:

? ? 在不改變業務場景的基礎上,我們對作業Job的執行策略做了微調:

  • 修改正式環境時間間隔為10分鐘

  • 更新方式調整為更新指定字段

  • 每個客戶單獨開啟事務處理

  • 狀態未發生變化時不修改數據

? ? 客戶環境的服務器比較復雜,通常來說偶爾的抖動屬于正常現象,心跳的有效期都是3-5分鐘,每分鐘去檢測一次狀態有點多余,這里將作業時間由每分鐘調整10分鐘,可以有效降低后臺作業與前端API接口之間的資源沖突;更新方式采用EFCore的模型跟蹤(ChangeTracker),按需更新,這里既然只檢測狀態變更,就只需要更改狀態,減少修改的字段,可以避免由主外鍵引起的額外共享鎖申請;第3條和第4條都是為了降低事務的范圍,這里的事務原子性控制到單個客戶明顯比全局性價比高,沒必要因為一個客戶的失敗,導致整個作業失敗,當客戶服務器狀態沒有發生變化時,對當前客戶的處理應直接跳過,減少修改次數;通過上面4條優化策略,任務的作業時間由之前的50s降低為15s,且不會對業務產生影響,死鎖也隨時消除。

五、寫在最后

? ? 盡管死鎖不能完全避免,但遵守特定的編碼習慣可以將發生死鎖的機會降至最低。在這里分享幾點研發協同平臺團隊的開發規范,有助于大家在日常開發中避免死鎖和提高數據庫性能:

  • 縮小事務的范圍,提前計算出需要更新的數據,避免在事務中做額外的業務邏輯計算;

  • 按需更新行字段,EFCore類似的ORM框架,帶來了開發上的便捷,同時也會帶來性能上的隱患;

  • 外鍵字段加索引,外鍵字段索引可以顯著降低查詢或更新時,降低對數據資源鎖定的范圍;

  • 定期優化慢SQL ,慢SQL意味著需研發協同平臺持續交付2.0架構演進要讀取更多索引頁或者數據頁,加大資源鎖定的范圍;

作者簡介

馮同學:?研發工程師,目前負責研發協同平臺的設計與開發工作。

也許您還想看

研發協同平臺持續集成Jenkins作業設計演進

研發協同平臺持續交付之代理服務實踐

研發協同平臺持續集成2.0架構演進

研發協同平臺持續交付2.0架構演進

總結

以上是生活随笔為你收集整理的研发协同平台数据库死锁处理及改进的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。