迷之自信的Single_User Mode

Alter database Set Single_User數據庫

對於任何DBA來講,恐怕都不陌生。在咱們須要獲取數據庫獨佔訪問權來作一些數據庫緊急維護的時候,這多是大多數DBA的首選,但它真的能夠實現「獨佔訪問權」嗎?併發

此次咱們聊聊Single_User是如何刷新咱們認知的工具

==============華麗麗的分割線==============測試

實驗目的:測試Single_User模式下是否能夠拿到獨佔權並隨心所欲。spa

照例交代一下咱們的環境:Windows 10 + SQL Server 2019,實際上本次實驗的結果基本上是覆蓋SQL Server所有版本的線程

併發測試工具:SQLQueryStress(0.9.7.79)blog

咱們先看一下在單用戶模式下,持有鎖的狀況io

從上圖能夠看到,在成功置爲Single_User模式後,咱們擁有了一個執行Session(id=60)上,DB級別的S鎖壓力測試

這時,咱們開啓SQLQueryStress,設置查詢語句,併發線程數爲2,迭代5000次請求

再次查詢持有鎖的狀況

Session 7一、72是咱們壓力測試工具設置2個線程產生的,能夠看到,除了持有S鎖外,他們各自還正在申請X鎖,只是相互等待而造成了死鎖

由上圖能夠看到,XEvents中存在大量死鎖信息,且下圖能夠看到死鎖的細節信息,由Session 7一、72致使

 

此時,當咱們再次準備從Session 60中執行語句,將數據庫置爲Multi_User時,錯誤發生了:

Session 60也被死鎖犧牲了。由此看來,咱們並無真正的獲取數據庫的「獨佔訪問權」

 

==============華麗麗的分割線==============

分析 & 結論:

一、將數據庫置爲單用戶模式在咱們長期的認知中,都是絕對的「獨佔訪問權」。但實際上,在有併發+連續訪問的狀況下,咱們仍有可能因外部訪問的死鎖而丟掉這個「獨佔訪問權」

二、進一步分析,從將數據庫置爲單用戶模式的時候,數據庫系統沒有直接將Session的鎖級別提高至最高(我的理解,從Alter Database觸發的動做,置爲SCH-X都不爲過),而是溫和的放置了DB級的S鎖,同時對其餘訪問相同數據庫的請求則要求申請X鎖,這就致使了,當外部請求訪問數據庫時,先放置DB級S鎖(這裏和Single User Session 的DB級S鎖且兼容),然後由於要申請X鎖,因此和其餘訪問一樣數據庫的請求達成了死鎖條件。

三、若是在應急處置中仍須要將DB置爲Single User模式,建議停掉外部訪問(停帳號,修改實例端口號,關閉TCP\IP,禁用外部訪問網卡,或者修改數據庫名稱),以避免沒法置回Multi User模式。

相關文章
相關標籤/搜索