擦亮自己的眼睛去看SQL Server之談談鎖機制

2020-12-17 站長之家

在談談SQL Server的鎖機制之前,來思考以下這個場景:當你在酷暑的時候騎著自己的小車往目的地行走時,路上連續遇到幾個時間很長的紅燈,是不是很鬱悶?有時候你可能實在受不了闖了個紅燈,其實在大部分情況下問題不大,如果通行的汽車很多那就不好說了。因為不遵守規則的人太多,都為了達到目的去走捷徑,不願意等待。這樣才有了交警。交警的作用就是維護這些紅綠燈的規則。這些紅綠燈就像鎖一樣,鎖住或延長你去目的地的時間。但是如果沒有交警大家又不自由遵守紅綠燈規則會導致什麼呢?大家想想都知道。

這個系列的一篇文章中提供的事務管理器中有個鎖管理器就是這裡的交警。它維護著SQLServer中的鎖。前段提到的大部分情況指的就是在系統事務量不大的時候,這時候的鎖永遠不會是什麼大問題。除非你知道你的系統永遠就給幾個人用,否則考慮到避免系統以後的並發量上升引起數據安全與效率問題,那你得深入了解鎖機制。在研究鎖之前,假定你已經了解事務的ACID概念,它是整個SQL Server的精髓所在。如果沒有事務那就不用談鎖了,除了事務需要鎖以外其他任何東西都需要這個讓SQL不自由的機制。說到底鎖是一個平衡並發與數據安全的機制,如果沒有鎖,任何SQL都能覆蓋其他SQL執行的數據,那麼數據會出現不一致的情況。如果鎖得太狠,那將影響資料庫系統的並發性以及效率(包括鎖本身帶來的額外開銷)。這時候就需要去權衡,SQLServer鎖管理器就充當權衡這兩者關係的角色,如下圖所示:

SQL Server中鎖的知識點實在太多,比如鎖從模式上分為:共享鎖(S)、更新鎖(U)、排他鎖(X)、架構鎖(Sch-S、Sch-M)、意向鎖(IS、IU、IX)、轉換鎖(SIX、SIU、UIX)、大容量更新鎖(BU);鎖從粒度上分為:資料庫鎖、文件鎖、表鎖、堆鎖、索引鎖、頁鎖、鍵鎖、區鎖、行鎖、應用程式鎖、元數據鎖;鎖之間存在兼容性問題;鎖會根據情況進行升級;鎖控制不好會出現死鎖;悲觀鎖的隔離性:未提交讀、已提交讀、可重複讀、可序列化;樂觀鎖的隔離性:讀提交快照隔離、快照隔離;閂(shuan)鎖。。。隨便列下就一大堆問題要說清楚需要花很大篇幅。還是抱著與前幾篇文章的風格,仔細分析一個具體的問題——鎖升級。

1、準備

有一個動態管理視圖可以查看所有鎖:sys.dm_tran_locks,還有一個動態管理視圖可以查看哪些請求正在阻塞其他的請求:sys.dm_os_waiting_tasks

2、什麼是鎖升級

鎖升級是指鎖的粒度由細向粗轉換。如:由行鎖轉成表鎖。

3、需要鎖升級嗎?

一般來說,鎖的粒度越小,並發性越好但是如果去鎖定的東西多就需要的鎖越多,這樣會消耗SQLServer的cpu與內存。一個鎖佔用內存約為96位元組,你算算如果用行鎖去鎖定百萬千萬的表需要多少內存。而且管理鎖(創建鎖、維護鎖、銷毀鎖等)也是有代價的,會消耗cpu。 如果用一個大點的鎖就將這些百萬千萬的鎖合併成一個鎖了,管理起來也方便消耗資源也小。

4、什麼時候出現鎖升級

SQLServer意識到鎖定的頁面或行數過大的時候發生。怎麼意識到過大呢?由兩種方法識別:請求用於的鎖的數目超過鎖數目臨界值;鎖管理器為單獨一個查詢消耗過多的內存超過內存臨界值。有其他一個超過臨界值,SQLServer就會試圖升級。注意這裡說的鎖數據以及內存是值由同一個查詢發生的,而不是總共的。這裡說的臨界值並不是固定的,SQLServer採用啟發式算法去動態調整。

5、控制鎖升級

SQLServer提供一些可以讓我們控制鎖升級的入口。在SQLServer2008中可以通過:

alter table test

set (lock_escalation = auto|table|disable)

我們還可以通過在代碼中顯示指定pagelock、tablock提示,會強制SQLServer使用更粗的鎖。不過這個設置不合理的話會導致並發降低。建議一般情況下不用,除非你很清楚這樣帶來的影響。

