我们在使用 MS Sql 2008 R2 时遇到了内存问题。似乎存在内存泄漏,内存使用量不断增加,直到达到约 1.5 GB 后才停止。
我们已使用以下脚本尝试找出导致问题的数据库。但是,结果中似乎没有找到与特定数据库相关的任何证据。定位此类问题的最佳做法是什么?
-- Note: querying sys.dm_os_buffer_descriptors
-- requires the VIEW_SERVER_STATE permission.
DECLARE @total_buffer INT;
SELECT @total_buffer = cntr_value
FROM sys.dm_os_performance_counters
WHERE RTRIM([object_name]) LIKE '%Buffer Manager'
AND counter_name = 'Total Pages';
;WITH src AS
(
SELECT
database_id, db_buffer_pages = COUNT_BIG(*)
FROM sys.dm_os_buffer_descriptors
--WHERE database_id BETWEEN 5 AND 32766
GROUP BY database_id
)
SELECT
[db_name] = CASE [database_id] WHEN 32767
THEN 'Resource DB'
ELSE DB_NAME([database_id]) END,
db_buffer_pages,
db_buffer_MB = db_buffer_pages / 128,
db_buffer_percent = CONVERT(DECIMAL(6,3),
db_buffer_pages * 100.0 / @total_buffer)
FROM src
ORDER BY db_buffer_MB DESC;
答案1
如果这是一个专用的 SQL Server 框,没有运行复制、没有运行 DTS/SSIS,也没有运行任何其他需要大量专用字节的进程(根据 perfmon.msc 的进程计数器),那么首先,以 MB 为单位获取总物理内存(如果不确定,请运行 msinfo32.exe),将该数字乘以 0.8,将结果四舍五入为整数,然后在查询窗口中运行:
EXEC sp_configure'最大服务器内存(MB)','结果'
其中“结果”是刚刚计算的整数。
目前,请确保 SQL Server 启动帐户已不是被赋予了“锁定内存中的页面”权限(通过 gpedit.msc)。
如果还有其他进程需要大量专用字节,则需要进一步减少最大服务器内存。最大服务器内存减少得越多,SQL Server 用于缓存磁盘 IO(和其他缓存需求)的内存就越少,因此 SQL Server 变得比可接受的速度慢的风险就越大。增加更多内存可能是一个可行的选择(尤其是考虑到 1.5 GB RAM 的成本)。
调整最大服务器内存后,使用 perfmon.msc 监视进程对象的专用字节数和虚拟字节数计数器、内存对象的可用兆字节数计数器以及 SQL Server 内存管理器对象的目标服务器内存和总服务器内存计数器。使用 5-15 秒轮询间隔,并保持 perfmon 运行直至出现问题,一旦出现问题,停止 perfmon 并检查其结果。当系统的可用兆字节数下降到 ~4-5 MB 时,SQL Server 预计会降低其目标服务器内存,其总服务器内存会跟随该目标。
32 位进程(例如 32 位 SQL Server)无法处理超过 2 GB 的物理内存,除非使用 AWE。64 位 SQL Server 可以处理比您能承受的更多的内存 :)。
最后,请进一步说明“服务崩溃”的含义。崩溃时,SQL Server 的错误日志会报告什么?崩溃时,Windows 的系统事件日志会报告什么?