掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
| Attribute | 值 |
|---|---|
| 產(chǎn)品名稱 | SQL Server |
| 事件 ID | 701 |
| 事件源 | MSSQLSERVER |
| 組件 | SQLEngine |
| 符號(hào)名稱 | NOSYSMEM |
| 消息正文 | 系統(tǒng)內(nèi)存不足,無(wú)法運(yùn)行此查詢。 |
注意

本文側(cè)重介紹 SQL Server。 有關(guān) Azure SQL 數(shù)據(jù)庫(kù)中的內(nèi)存不足問(wèn)題的疑難解答,請(qǐng)參閱排查 Azure SQL 數(shù)據(jù)庫(kù)的內(nèi)存不足錯(cuò)誤。
當(dāng)SQL Server未能分配足夠的內(nèi)存來(lái)運(yùn)行查詢時(shí),會(huì)發(fā)生錯(cuò)誤 701。 造成內(nèi)存不足的因素可能有很多,包括操作系統(tǒng)設(shè)置、物理內(nèi)存可用性、其他組件在 SQL Server 內(nèi)使用內(nèi)存或當(dāng)前工作負(fù)荷存在內(nèi)存限制。 大多數(shù)情況下,失敗的事務(wù)不是引發(fā)此錯(cuò)誤的原因。 總的來(lái)說(shuō),原因可以分為三類:
外部壓力是指進(jìn)程外部的組件的內(nèi)存利用率較高,導(dǎo)致 SQL Server 內(nèi)存不足。 必須查明系統(tǒng)上的其他應(yīng)用程序是否正在消耗內(nèi)存,導(dǎo)致內(nèi)存可用性較低。 SQL Server 是設(shè)計(jì)用于通過(guò)減少內(nèi)存使用量來(lái)應(yīng)對(duì)操作系統(tǒng)內(nèi)存壓力的為數(shù)不多的應(yīng)用程序之一。 這意味著,如果某個(gè)應(yīng)用程序或驅(qū)動(dòng)程序請(qǐng)求內(nèi)存,操作系統(tǒng)將向所有應(yīng)用程序發(fā)送一個(gè)釋放內(nèi)存的信號(hào),SQL Server 將通過(guò)減少其自身的內(nèi)存使用量來(lái)做出響應(yīng)。 很少有其他應(yīng)用程序做出響應(yīng),因?yàn)樗鼈儾挥糜趥陕?tīng)該通知。 因此,如果 SQL 開(kāi)始減少其內(nèi)存使用量,則其內(nèi)存池也會(huì)減小,任何需要內(nèi)存的組件都可能無(wú)法獲取它。 你將開(kāi)始收到 701 和其他與內(nèi)存相關(guān)的錯(cuò)誤。 有關(guān)詳細(xì)信息,請(qǐng)參閱 SQL Server 內(nèi)存體系結(jié)構(gòu)
內(nèi)部?jī)?nèi)存壓力是指由 SQL Server 進(jìn)程內(nèi)部的因素導(dǎo)致的低內(nèi)存可用性。 SQL Server 進(jìn)程內(nèi)部運(yùn)行的某些組件可能是 SQL Server 引擎的“外部”組件。 示例包括鏈接服務(wù)器、SQLCLR 組件、擴(kuò)展過(guò)程 (XP) 和 OLE 自動(dòng)化 (sp_OA*) 等 DLL。 其他示例包括防病毒或其他安全程序,它們將 DLL 注入進(jìn)程中以用于監(jiān)視目的。 這些組件中的任何組件出現(xiàn)問(wèn)題或設(shè)計(jì)不佳都可能導(dǎo)致消耗大量?jī)?nèi)存。 例如,考慮鏈接服務(wù)器,該服務(wù)器將來(lái)自外部源的 2000 萬(wàn)行數(shù)據(jù)緩存到 SQL Server 內(nèi)存中。 就 SQL Server 而言,內(nèi)存分配器不會(huì)報(bào)告高內(nèi)存使用率,但 SQL Server 進(jìn)程內(nèi)部消耗的內(nèi)存將會(huì)很高。 例如,鏈接服務(wù)器 DLL 的此內(nèi)存增長(zhǎng)會(huì)導(dǎo)致 SQL Server 開(kāi)始減少其內(nèi)存使用量(見(jiàn)上文),并造成 SQL Server 內(nèi)部的組件內(nèi)存不足,從而導(dǎo)致類似 701 的錯(cuò)誤。
來(lái)自 SQL Server 引擎內(nèi)部的組件的內(nèi)部?jī)?nèi)存壓力也可能導(dǎo)致錯(cuò)誤 701。 有數(shù)百個(gè)組件在 SQL Server 中分配內(nèi)存,這些組件通過(guò)內(nèi)存分配器跟蹤。 必須確定哪些內(nèi)存分配器負(fù)責(zé)最大的內(nèi)存分配,才能進(jìn)一步解決此問(wèn)題。 例如,如果發(fā)現(xiàn) OBJECTSTORE_LOCK_MANAGER 內(nèi)存分配器顯示較大內(nèi)存分配,則需要進(jìn)一步了解鎖管理器消耗如此多內(nèi)存的原因。 你可能會(huì)發(fā)現(xiàn),有些查詢會(huì)獲取大量的鎖,請(qǐng)使用索引對(duì)其進(jìn)行優(yōu)化,或減少長(zhǎng)時(shí)間持有鎖的事務(wù),或檢查是否禁用了鎖升級(jí)。 每個(gè)內(nèi)存分配器或組件都有一種獨(dú)特的方式來(lái)訪問(wèn)和使用內(nèi)存。 有關(guān)詳細(xì)信息,請(qǐng)參閱內(nèi)存分配器類型及其說(shuō)明。
如果偶爾或者短暫出現(xiàn)錯(cuò)誤 701,則可能存在可自行解決的短期內(nèi)存問(wèn)題。 在這些情況下,你可能不需要采取任何措施。 但是,如果錯(cuò)誤在多個(gè)連接上多次出現(xiàn),并且持續(xù)數(shù)秒或更長(zhǎng)時(shí)間,請(qǐng)按照以下步驟進(jìn)行進(jìn)一步的故障排除。
下面的列表概述了有助于解決內(nèi)存錯(cuò)誤的一般步驟。
允許收集故障排除數(shù)據(jù)的診斷工具包括性能監(jiān)視器、sys.dm_os_memory_clerks 和 DBCC MEMORYSTATUS 。
使用性能監(jiān)視器配置和收集以下計(jì)數(shù)器:
在受影響的 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
自動(dòng)捕獲這些數(shù)據(jù)點(diǎn)的另一種方式是使用 PSSDIAG 或 SQL LogScout 等工具。
以下各部分介紹了每種方案(外部或內(nèi)部?jī)?nèi)存壓力)的更詳細(xì)步驟。
若要診斷 SQL Server 進(jìn)程外部系統(tǒng)上的內(nèi)存不足情況,請(qǐng)收集性能監(jiān)視器計(jì)數(shù)器。 通過(guò)查看這些計(jì)數(shù)器,調(diào)查除 SQL Server 之外的應(yīng)用程序或服務(wù)是否正在消耗此服務(wù)器上的內(nèi)存:
下面是使用 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)) }
}
}
查看系統(tǒng)事件日志,查找與內(nèi)存相關(guān)的錯(cuò)誤(例如,虛擬內(nèi)存不足)。
查看應(yīng)用程序事件日志,了解與應(yīng)用程序相關(guān)的內(nèi)存問(wèn)題。
下面是一個(gè)示例 PowerShell 腳本,用于查詢關(guān)鍵字“memory”的 System 和 Applicaiton 事件日志。 隨意使用其他字符串(如“resource”)進(jìn)行搜索:
Get-EventLog System -ComputerName "$env:COMPUTERNAME" -Message "*memory*"
Get-EventLog Application -ComputerName "$env:COMPUTERNAME" -Message "*memory*"
解決不太關(guān)鍵的應(yīng)用程序或服務(wù)的任何代碼或配置問(wèn)題,以減少其內(nèi)存使用量。
如果除SQL Server之外的應(yīng)用程序消耗資源,請(qǐng)嘗試停止或重新安排這些應(yīng)用程序,或考慮在單獨(dú)的服務(wù)器上運(yùn)行它們。 這些步驟將消除外部?jī)?nèi)存壓力。
若要診斷 SQL Server 內(nèi)部的模塊 (DLL) 導(dǎo)致的內(nèi)部?jī)?nèi)存壓力,請(qǐng)使用以下方法:
如果 SQL Server 未使用鎖定內(nèi)存頁(yè) (AWE API),那么它的大部分內(nèi)存都將反映在性能監(jiān)視器的“Process:Private Bytes”計(jì)數(shù)器(SQLServr 實(shí)例)中。 SQL Server 引擎中的總體內(nèi)存使用情況反映在“SQL Server:Memory Manager: Total Server Memory (KB)”計(jì)數(shù)器中。 如果發(fā)現(xiàn)值“Process:Private Bytes”和“SQL Server:Memory Manager: Total Server Memory (KB)”之間存在顯著差異,則這種差異可能來(lái)自 DLL(鏈接服務(wù)器、XP、SQLCLR 等) 。 例如,如果“Private bytes”為 300 GB,而“Total Server Memory”為 250 GB,則進(jìn)程中大約 50 GB 的總內(nèi)存來(lái)自 SQL Server 引擎外部 。
如果 SQL Server 使用鎖定內(nèi)存頁(yè) (AWE API),那么確定問(wèn)題將更具挑戰(zhàn)性,因?yàn)樾阅鼙O(jiān)視器不提供跟蹤單個(gè)進(jìn)程的內(nèi)存使用情況的 AWE 計(jì)數(shù)器。 SQL Server 引擎中的總體內(nèi)存使用情況反映在“SQL Server:Memory Manager: Total Server Memory (KB)”計(jì)數(shù)器中。 典型的“Process:Private Bytes”值可能在 300 MB 和 1-2 GB 之間變化。 如果發(fā)現(xiàn)“Process:Private Bytes”的使用量顯著超過(guò)此典型使用量,則差異可能來(lái)自 DLL(鏈接服務(wù)器、XP、SQLCLR 等)。 例如,如果“Private bytes”計(jì)數(shù)器為 5-4 GB,并且 SQL Server 使用了鎖定內(nèi)存頁(yè) (AWE),則大部分專用字節(jié)可能來(lái)自 SQL Server 引擎外部。 這是一種近似技術(shù)。
使用任務(wù)列表實(shí)用工具確定 SQL Server 空間中加載的所有 DLL:
tasklist /M /FI "IMAGENAME eq sqlservr.exe"
還可以使用此查詢來(lái)檢查加載的模塊 (DLL),并查看是否存在不需要的內(nèi)容
SELECT * FROM sys.dm_os_loaded_modules
如果懷疑某個(gè)鏈接服務(wù)器模塊導(dǎo)致消耗大量?jī)?nèi)存,可以通過(guò)禁用“允許進(jìn)程內(nèi)”選項(xiàng)將其配置為在進(jìn)程外運(yùn)行。 有關(guān)詳細(xì)信息,請(qǐng)參閱創(chuàng)建鏈接服務(wù)器。 并非所有鏈接服務(wù)器 OLEDB 提供程序都可以在進(jìn)程外運(yùn)行;有關(guān)更多信息,請(qǐng)聯(lián)系產(chǎn)品制造商。
在使用 OLE 自動(dòng)化對(duì)象 (sp_OA*) 的極少數(shù)情況下,可以通過(guò)將“上下文”設(shè)置為 4 來(lái)將對(duì)象配置為在 SQL Server 外部的進(jìn)程中運(yùn)行(僅限本地 (.exe) OLE 服務(wù)器)。 有關(guān)詳細(xì)信息,請(qǐng)參閱 sp_OACreate。
開(kāi)始收集 SQL Server:SQL Server:Buffer Manager 的性能監(jiān)視器計(jì)數(shù)器,SQL Server:內(nèi)存管理器。
多次查詢 SQL Server 內(nèi)存分配器 DMV,查看引擎中內(nèi)存消耗最大的位置:
SELECT pages_kb, type, name, virtual_memory_committed_kb, awe_allocated_kb
FROM sys.dm_os_memory_clerks
ORDER BY pages_kb DESC
或者,可以在看到這些錯(cuò)誤消息時(shí)觀察更詳細(xì)的 DBCC MEMORYSTATUS 輸出及其變化情況。
DBCC MEMORYSTATUS
如果在內(nèi)存分配器中發(fā)現(xiàn)了明顯的導(dǎo)致錯(cuò)誤的因素,請(qǐng)專注于解決該組件的內(nèi)存消耗具體問(wèn)題。 下面是幾個(gè)示例:
以下操作可能會(huì)釋放一些內(nèi)存并將其提供給SQL Server:
檢查以下 SQL Server 內(nèi)存配置參數(shù),并在可能的情況下考慮增加最大服務(wù)器內(nèi)存:
max server memory
min server memory
注意不正常的設(shè)置。 根據(jù)需要更正它們。 滿足更高內(nèi)存要求。 服務(wù)器內(nèi)存配置選項(xiàng)中列出了默認(rèn)設(shè)置。
如果尚未配置最大服務(wù)器內(nèi)存(尤其是使用鎖定內(nèi)存頁(yè)),請(qǐng)考慮設(shè)置為特定值,以便為操作系統(tǒng)分配一些內(nèi)存。 請(qǐng)參閱鎖定內(nèi)存頁(yè)服務(wù)器配置選項(xiàng)。
檢查查詢工作負(fù)荷:并發(fā)會(huì)話數(shù)、當(dāng)前正在執(zhí)行的查詢,并查看是否存在可能會(huì)暫時(shí)停止或移動(dòng)到另一 SQL Server 的不太關(guān)鍵的應(yīng)用程序。
如果在虛擬機(jī) (VM) 上運(yùn)行 SQL Server,請(qǐng)確保該 VM 的內(nèi)存未過(guò)量使用。 有關(guān)如何為 VM 配置內(nèi)存的想法,請(qǐng)參閱此博客 虛擬化 – 內(nèi)存過(guò)度使用以及如何在 VM 中檢測(cè)內(nèi)存 和 排查 ESX/ESXi 虛擬機(jī)性能問(wèn)題 (內(nèi)存過(guò)度)
可以運(yùn)行以下 DBCC 命令來(lái)釋放多個(gè)SQL Server內(nèi)存緩存。
DBCC FREESYSTEMCACHE
DBCC FREESESSIONCACHE
DBCC FREEPROCCACHE
如果使用 Resource Governor,建議檢查資源池或工作負(fù)荷組設(shè)置,看看它們是否對(duì)內(nèi)存限制過(guò)大。
如果問(wèn)題仍存在,你將需要進(jìn)一步調(diào)查,可能需要增加服務(wù)器資源 (RAM)。
香港美國(guó)云服務(wù)器選創(chuàng)新互聯(lián),2H2G首月10元開(kāi)通。
創(chuàng)新互聯(lián)(www.cdcxhl.com)互聯(lián)網(wǎng)服務(wù)提供商,擁有超過(guò)10年的服務(wù)器租用、服務(wù)器托管、云服務(wù)器、虛擬主機(jī)、網(wǎng)站系統(tǒng)開(kāi)發(fā)經(jīng)驗(yàn)。專業(yè)提供云主機(jī)、虛擬主機(jī)、域名注冊(cè)、VPS主機(jī)、云服務(wù)器、香港云服務(wù)器、免備案服務(wù)器等。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問(wèn)/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流