控制鎖的粒度

2021-08-23 15:03:29 字數 2263 閱讀 1472

日期:2023年5月3日

翻譯:張洪舉

原文:在sql server 7.0

的所有版本中,引擎可以鎖定行、

頁或整個表。

此外,即使通過獲取行或頁鎖的方式啟動了查詢,如果獲取了太多的鎖,sql server

也可能會將其提公升到乙個表鎖。

每個鎖都需要使用記憶體,所以,當以乙個表鎖公升級替換成千上萬的細粒度鎖,可以節省大量的資源。另一方面,一旦表以獨佔方式被鎖定,則沒有其他程序可以從中訪問任何資料,從而大幅降低併發操作。

我們回到sql server 6/6.5

中,我們具有一些控制,像表的多少百分比被鎖定才引發鎖的粒度公升級。但是,這些作為執行控制的配置選項在sql 7

中被移除掉了。所以,現在我們如何進行控制呢?

在下列情況下會發生鎖公升級(來自sql server 2008

內部,ms press 2009

):我所見過的大部分對公升級的討論都是要阻止鎖公升級,從而能夠最大化地訪問資料。一種方法是在例項上啟用跟蹤標誌1211

,這可以防止從在任何情況下發生鎖公升級。

這樣做你需要非常小心,因為它會影響例項上的所有資料庫中的表。

另一種方法是跟蹤sql server

表的使用,因為即使有乙個被不同連線鎖定的行,也不會發生鎖公升級。

所以,你可以將乙個虛擬的行新增到表中,並開啟乙個事務程序,更新虛擬的行,然後將事務保持開啟狀態。雖然這可以防止任何人獲得乙個表鎖,但此方法具有嚴重的***。即:只要該事務處於開啟狀態,日誌不能截斷過去這一點。

但是,如果您可以將其與表的更新操作同步,並確保只要更新一完成就關閉虛擬更新,效果會好一些。

sql server 2008

為我們提供了更多的控制功能,在alter table

中新增乙個新選項:

alter table

set (lock_escalation = [table | auto |disable]);

預設公升級是table

,並且在sql 2008

之前這是唯一的公升級選擇。如果將該選項設定為auto

,鎖可以公升級到表或是乙個分割槽(如果表已分割槽)。

第三個選項是完全禁用此表的公升級。

此選項更易於管理對另乙個對單行鎖定的事務跟蹤,以及更細粒度地禁止整個例項上的公升級。

但是,你希望相反的行為怎麼辦?你總是希望通過表鎖來節省資源怎麼辦?

是這樣的,鎖提示可以請求為tablock

或tablockx

,但這些設定必須在每個查詢中指定。

如果一些表一直想鎖定在表級別怎麼辦?

sql server

在alter index

中提供了乙個選項,用於禁止row

和page

鎖(在sql 7

和2000

中可以使用系統過程sp_indexoption

來做這些事情)

。如果索引是聚集索引,這意味著對於表,row

和page

鎖是被禁止的。但是,如果表是乙個堆,則不能使用此選項。

alter index on

set (allow_page_locks = off);

此外請注意如果將allow_page_locks

設定為off

,則不能reorganize

(進行碎片整理)

索引。我通常在我的內部和除錯課程中提及此alter index

選項,並且還有一次提到此選項是客戶不恰當地關閉了page

和row

鎖,同時啟動了許多莫名其妙的表鎖。當你檢查sys.indexes

(有名為allow_row_locks

和allow_page_locks

的列,可能的值僅為0

和1)時,該行為不再是莫名其妙的。

(對於sql server 2005

之前的版本,可以使用indexproperty

函式來檢查這些選項的狀態)

。這就是幾年前我最後一次在遇到有人使用此選項來關閉精細粒度的鎖,並且我正考慮從課程中刪除對它的提及。

然而,上週在我的奧斯陸課上,乙個學生詢問為什麼她具有cte

的查詢在任何時候都啟用表鎖。我不相信它與cte

有關,但建議她等待一下,我們將在課程的第四天進行鎖的討論。

她付出了很多關注,星期五的早上她回來對我說不是cte

的問題,而是有人關閉了allow_page_locks

和allow_row_locks 選項!

所以,在以後的課程中我想我會繼續提及此選項。

鎖粒度示例

準備資料 建立表並插入資料 create table if not exists lock test id int unsigned auto increment,name varchar 100 not null default comment 名字 age int not null defaul...

MySQL併發控制之讀寫鎖和鎖粒度詳解

無論何時,只要有多個查詢需要在同一時刻修改資料,都會產生併發控制的問題。本章的目的是討論mysql在兩個層面的併發控制 伺服器層與儲存引擎層。併發控制是 乙個內容龐大的話題,有大量的理 獻對其進行過詳細的論述。本章只簡要地討論 mysql如何控制併發讀寫,因此讀者需要有相關的知識來理解本章接下來的內...

MySQL MDL,元資料鎖的粒度

mysql server層定義了如下的元資料鎖的粒度,這些鎖較多,超出了讀鎖和寫鎖兩種鎖粒度,這是因為讀鎖和寫鎖通常是理論上根據概念 的範疇,而在工程實踐中會根據實際情況進行細化,以最大限度地提高併發度。type of metadata lock request.sa comments for md...