sqlserver latch

什麼是bool pool

sqlserver運行內存分爲兩類,一類是bool pool;一類是非bool pool.

開發人員只需要關注一點,bool pool是內存區域即可。

pin與spin

pin

pin是對對象內容的請求。可以與get一起理解 ,get是對對象的請求。

舉例有一個蛋糕切成8塊,對某個蛋糕的請求就是get,而對申請到的蛋糕具體的哪一塊就是pin。

spin

中文翻譯就是旋轉。當前進程不能獲得latch,那它會繞着cpu空轉(執行一段空循環),而不是放棄cpu。這個過程就叫spin。

什麼是latch

latch是sqlserver用來同步資源的手段。這裏的同步跟通訊裏的同步不是一個意思。如果同步跟資源兩個字,大家可以直觀理解爲——如何保證同一個資源在某個時間只能被一個東西(線程、事務等)訪問。

latch在作用上很像一個輕量鎖。latch主要作用在內存上。我們數據庫中的表,在物理上本質是由很多數據頁組成。latch就是作用於如何把頁從磁盤加載到內存中,如何在DDL訪問數據庫的時候同步資源。

當我們發起線程請求的時候,首先這個線程有可能會獲得鎖。然後找到資源對應的數據頁,獲取到該數據頁的latch以後,纔可以在該頁中繼續搜索到對應的數據行。通過這個流程可以清晰的體會到lock和latch不同的地方。

那麼如何獲取latch呢,流程就是——請求-SPIN-休眠-請求-SPIN-休眠(如此往復)。爲什麼要一直spin而不是切時間片呢?因爲如果你需要做上下文切換(context switch),那麼cpu需要保存節點信息,處理完再原換回來。這種在高併發的場景裏,會相當消耗資源,所以選擇以spin的方式,直到獲取請求的資源 。或者達到_spin_count值,此時會放棄CPU,進行短暫的休眠,再重複剛纔的動作。

latch與lock的區別

  • latch作用於內存中,lock作用於數據庫對象。
  • latch不存在死鎖,lock死鎖很正常啦。
  • latch佔用時間非常少,lock佔用時間由事務決定。

latch分類

分爲pagelatch和pageiolatch。他們又有細分,其實是根據縮寫來分爲不同的狀態。不同的場景用不用的latch保證資源同步。例如你把數據頁從磁盤讀到內存中,這時候需要加PAGELATCH_EX。如果在加載內存完之前需要訪問該數據頁(因爲加載是民異步的,所以該線程可以先去做其他事情),則該線程可以自己給自己加一個PAGELATCH_SH,先等待PAGELATCH_EX釋放再去做其他事,同時可以避免在加載完畢前有其他線程過來請求或修改該頁。

pagelatch分爲

  • PAGELATCH_DT : Destroy buffer page  latch
  • PAGELATCH_EX : Exclusive buffer page  latch
  • PAGELATCH_KP : Keep buffer page  latch
  • PAGELATCH_NL : Null buffer page latch
  • PAGELATCH_SH : Shared buffer page   latch
  • PAGELATCH_UP : Update buffer page latch

pageiolatch細分爲

  • PAGEIOLATCH_DT : Destroy buffer page I/O latch
  • PAGEIOLATCH_EX : Exclusive buffer page I/O latch。如果出現在這個狀態,表示正在將disk中的數據頁加載到內存
  • PAGEIOLATCH_KP : Keep buffer page I/O latch
  • PAGEIOLATCH_NL : Null buffer page I/O latch
  • PAGEIOLATCH_SH : Shared buffer page I/O latch。如果出現在這個狀態,表示在加載數據頁到內存期間,試圖讀取內存中的數據頁,此時加載數據頁的過程沒有完成,處於loading狀態。如果經常出現PageIOLatch_SH,表明Loading數據頁的時間太長,可能出現IO bottleneck。
  • PAGEIOLATCH_UP : Update buffer page I/O latch

 

pagelatch和pageiolatch的區別

pagelatch是爲了保證page在buff pool中讀寫正確。例如,往數據頁中插入數據是從空閒位置開始往後寫入。若現在有一個數據頁A,現在有兩個線程都想往頁A裏插入數據。如果沒有pagelatch,那麼大家在同一時間讀取到的空閒位置都是相同的。那麼兩個線程在寫入的時候,後寫入的線程會把先寫入的線程寫入的東西覆蓋。

pageiolatch是爲了保證異步訪問數據的時候保證數據的一致性。最多的情況就是把數據頁從disk加存到memory時。sql server會首先在內存中爲這個page空出一塊空間,並且加上PAGEIOLATCH_EX ,然後在這個page真正從disk讀取到內存當中之前,其他線程不能對這片內存進行操作。因爲異步操作,所以這個線程會去訪問這個page,此時申請PAGEIOLATCH_SH ,但是與之前的PAGEIOLATCH_EX ,最終導致自己被自己阻塞了。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章