MSSQLSERVER_701

適用于:SQL Server (所有支援的版本)

詳細資料

屬性
產品名稱 SQL Server
事件識別碼 701
事件來源 MSSQLSERVER
元件 SQLEngine
符號名稱 NOSYSMEM
訊息文字 系統記憶體不足,無法執行此查詢。

注意

本文著重于SQL Server。 如需針對Azure SQL資料庫中記憶體不足問題進行疑難排解的資訊,請參閱針對 Azure SQL Database 的記憶體不足錯誤進行疑難排解

說明

當SQL Server無法配置足夠的記憶體來執行查詢時,就會發生錯誤 701。 記憶體不足的原因可能是許多因素,包括作業系統設定、實體記憶體可用性、其他元件在SQL Server內使用記憶體,或目前工作負載的記憶體限制。 在大部分情況下,交易失敗並非造成此錯誤的原因。 整體來說,原因可以分成三個:

外部或 OS 記憶體壓力

外部壓力是指來自進程外部的元件,導致記憶體不足而無法SQL Server的高記憶體使用率。 您必須找出系統上的其他應用程式是否耗用記憶體,並貢獻低記憶體可用性。 SQL Server是幾個應用程式之一,其設計目的是要藉由縮減其記憶體使用量來回應 OS 記憶體壓力。 這表示,如果某些應用程式或驅動程式要求記憶體,OS 會傳送訊號給所有應用程式以釋放記憶體,而SQL Server會藉由減少自己的記憶體使用量來回應。 很少其他應用程式會回應,因為它們不是設計來接聽該通知。 因此,如果 SQL 開始縮減其記憶體使用量,則會減少其記憶體集區,而且無論哪些元件都需要記憶體, 您開始收到 701 和其他記憶體相關錯誤。 如需詳細資訊,請參閱SQL Server記憶體架構

內部記憶體壓力,不是來自SQL Server

