Sql-Server

當 SQL Server 沒有可用的物理記憶體時會發生什麼?

  • September 5, 2019

在Google搜尋時,我發現了一些相互矛盾的資訊。

一些站點指出,當沒有為數據留下物理記憶體時,SQL Server 會將已經存在的數據移動​​到 TEMPDB 中(請參閱:SQL Server:揭秘 TempDb 和建議)。

但是其他站點指出,當沒有足夠的物理記憶體時,作業系統可以使用 PAGE FILE 並將數據從物理記憶體移動到它(請參閱SQL Server 的頁面文件)。

我想知道當 SQL Server 用完物理記憶體時,它會在哪裡寫入數據?到 tempdb 還是到 OS Page 文件?或者也許他們兩個?

當沒有為數據留下物理記憶體時,SQL Server 將已經存在的數據移動​​到 TEMPDB

您連結到的文章充其量是誤導性的,並且在某些地方是不正確的。我認為作者試圖過度簡化一些複雜的事情,這樣做有點過頭了。

SQL Server 不會以這種方式將數據從記憶體(緩衝池)移動到 tempdb。它使用“最近最少使用”的記憶體策略(通常),因此如果存在記憶體壓力,並且需要將新數據拉入記憶體,SQL Server 將從緩衝池中踢出 LRU 數據以容納新數據。這種行為通常由名為“Page Life Expectancy”(PLE)的性能計數器監控:

PLE 的定義是讀入緩衝池的數據文件頁面(數據文件頁面的記憶體記憶體)在被擠出記憶體為不同的數據騰出空間之前將保留在記憶體中的預期時間,以秒為單位文件頁面。考慮 PLE 的另一種方法是即時測量緩衝池上的壓力,以便為從磁碟讀取的頁面騰出可用空間。對於這兩個定義,數字越大越好。

在查詢執行期間,SQL Server可以將 tempdb 用於某些操作。如果估計不好,通常會這樣做,但可用記憶體不足會影響此行為。

可以以這種方式“溢出”到 tempdb 的一些操作是散列行(用於連接或聚合等)、對記憶體中的行進行排序以及在並行查詢執行期間緩衝行。

使用者查詢還可以顯式使用 tempdb(使用全域或本地臨時表),並隱式使用 tempdb(使用快照或讀取送出的快照隔離級別)。

這些情況似乎都不符合您引用的陳述。

當沒有足夠的物理記憶體時,作業系統可以使用 PAGE FILE 並將數據從物理記憶體移動到它

這肯定會發生,並且大部分情況下不在 SQL Server 的控制範圍內。您可以轉動一個旋鈕來嘗試防止某些類型的作業系統級分頁,即打開“記憶體中的鎖定頁面”(LPIM)

此 Windows 策略確定哪些帳戶可以使用程序將數據保存在物理記憶體中,從而防止系統將數據分頁到磁碟上的虛擬記憶體中。

那麼我們可以防止被分頁到磁碟呢?

在 SQL Server 2012 之前,通過稱為“單頁分配器”的組件分配的頁面被鎖定在記憶體中(無法分頁)。這包括緩衝池(數據庫頁)、過程高速記憶體和其他一些記憶體區域。

有關詳細資訊,請參閱Fun with Locked Pages、AWE、任務管理器和工作集……,尤其是“4. 現在我知道 x64 上的 SQL Server 可以使用“鎖定頁面”,究竟鎖定了什麼?”部分。其他相關閱讀可以在這裡找到:Great SQL Server Debates: Lock Pages in Memory

在 SQL Server 2012 及更高版本中,沒有“單頁分配器”(單頁和多頁分配器已合併,根據深入了解記憶體 – SQL Server 2012/2014)。我所見過的任何地方都沒有詳細記錄可以分頁和不可以分頁的詳細資訊。您可以使用這樣的查詢查看鎖定的內容:

select osn.node_id, osn.memory_node_id, osn.node_state_desc, omn.locked_page_allocations_kb
from sys.dm_os_memory_nodes omn
inner join sys.dm_os_nodes osn on (omn.memory_node_id = osn.memory_node_id)
where osn.node_state_desc <> 'ONLINE DAC'

根據同一篇 MS Support 文章,您還可以使用DBCC MEMORYSTATUS來查看“鎖定”了多少記憶體。

附帶說明一下,您可以在錯誤日誌中看到作業系統正在分頁的 SQL Server 工作集的證據。會有如下所示的消息:

2019-09-02 10:19:27.29 spid11s sql server 程序記憶體的很大一部分已被分頁。這可能會導致性能下降。持續時間:329 秒。工作集 (KB):68780,已送出 (KB):244052,記憶體使用率:28%。

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