平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“SQL Server数据库服务器内存问题排查及解决方案”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。
前言
在这个场景下,最近我公众号小伙伴反馈数据库服务器爆满如何处理!下面我详细解答一下处理方案和预防方案。
理解这一步时,SQL Server数据库服务器内存占用高是普遍情况,不用过于紧张,因为几乎所有涉及的数据库为了加快数据库的执行效率都会缓存一部分数据到内存,如果服务器还有剩余内存,通常不用慌。如果经常内存爆满导致服务器异常那就另当别论了。
一、 立刻处理(更快释放、恢复)
清除缓存(谨慎采用,仅在紧急时)这会清空缓存,可能导致瞬间性能波动,业务低峰期操作。
DBCC FREESYSTEMCACHE ('ALL');
DBCC FREEPROCCACHE; 杀掉阻塞/耗时查询先找出耗资源的会话,手动 Kill。
-- 查看耗时且占用高的会话(为啥限制大于50是因为2005之前系统会话ID都小于等于50)
SELECT session_id, status, command, wait_type
FROM sys.dm_exec_requests
WHERE session_id > 50;
-- 杀掉会话(替换 SPID)注意一定不要误杀 有些属于系统会话(比如写日志、清理)
KILL 56;
二、 根源排查
确认内存采用情况
-- 查看数据库内存使用
SELECT
(physical_memory_in_use_kb / 1024) AS SQL_Server_Used_Memory_MB,
(locked_page_allocations_kb / 1024) AS SQL_Server_Locked_Pages_MB,
(total_virtual_address_space_kb / 1024) AS Total_Virtual_Address_Space_MB,
process_physical_memory_low,
process_virtual_memory_low
FROM sys.dm_os_process_memory;
--查看服务器内存使用
SELECT
(total_physical_memory_kb / 1024) AS Total_OS_Memory_MB,
(available_physical_memory_kb / 1024) AS Available_OS_Memory_MB,
system_memory_state_desc
FROM sys.dm_os_sys_memory;
结论:如果 Available_OS_Memory_MB 还很大,说明这只是SQL占满了缓冲池,是正常现象;如果可用内存极少,服务器甚至Swap分区爆满,才需紧急优化。*
落到代码里,顺便提一下,不要采用任务管理器来查看 SQL Server 的内存采用情况,它显示的值往往不准确。这是因为如果 SQL Server 启用了“锁定内存页”权限,大部分内存分配会借助 AWE API 进行,这部分内存不会在任务管理器的“进程私有字节”中显示,从而导致你看不到真实的内存占用。采用上述 DMV 查询才能获得准确的数据。
定位是谁在“吃内存”
-- 按数据库统计内存占用
SELECT
DB_NAME(database_id) AS DatabaseName,
COUNT(*) * 8/1024 AS CacheSize_MB
FROM sys.dm_os_buffer_descriptors
GROUP BY DB_NAME(database_id)
ORDER BY CacheSize_MB DESC;
GO
三、 永久优化方案(稳定运行)
设置最大内存(关键!)防止SQL Server抢光系统内存导致Windows或其他服务挂掉。
sp_configure 'show advanced options', 1; RECONFIGURE;
sp_configure 'max server memory (MB)', 32768; -- 假设机器64G,留32G给系统和其他程序
RECONFIGURE;
索引与查询优化内存高大多是因为全表查询、缺失表索引、滥用函数、查询大字段数据导致的。
-- 检查碎片
DBCC SHOWCONTIG ('表名');
-- 重组(碎片<30%)或重建(碎片>30%)
ALTER INDEX ALL ON 表名 REBUILD;
重建/重组索引:
清理执行计划缓存:解决参数嗅听问题。
DBCC FREEPROCCACHE;
四、 监控预警建议
建议在服务器上建个作业,每天自动检查内存,超了发邮件/短信提醒:
-- 简单的内存告警检查脚本
DECLARE @UsedMB INT;
SELECT @UsedMB = (physical_memory_in_use_kb/1024) FROM sys.dm_os_process_memory;
IF @UsedMB > 40000 -- 阈值,根据你机器配置调整
BEGIN
-- 这里可以调用存储过程发送邮件通知
PRINT '警告:SQL Server内存占用已超过阈值!当前使用:' + CAST(@UsedMB AS VARCHAR) + ' MB';
END;
核心思路:SQL Server吃内存是为了快理解这一步时,。只要不导致服务器卡顿、不报错,高内存借助率反而是服务器设置在物尽其用。
到此这篇关于SQL Server数据库服务器内存问题排查的文章就介绍到这了,更多相关SQL Server服务器内存问题内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!
- 腾讯云Windows云服务器自建Sql Server限制内存的操作步骤
- SQL server数据库log日志过大占用内存大的解决办法
- SQL Server内存机制详解
- SQL Server 2008 R2占用cpu、内存越来越大的两种解决方法
- SQL语句实现查询SQL Server内存采用状况
- 揭秘SQL Server 2014有哪些新特性(1)-内存数据库
- 浅谈SQL Server 对于内存的管理[图文]
- SQL Server 数据页缓冲区的内存瓶颈分析
- 优化SQL Server的内存占用之执行缓存
- 解决SQL Server虚拟内存不足情况