Sql-Server

大記憶體環境中的 SQL Server TempDB 行為

  • May 8, 2020

讀完這個問題讓我想起了我不久前的一個問題。

我們有一個 512GB 記憶體的 SQL Server,主數據庫是 450GB。我們在 TempDB 中看到了很多動作(好吧,我認為這是“相當多的動作”——它可能不是!)。我安裝了 RamDisk Plus Server 的展示版,創建了一個 50GB 的 ramdrive,將 TempDB 指向它,但性能完全沒有改善。

對 TempDB 的寫入是否總是會導致對磁碟的實際物理寫入,或者 TempDB 寫入是否由 SQL Server 記憶體以用於延遲寫入,就像在 Windows 文件系統記憶體中一樣?

在這種情況下,ramdisk 沒有意義嗎?

我知道 SQL Server 6.5 支持 TempDB-In-Ram,但我看到很久以前就停止了!

對 TempDB 的寫入是否總是會導致對磁碟的實際物理寫入,或者 TempDB 寫入是否由 SQL Server 記憶體以用於延遲寫入,就像在 Windows 文件系統記憶體中一樣?

他們總是嗎?絕對不是。他們有嗎?是的,但不是典型機制的結果。這裡的參考是檢查點對 tempdb 有什麼作用?.

在“行為良好”的系統中,對使用者數據庫文件的寫入發生在檢查點上。在表現不佳的系統中,當lazywriter 需要從緩衝池中刷新頁面以為其他頁面騰出空間時,也會發生寫入。

僅當 tempdb 日誌文件已滿 70% 時才會為 tempdb 執行檢查點 - 這是為了盡可能防止 tempdb 日誌增長(請注意,長時間執行的事務實際上仍然可以將日誌作為人質並阻止其清除,就像在使用者數據庫中一樣)。

但是沒有必要將 tempdb 刷新到磁碟,因為崩潰恢復永遠不會在 tempdb 上執行,它總是在啟動時重新創建。

Tempdb 在發生崩潰時不會恢復,因此無需將臟 tempdb 頁面強制寫入磁碟,除非lazywriter 程序(緩衝池的一部分)必須為其他數據庫的頁面騰出空間。

這很明顯(令我驚訝)是將 tempdb 頁面寫入磁碟的唯一機制。如果存在緩衝池壓力,則可能會將 tempdb 頁面刷新到磁碟。如果沒有,它不應該發生。

編輯:對於在檢查點之外寫入頁面的使用者數據庫,“行為不端”是否是適當的描述存在爭議。不尋常的,非典型的,或者只是不理想?

附加編輯(在評論/與@PaulWhite 聊天之後):

上面明顯的遺漏是臨時表不是 tempdb 流量的唯一來源。引用理解散列、排序和交換溢出事件

某些 SQL Server 查詢執行操作經過校準,可通過使用(有點)大量記憶體作為中間儲存來實現最佳性能。查詢優化器將使用此記憶體暫存器根據這些運算符選擇一個計劃並估算成本。但這當然只是一個估計。在執行時,估計可能被證明是錯誤的,儘管沒有足夠的記憶體,但計劃必須繼續。在這種情況下,這些運算符會溢出到磁碟。

我錯誤地認為溢出操作的物理寫入背後的機制與前面描述的完全相同,即由於緩衝池的壓力(由溢出引起),lazywriter 將 tempdb 頁面強制寫入磁碟。

@PaulWhite 解釋了我錯在哪裡(感謝保羅!):

我認為您在問為什麼當查詢超出其工作空間記憶體授權時會發生物理 tempdb 活動,而不是僅使用 tempdb-in-memory 如果這樣做,查詢將使用比其授權更多的記憶體,從而破壞了限制記憶體的點贈款放在首位。

溢出在寫入到儲存方面確實很特別。在溢出時可以看到物理 tempdb 活動,即使面對大量可用記憶體和 tempdb 上的零壓力也是如此。

Paul 還向我介紹了他的部落格文章Advanced TSQL Tuning: Why Internals Knowledge Matters,其中包括用於展示溢出的範例腳本,供那些想要深入研究的人使用。

引用自:https://dba.stackexchange.com/questions/23656