6、舉例說明

6.1建庫建表:

create database Test

create table test

ID identity(1,1) primary key,

[Name] varchar(50) not null default 『』,

CreatedTime datetime not null default getdate();

查看當前鎖情況:

默認某個連接對整個資料庫有個共享鎖。

6.2循環插入幾十萬條記錄:

while 1 = 1

insert into test(Name) values (『kk』)

插入時的鎖快照 :

從上圖中看出這個快照中有:三個資料庫共享鎖、一個頁級意向排他鎖、一個表級意向排他鎖、兩個行級排他鎖。

三個資料庫共享鎖:前面已經提過,默認某個連接對整個資料庫有個共享鎖;

一個頁級意向排他鎖、一個表級意向排他鎖:在頁以及表級表示資源的一部分實際已經有鎖進行保護,這樣的好處允許其他請求鎖在表頁級別上進行檢查,減少不必要的更細的鎖請求,提高性能。比如在這種情況下,如果允許alter操作那麼這個操作就會等待因為這裡有表級排他鎖,它提示alter操作該表有活動。

6.3 跟蹤Lock:Escalation事件

在profiler中設置只跟蹤Lock:Escalation事件,鎖升級事件。

6.4更新表中記錄:

update test set name = 『name』 where name = 『kk』

在profiler中看到了Lock:Escalation事件被觸發:

更新時的快照為(按順序):

如上圖:此時update操作以排他鎖定它更新的行。

如上圖:此時update操作以排他鎖鎖定了整個表,以架構穩定鎖(Sch-S)鎖定它相關的元數據表。

如上圖:此時釋放了對元數據表的架構穩定鎖(Sch-S)鎖,剩下對整個表的排他鎖。

從上面的分析中,發現SQLServer鎖機制是有點複雜的,不過也是很有意思的。研究後,你會發現它真的很智能。今天分析就到此結束,文中如有描述不當的地方,歡迎指出。共同進步才是硬道理。(來源:博客園)

