您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關SQL SERVER鎖升級的investigation是怎樣的,文章內容質量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關知識有一定的了解。
前些日子在分析SQL SERVER 死鎖的過程中,檢查有一些莫名其妙的死鎖,兩個根本不搭噶的事務,鎖在了一起,WHY,其實SQL SERVER 在數據庫界,算是一朵奇葩,獨有的鎖升級的技術,我想你應該不曾聽到 MYSQL ,ORACLE , PG ,MONGODB 這些數據庫提及到的鎖升級的問題。
而牽扯到鎖升級到額問題,就需要提及,到底為什么鎖升級,鎖從哪里升級到哪里的問題。所以就有了這篇文字,關于鎖升級的東西。
首先我們在談論鎖的時候,的先站在一個討論的起跑線,就是鎖是發生在內存級別的,并且鎖的開始和結束都是伴隨著“事務”的開始和結束。在達成如上的共識后我們就開始下面的一些討論和研究。
當事務管理器接收到提交請求時,它向事務中涉及的所有資源管理器發送一個prepare命令。然后,每個資源管理器執行使事務持久所需的所有操作,并將保存事務日志映像的所有緩沖區刷新到磁盤。當每個資源管理器完成準備階段時,它將準備的成功或失敗返回給事務管理器。
如果事務管理器從所有資源管理器接收到成功的準備,它將向每個資源管理器發送提交命令。然后,資源管理器可以完成提交。如果所有資源管理器都報告提交成功,那么事務管理器將向應用程序發送成功通知。如果任何資源管理器報告準備失敗,事務管理器將向每個資源管理器發送回滾命令,并指示向應用程序提交失敗。
SQL SERVER 在什么時候會選擇什么樣的鎖的因素可能有哪些
下面是部分SQL SERVER 中可以進行鎖的資源樣本
RID | 沒有建立聚簇索引(HEAP TABLE)中標識行 ROW ID |
KEY | 索引中的行鎖,用于在可序列化事務中保護鍵范圍 |
PAGE | 8KB的page 頁,作為一個鎖定的單位 |
EXTENT | 連續的8 個頁面,作為鎖定的單位 |
HoBT | 堆或b樹。保護表中沒有聚集索引的b樹(索引)或堆數據頁的鎖。 |
TABLE | 表 |
問題:為什么要這么多鎖的類型,MYSQL innodb 不僅僅有 row lock嗎?
作為一個商業數據庫,在設計之初SQL SERVER 考慮了下面一個圖(假設),使用低級鎖(如行鎖)可以降低兩個事務同時請求同一數據塊上的鎖的概率,從而提高并發性,但使用低級鎖還會增加鎖的數量和管理鎖所需的資源反之使用表或頁鎖可以降低開銷,但代價是降低并發性。
SQL Server數據庫引擎使用動態鎖定策略來確定最經濟有效的鎖。數據庫引擎會根據模式和查詢的特性自動確定在執行查詢時哪些鎖是最合適的。例如,為了減少鎖定的開銷,優化器可以在執行索引掃描時選擇索引中的頁級鎖定。這樣做的好處也是顯而易見,如果我有多行在一個PAGE中,并且都需要更改,系統會根據需要索引的資源來鎖定這個PAGE,而不是一個頁面里面的每個行,因為要考慮每個鎖的管理,申請,釋放,都是需要相關CPU 資源,內存資源的,如果能在不影響并發度的情況下,鎖的粒度有效控制是有助于系統的信息的訪問和修改的。
并且SQL SERVER 也是可以在表的創建,或使用中進行鎖釋放可以自動進行升級的設置的,你可以打開表的鎖升級,或禁止掉他。
說到這里不得不說說SQL SERVER 鎖的歷史 SQL SERVER 7.0 之前的時候,(應該不是我出生的時候,在很久很久很久久以前久以前),SQL SERVER 是不支持 ROW 鎖的,而僅僅支持 PAGE LOCK,并且一個頁面是 2KB ,在 SQL SERVER 7.0,他們將SQL SERVER 變為了 8KB 的PAGE ,并且開始支持了 ROW LOCK。那到底為什么 SQL SERVER 不能做成和MYSQL 一樣,僅僅支持行鎖就好的數據庫,為什么單庫的商業數據庫還是有優勢的(注意這是問句)
下面是一個行鎖的結構
鎖是一個64或128字節的內存結構(分別用于32位或64位機器),每個持有或請求鎖的進程都有另外32或64字節。如果您需要對每一行都使用鎖,并且掃描一百萬行,那么您需要超過64MB的RAM來保存該進程的鎖。
一個語句在一個對象上持有的鎖的數量超過了一個閾值。舉例目前這個閾值是5000個鎖,超過就會觸發esclation,如果鎖分布在同一語句中的多個對象上,則不會發生鎖升級——例如,一個索引中的3000個鎖和另一個索引中的3000個鎖,另一方面鎖資源占用的內存超過啟用內存的40%,那么鎖會將發生升級。
那鎖升級到底是好不好,回答是 呵呵, 我想你明白我的意思。為什么
當觸發鎖升級時,如果存在沖突鎖,則會先增加更多的X鎖(我想你應該是懂這個過程的),并且不同進程持有的同一表或分區上有并發的X鎖,則鎖升級嘗試將失敗。每次事務在同一對象上獲得另外更多個鎖時,SQL Server都會繼續嘗試升級鎖,成功后會將SQL Server索引或堆表上的所有行鎖進行釋放。
可以想想這個鎖升級從上到下的描述中,觸發他的伴隨的是大事務,占用更多的內存,系統陷入了可能繁忙的狀態,那此時進行鎖升級,可能會成功,可能會失敗,同時成功后,鎖的級別將從ROW 變成 PAGE 或者更寬泛的鎖,系統將由 SHARE 變為 ONLY You use it . 其他的事務如果訪問你的資源,你是不是就不在管他們死活。
這還不是最糟糕的,鎖升級會導致更多的死鎖的出現,并且是莫名其妙的,看似兩個根本就無關的事務,也會鎖在一起,我想這時候如果你的領導來詢問你的時候為什么這么多莫名其妙的死鎖時,你是不是已經可以,有理有據來和他 make clear 一下了。
關于SQL SERVER鎖升級的investigation是怎樣的就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。