內部記憶體壓力是指SQL Server進程內因素所造成的低記憶體可用性。 有些元件可以在SQL Server進程內執行,這些元件是SQL Server引擎的「外部」。 範例包括連結的伺服器、SQLCLR 元件、XP) (擴充程式,以及 OLE Automation (sp_OA*) 。 其他套裝程式括防毒或其他安全性程式,這些程式會將 DLL 插入進程內以進行監視。 上述任何元件中的問題或設計不佳可能會導致記憶體耗用量很大。 例如,假設連結的伺服器快取來自外部來源的資料列 2 億個數據列,以SQL Server記憶體。 就SQL Server而言,沒有記憶體 Clerk 會報告高記憶體使用量,但SQL Server進程內耗用的記憶體會很高。 例如,此記憶體會從連結的伺服器 DLL 成長,會導致SQL Server開始剪下其記憶體使用量, (請參閱上述) ,並針對SQL Server內的元件建立低記憶體狀況,導致 701 之類的錯誤。

內部記憶體壓力,來自SQL Server元件 ()

內部記憶體壓力來自SQL Server引擎內的元件,也可能導致錯誤 701。 透過記憶體 Clerk追蹤數百個元件,會在 SQL Server 中配置記憶體。 您必須識別哪些記憶體 clerk () 負責最大的記憶體配置,才能進一步解決此問題。 例如,如果您發現OBJECTSTORE_LOCK_MANAGER記憶體 Clerk 顯示大型記憶體配置,您需要進一步瞭解鎖定管理員耗用太多記憶體的原因。 您可能會發現有一些查詢會取得大量的鎖定,並使用索引加以優化,或縮短長時間保留鎖定的交易,或檢查鎖定擴大是否已停用。 每個記憶體 Clerk 或元件都有唯一的存取和使用記憶體的方式。 如需詳細資訊,請參閱 記憶體 Clerk 類型 及其描述。

使用者動作

如果錯誤 701 偶爾出現或短暫出現,則可能有短期記憶體問題可自行解決。 在這些情況下,您可能不需要採取動作。 不過,如果錯誤多次發生,在多個連線上持續數秒或更長的時間,請依照步驟進一步進行疑難排解。

下列清單概述有助於針對記憶體錯誤進行疑難排解的一般步驟。

診斷工具和擷取

可讓您收集疑難排解資料的診斷工具會效能監視器sys.dm_os_memory_clerksDBCC MEMORYSTATUS

使用 效能監視器 設定並收集下列計數器:

  • 記憶體:可用 MB
  • Process:Working Set
  • Process:Private Bytes
  • SQL Server:記憶體管理員: (所有計數器)
  • SQL Server:Buffer Manager: (所有計數器)

針對受影響的SQL Server收集此查詢的定期輸出

SELECT pages_kb, type, name, virtual_memory_committed_kb, awe_allocated_kb
FROM sys.dm_os_memory_clerks
ORDER BY pages_kb DESC

Pssdiag 或 SQL LogScout

擷取這些資料點的替代方式是使用 PSSDIAGSQL LogScout之類的工具。

  • 如果您使用 Pssdiag,請將 設定為擷取 Perfmon 收集器和 自訂診斷\SQL 記憶體錯誤 收集器
  • 如果您使用 SQL LogScout,請設定 以擷取 記憶體 案例

下列各節說明每個案例的更詳細步驟 - 外部或內部記憶體壓力。

外部壓力:診斷和解決方案

  • 若要診斷SQL Server進程外部系統上的記憶體不足狀況,請收集效能監視器計數器。 查看下列計數器,調查SQL Server以外的應用程式或服務是否耗用此伺服器上的記憶體:

    • 記憶體:可用 MB
    • Process:Working Set
    • Process:Private Bytes

    以下是使用 PowerShell 的 Perfmon 記錄收集範例

    clear
    $serverName = $env:COMPUTERNAME
    $Counters = @(
       ("\\$serverName" +"\Memory\Available MBytes"),
       ("\\$serverName" +"\Process(*)\Working Set"),
       ("\\$serverName" +"\Process(*)\Private Bytes")
    )
    
    Get-Counter -Counter $Counters -SampleInterval 2 -MaxSamples 1 | ForEach-Object  {
    $_.CounterSamples | ForEach-Object 	  {
       [pscustomobject]@{
          TimeStamp = $_.TimeStamp
          Path = $_.Path
          Value = ([Math]::Round($_.CookedValue, 3)) }
    }
    }
    
  • 檢閱系統事件記錄檔,並尋找 (的記憶體相關錯誤,例如,低虛擬記憶體) 。

  • 檢閱應用程式事件記錄檔中是否有應用程式相關的記憶體問題。

    以下是範例 PowerShell 腳本,可查詢系統與應用程式事件記錄檔中的關鍵字 「memory」。 您可以隨意使用其他字串,例如「resource」 來進行搜尋:

    Get-EventLog System -ComputerName "$env:COMPUTERNAME" -Message "*memory*"
    Get-EventLog Application -ComputerName "$env:COMPUTERNAME" -Message "*memory*"
    
  • 解決較不重要應用程式或服務的任何程式碼或設定問題,以減少其記憶體使用量。

  • 如果SQL Server以外的應用程式耗用資源,請嘗試停止或重新排程這些應用程式,或考慮在另一部伺服器上執行它們。 這些步驟將會移除外部記憶體壓力。

內部記憶體壓力,不是來自SQL Server:診斷和解決方案

若要診斷模組 (DLL) 內部SQL Server所造成的記憶體壓力,請使用下列方法:

  • 如果SQL Server不是* 使用記憶體中的鎖定頁面 (AWE API) ,則大部分的記憶體都會反映在 效能監視器 中的Process:Private Bytes計數器 SQLServr (實例) 。 來自SQL Server引擎內的整體記憶體使用量會反映在SQL Server:記憶體管理員:伺服器記憶體總計 (KB) 計數器中。 如果您在Process:Private Bytes和 SQL Server:Memory Manager 值之間發現顯著差異:伺服器記憶體總計 (KB) ,則該差異可能是來自 DLL (連結伺服器、XP、SQLCLR 等) 。 例如,如果Private 位元組為 300 GB,而伺服器記憶體總計為 250 GB,則進程中大約 50 GB 的整體記憶體來自SQL Server引擎外部。

  • 如果SQL Server在記憶體 (AWE API) 中使用鎖定的頁面,則較難以識別問題,因為效能監視器不提供 AWE 計數器來追蹤個別進程的記憶體使用量。 來自SQL Server引擎內的整體記憶體使用量會反映在SQL Server:記憶體管理員:伺服器記憶體總計 (KB) 計數器中。 一般 Process:Private Bytes 值整體可能會因 300 MB 和 1-2 GB 而有所不同。 如果您發現 Process:Private Bytes 的使用量超過此一般用途,則差異可能是來自 DLL (連結的伺服器、XP、SQLCLR 等) 。 例如,如果Private bytes計數器為 5-4 GB,且SQL Server使用 [記憶體中鎖定的頁面] (AWE) ,則大部分的 Private 位元組可能來自SQL Server引擎外部。 這是近似值技術。

  • 使用 Tasklist 公用程式來識別SQL Server空間內載入的任何 DLL:

    tasklist /M /FI "IMAGENAME eq sqlservr.exe"
    
  • 您也可以使用此查詢來檢查載入的模組, (DLL) ,並查看是否有預期有專案

    SELECT * FROM sys.dm_os_loaded_modules
    
  • 如果您懷疑連結的伺服器模組造成大量的記憶體耗用量,您可以停用 [ 允許同進程 ] 選項,將其設定為用盡進程。 如需詳細資訊,請參閱 建立連結的伺服器 。 並非所有連結的伺服器 OLEDB 提供者都可能會用盡進程;如需詳細資訊,請連絡產品製造商。

  • 在極少數的情況下, () sp_OA* 使用 OLE 自動化物件,您可以藉由設定coNtext = 4 (Local (.exe) OLE server.) ,將物件設定為在SQL Server外部的進程中執行。 如需詳細資訊,請參閱 sp_OACreate

SQL Server引擎的內部記憶體使用量:診斷和解決方案

  • 開始收集 SQL Server:SQL Server:Buffer Manager的效能監視器計數器,SQL Server:記憶體管理員

  • 查詢SQL Server記憶體 Clerks DMV 多次,以查看引擎內記憶體耗用量最高的位置:

    SELECT pages_kb, type, name, virtual_memory_committed_kb, awe_allocated_kb
    FROM sys.dm_os_memory_clerks
    ORDER BY pages_kb DESC
    
  • 或者,您可以觀察更詳細的 DBCC MEMORYSTATUS 輸出,以及當您看到這些錯誤訊息時變更的方式。

    DBCC MEMORYSTATUS
    
  • 如果您識別記憶體 Clerk 之間的明確干擾,請專注于解決該元件記憶體耗用量的特定問題。 以下是數個範例:

    • 如果MEMORYCLERK_SQLQERESER加值稅IONS記憶體 Clerk 耗用記憶體,請識別使用大量記憶體授與的查詢,並透過索引加以優化、重寫 (移除 ORDER,例如) ,或套用查詢提示。
    • 如果快取大量臨機操作查詢計劃,則CACHESTORE_SQLCP記憶體 Clerk 會使用大量的記憶體。 識別無法重複使用其查詢計劃的非參數化查詢,並藉由轉換成預存程式或使用sp_executesql或使用 FORCED 參數化來參數化它們。
    • 如果物件計畫快取存放區CACHESTORE_OBJCP耗用太多記憶體,請執行下列動作:找出哪些預存程式、函式或觸發程式使用大量記憶體,並可能重新設計應用程式。 通常,這可能是因為具有數百個程式的大量資料庫或架構所造成。
    • 如果OBJECTSTORE_LOCK_MANAGER記憶體 Clerk 顯示大型記憶體配置,請識別套用許多鎖定的查詢,並使用索引加以優化。 縮短在特定隔離等級中,導致鎖定不會長時間釋放的交易,或檢查鎖定擴大是否已停用。

快速減輕可能會讓記憶體可用

下列動作可能會釋放一些記憶體,並讓它可供SQL Server使用:

  • 請檢查下列SQL Server記憶體組態參數,並盡可能考慮增加最大伺服器記憶體

    • max server memory

    • min server memory

      注意不尋常的設定, 並且視需要加以更正。 說明增加的記憶體需求。 預設設定會列在 伺服器記憶體組態選項中。

  • 如果您尚未設定 最大伺服器記憶體 ,特別是使用 [記憶體中鎖定的頁面],請考慮將 設定為特定值,以允許 OS 的某些記憶體。 請參閱 記憶體伺服器組態選項中的鎖定頁面

  • 檢查查詢工作負載:並行會話數目,目前正在執行查詢,並查看是否有較不重要的應用程式暫時停止或移至另一個SQL Server。

  • 如果您在虛擬機器上執行SQL Server (VM) ,請確定 VM 的記憶體不會過度認可。 如需如何設定 VM 記憶體的概念,請參閱此部落格虛擬化 – 過度認可記憶體,以及如何在 VM 內偵測它,以及如何針對 ESX/ESXi 虛擬機器效能問題進行疑難排解, (記憶體過度認可)

  • 您可以執行下列 DBCC 命令來釋放數個SQL Server記憶體快取。

    • DBCC FREESYSTEMCACHE

    • DBCC FREESESSIONCACHE

    • DBCC FREEPROCCACHE

  • 如果您使用 Resource Governor,建議您檢查資源集區或工作負載群組設定,並查看它們是否不會大幅限制記憶體。

  • 如果問題持續發生,您必須進一步調查,而且可能會 (RAM) 增加伺服器資源。