相關焦點

  • SQL Server 2014
    解壓「cn_sql_server_2014_X64.iso」64位系統解壓「cn_sql_server_2014_X64.iso」。右擊「cn_sql_server_2014_X64.iso」點擊「解壓到cn_sql_server_2014_X64.iso」。
  • 不一樣的 SQL Server 日期格式化
    CONVERT 來轉換的,SQL Server 從 2012 開始增加了 FORMAT 方法,可以使用 FORMAT 來格式化日期,更標準化,更具可定製性,而且和 C# 裡的日期格式化差不多,可以直接把 C# 裡日期的格式直接拿過來用FORMAT 介紹FORMAT 適用於數字和日期類型數據的格式化,其他數據類型不支持,其他類型數據轉換請使用 CONVERT 和 CAST 去轉換。
  • SQL Server 2019安裝教程
    1、選中下載的【sql_server_2019】軟體壓縮包,滑鼠右擊選擇【解壓到sql_server_2019】。2、雙擊打開解壓後的【sql_server_2019】文件夾。3.滑鼠右擊【sql_server_2019.iso】,選擇【打開方式】-【Windows資源管理器】。
  • SQL Server 安裝步驟
    本文通過圖文並茂的形式給大家介紹了SQL server 2016 安裝步驟,非常不錯,具有參考借鑑價值,需要的朋友參考下吧。
  • MySQL和SQL Server的區別
    1、mysql支持enum,和set類型,sql server不支持
  • SQL Server 中 JSON_MODIFY 的使用
    如果是要刪除某一個屬性,把某一個屬性更新為 NULL 即可如果要增加一個 bool 類型的屬性,需要把對應的值轉換為 BIT 類型Referencehttps://docs.microsoft.com/en-us/sql/t-sql/functions/json-modify-transact-sql?
  • Windows下Laravel 7.0連接sql server - php中文網
    laravel 7.0 默認連接 mysql, 同時項目需要連接 sql servel (另一個系統應用)$users = DB::connection (『php_sqlsrv』)->select (…);
  • Cloud SQL for SQL Server:資料庫管理的最佳實踐
    執行下列 sql 語句可查看特定資料庫的所有資料庫範圍配置:USE <dbname>;GOSELECT a.在實例級,通過選擇複選框「啟用自動存儲增長」來啟用cloud sql 實例上的自動增長。在資料庫級別,啟用自動增長是資料庫所有者的責任。有關更多信息,可查看Microsoft的配置參數文檔。更新資料庫文件自動增長設置,以使用 MB 增量而不是 % 增長率。
  • 如何使用 SQL Server FILESTREAM 存儲非結構化數據?
    在SQL Server 2008之前的MSSQL早期版本中,存在各種用於存儲非結構化數據的機制。這些信息通常被以文件的形式存儲在共享文件夾中,其訪問權限被授予了某些用戶。這些文件的UNC路徑通常作為表(varchar (n))中的一列存儲於資料庫中,以便應用程式邏輯可以訪問特定的文件。但文件的安全性、管理其訪問權並對其進行維護方面存在一定問題。
  • SQL Server之索引解析(二)
    查看索引情況--dbcc show_statistics ([tablename], [indexname])--dbcc show_statistics (TestDataUnIndex, PK_TestDataUnIndex)命令詳細見https://docs.microsoft.com/zh-cn/previous-versions/s
  • 繞過SQL Server的登錄觸發器限制
    1.打開Powershell並使用自己喜歡的方式加載PowerUpSQL。下面的示例顯示了如何直接從GitHub加載PowerUpSQL。;Initial Catalog=Master;Integrated Security=True;  Application Name =MyApp"Data Source=server\instance1;Initial Catalog=Master;Integrated Security=True;  ApplicationName =MyApp"Data Source=server\instance1
  • SQL Server的Descending Indexes降序索引
    OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]) ON [PRIMARY]GO 插入測試數據DECLARE @i INT;DECLARE @sql
  • SQL Server 警報(自動化運維)
    其實,SQL Server 也可以實現自動化運維,那就是 SQL Server 代理警報!什麼是警報相信很多同學使用客戶端工具SSMS時都應該看到過,甚至專業是DBA,但是有沒有考慮它有什麼用呢?請右鍵「警報」創建一個警報,類型有事件警報、性能計數器、WMI事件,這裡我選擇「WMI事件警報」。對於性能計數器的警報很簡單,這裡就不舉例說明了。
  • InnoDB加鎖實驗
    普通記錄鎖就是之鎖定一個索引的entry, 而gap lock會鎖定一個開區間(a,b), next-key鎖是record lock和gap lock的聚合, 鎖定一個左開右閉的區間, (ab]. 這3種鎖如何鎖定, 如何確定範圍, 會在後面的試驗中講到, 這裡就先不舉例子了. III.
  • Microsoft SQL Server手注之報錯注入
    Microsoft SQL Server手注之報錯注入簡介今天主要分享下sql注入中的報錯型,在大多網上的文章會列出類似於公式的句子
  • SQL Server應用程式的高級Sql注入
    = "select * from users where username = '" + username + "' and password = '" + password + "'"; trace( "query: " + sql ); rso.open( sql, cn ); if (rso.EOF) { rso.close(); %〉
  • server sql 作業 使用專題及常見問題 - CSDN
    serverId -serverid 綁定到清單。ELSE CONCAT(msl.server_name,'\',msl.instance) END AS instance, e.script, e.message, e.error_timestampFROM monitoring.ErrorLog eJOIN inventory.MasterServerList msl ON msl.serverId = e.serverIdWHERE
  • 5分鐘學會SQL SERVER行轉列、列轉行,PIVOT操作
    本文項目地址:https://github.com/firewang/sql50參考網址:https://docs.microsoft.com/zh-cn/sql/t-sql/queries/from-using-pivot-and-unpivot
  • 【參賽作品22】關於遷移SQL server到openGauss的問題和解決
    (之所以列出相同,是為了更放心地使用)openGauss版本:1.0.1SQL server版本:2008對比以下所有內容均基於具體使用,因此將涵蓋使用中較基本方面。整體結構SQL server和openGauss同為關係型資料庫,創建資料庫和使用基本相同,當然openGauss資料庫相比其他開源資料庫主要有複合應用場景、高性能和高可用等產品特點,在不同之處基本可以解決。
  • SQL是什麼?
    今天我們先了解sql是什麼?Sql是什麼,首先我們先看sql的定義:結構化查詢語言(Structured Query Language)簡稱sql,是用於操作關係型資料庫的標準計算機語言。雖然sql是一種標準化的語言,但是各個不同的資料庫管理系統對標準的sql支持度不太一致,而且都會進行相應的擴展,例如oracle資料庫把自己擴展的sql稱為pl/sql,sql-server資料庫的稱為t-sql。不過不要急,如果我們掌握了標準SQL的核心功能,那麼所有資料庫通常都可以執行。不常用的SQL功能,就算是資料庫的擴展功能,我們查資料也能快速了解。