前言
最近我公众号小伙伴反馈数据库服务器爆满如何处理!接下来我详细解答一下处理方案和预防方案。
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;
复制代码
四、 监控预警建议
建议在服务器上建个作业,每天自动检查内存,超了发邮件/短信提醒:- -- 简单的内存告警检查脚本
- 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;
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |