簡單介紹SQL Server中的自旋鎖_MsSql

來源:互聯網
上載者:User

為什麼我們需要自旋鎖?
用閂鎖同步多個線程間資料結構訪問,在每個共用資料結構前都放置一個閂鎖沒有意義的。閂鎖與此緊密關聯:當你不能獲得閂鎖(因為其他人已經有一個不相容的閂鎖拿到),查詢就會強制等待,並進入掛起(SUSPENDED)狀態。查詢在掛起狀態等待直到可以拿到閂鎖,然後就會進入可執行(RUNNABLE)狀態。對於查詢執行只要沒有可用的CPU,查詢就一直在可執行(RUNNABLE)狀態。一旦CPU有空閑,查詢會進入運行(RUNNING)狀態,最後成功擷取到閂鎖,用它來保護訪問的共用資料結構。下圖展示了SQLOS對協調線程調度實現的狀態機器。

因為太多關聯的閂鎖,對“忙碌”資料結構使用閂鎖保護沒有意義。因此SQL Server實現所謂自旋鎖(Spinlocks)。自旋鎖就像一個閂鎖,儲存引擎使用的一個輕量級同步對象,用來同步對共用資料結構線程訪問。和閂鎖的主要區別是你積極等待自旋鎖——不離開CPU。在自旋鎖上的“等待”總會發生在運行(RUNNING)狀態的CPU。在你閉合迴圈裡旋轉直到獲得自旋鎖。這就是所謂的忙碌等待(busy wait)。自旋鎖的最大優點是當查詢在自旋鎖上等待時,不會涉及到環境切換。另一方面忙碌等待浪費CPU周期,其他查詢也許能對它們更有效使用。

為了避免太多的CPU周期浪費,SQL Server 2008 R2及後續版本實現所謂的指數補償機制(exponential backoff mechanism),那裡在CPU上一些時間的休眠後,線程停止旋轉。線上程進入休眠期間,增加了嘗試獲得自旋鎖的逾時。這個行為可以降低對CPU效能的影響。

(補充說明:Spinlock中文可以稱為自旋鎖。它是一個輕量級的,使用者態的同步對象,和critical section類似,但是粒度比前者小多了。它主要用來保護某些特定的記憶體對象的多線程並發訪問。Spinlock是排他性的。一次只能一個線程擁有。

Spinlock的設計目標是非常快和高效率。Spinlock內部如何工作呢?它首先試圖獲得某個對象的鎖,如果目標被其它線程佔有,就在那裡輪詢(spin)一定時間。如果還得不到鎖,就sleep一小會,然後繼續spin。反覆這個過程直到得到對象的佔有權。)

自旋鎖與故障排除
對自旋鎖故障排除的主要DMV是 sys.dm_os_spinlock_stats。這個DMV裡返回的每一行都代表SQL Server裡的一個自旋鎖。SQL Server 2014實現了262個不同自旋鎖。我們來詳細看下這個DMV裡的各個列:

name:自旋鎖名稱
collision:當嘗試訪問保護的資料結構時,被自旋鎖阻塞的線程次數
spins:在迴圈裡嘗試獲得自旋鎖的自旋鎖線程次數
spins_per_collision:旋轉和碰撞之間的比率
sleep_time:因為退避線程休眠時間
backoffs:為了其他線程在CPU上繼續,線程退避次數
在這個DMV裡最重要的列是backoffs,對於特定的自旋鎖類型,這列告訴你退避發生頻率。高頻率的退避會屈服於CPU消耗引起SQL Server裡的自旋鎖競爭(Spinlock Contention)。我就見過一個32核的SQL Server伺服器,CPU運行在100%而不進行任何工作——典型的自旋鎖競爭癥狀。

對自旋鎖問題進行故障排除你可以使用擴充事件提供的sqlos.spinlock_backoff。當退避(backoff)發生時,就會觸發這個擴充事件。如果你捕獲了這個事件,你還要保證你使用非常好的選擇性謂語,因為在SQL Server裡退避會經常發生。一個好的謂語可以是特定的自旋鎖類型,通過剛才提到的DMV你已經看到。下列代碼給你展示了如何建立這樣的擴充事件會話。


 -- Retrieve the type value for the LOCK_HASH spinlock. -- That value is used by the next XEvent session SELECT * FROM sys.dm_xe_map_values WHERE name = 'spinlock_types' AND map_value = 'LOCK_HASH' GO  -- Tracks the spinlock_backoff event CREATE EVENT SESSION SpinlockContention ON SERVER  ADD EVENT sqlos.spinlock_backoff( ACTION (  package0.callstack )  WHERE (  [type] = 129 -- <<< Value from the previous query )) ADD TARGET package0.histogram (  SET source = 'package0.callstack', source_type = 1 ) GO

從代碼裡可以看到,這裡我在呼叫堆疊(callstack)上使用了長條圖(histogram)目標來bucktize。因此對於特定的自旋鎖,你可以可能到SQL Serve裡產生的最高退避(backoffs)代碼路徑。你甚至可以通過啟用3656跟蹤標記(trace flag)來標識呼叫堆疊。這裡你可以看到來自這個擴充會話的輸出:

sqldk.dll!XeSosPkg::spinlock_backoff::Publish+0x138
sqldk.dll!SpinlockBase::Sleep+0xc5
sqlmin.dll!Spinlock<129,7,1>::SpinToAcquireWithExponentialBackoff+0x169
sqlmin.dll!lck_lockInternal+0x841
sqlmin.dll!XactWorkspaceImp::GetSharedDBLockFromLockManager+0x18d
sqlmin.dll!XactWorkspaceImp::GetDBLockLocal+0x15b
sqlmin.dll!XactWorkspaceImp::GetDBLock+0x5a
sqlmin.dll!lockdb+0x4a sqlmin.dll!DBMgr::OpenDB+0x1ec
sqlmin.dll!sqlusedb+0xeb
sqllang.dll!usedb+0xb3
sqllang.dll!LoginUseDbHelper::UseByMDDatabaseId+0x93
sqllang.dll!LoginUseDbHelper::FDetermineSessionDb+0x3e1
sqllang.dll!FRedoLoginImpl+0xa1b
sqllang.dll!FRedoLogin+0x1c1
sqllang.dll!process_request+0x3ec
sqllang.dll!process_commands+0x4a3
sqldk.dll!SOS_Task::Param::Execute+0x21e
sqldk.dll!SOS_Scheduler::RunTask+0xa8
sqldk.dll!SOS_Scheduler::ProcessTasks+0x279
sqldk.dll!SchedulerManager::WorkerEntryPoint+0x24c
sqldk.dll!SystemThread::RunWorker+0x8f
sqldk.dll!SystemThreadDispatcher::ProcessWorker+0x3ab
sqldk.dll!SchedulerManager::ThreadEntryPoint+0x226

使用提供呼叫堆疊,不難找出自旋鎖競爭發生的地方。在那個指定的笤俑堆棧裡競爭發生在LOCK_HASH自旋鎖類型裡,它是保護鎖管理器的雜湊表。每次在鎖管理器裡加鎖或解鎖被執行時,自旋鎖必須在對應的雜湊桶裡獲得。如你所見,在呼叫堆疊裡,當從XactWorkspacelmp類調用GetSharedDBLockFromLockManager函數時,自旋鎖被獲得。這表示當競爭到資料庫時,共用資料庫鎖被嘗試擷取。最後在用很高的退避(backoffs)的LOCK_HASH自旋鎖裡,這屈服於自旋鎖競爭。

以上就是本文的全部內容,希望對大家的學習有所協助。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.