Troubleshooting SQL Server RESOURCE_SEMAPHORE Waittype Memory Issues
前言: 本文是对博客https://www.mssqltips.com/sqlservertip/2827/troubleshooting-sql-server-resourcesemaphore-waittype-memory-issues/的翻译,本文基本直译,部分地方读起来有点不自然。 如有翻译不对或不好的地方,敬请指出,大家一起学习进步。尊重原创和翻译劳动成果,转载时请注明出处http://www.cnblogs.com/kerrycode/p/7068246.html。谢谢!
问题描述
今天,我们的一个SQL Server实例性能变得非常慢。当我登录到数据库服务器进行一些初始检查时,我最初始观察、注意到的是它的内存压力(memory pressure)。接下来,我们必须找出是什么导致我们的实例出现内存紧张。当我检查事务的等待类型时,RESOURCE_SEMAPHORE等待是大多数事务的问题。在这篇文章中,我将描述这个问题,以及如何查找哪个查询语句或事务导致了内存压力
解决方案
当我检查所有事务的等待类型时,大多数事务的等待类型为RESOURCE_SEMAPHORE 等待以及某些页面IO等待。页面IO等待也是由于内存压力导致,因为这些事务无法获得足够的内存来执行这个操作。
资源信号量等待
在继续之前,我想对资源信号量(Resource_semaphore)等待进行一些说明,以便您可以更好地了解SQL Server是如何将内存授予SQL Server查询语句的。
当SQL Server收到用户发送的查询请求(查询语句)时,它首先创建一个编译过的计划,然后在这个基础上创建一个执行步骤(个人觉得执行步骤比执行计划要合适)。当SQL Server创建一个编译过的计划时,它会计算两个内存授予参数,称为“请求内存”(required memory)和“附加内存”(additional memory)。请求内存是运行排序和HASH连接所需的最小内存。它之所以是 "必需"的, 是因为如果没有可用的“请求内存”, 查询将无法启动。附加内存(additional memory)是在内存中存储临时行(个人觉得翻译为中间结果可能更合理)所需的内存量。这被称为额外(附加)的,因为如果没有足够可用的“附加内存”可以将查询的中间结果存储在磁盘上。
首先,服务器计算任何给定的查询执行需要多少内存。这通常是“请求内存”(required memory)和“附加内存”(additional memory)的总和,但如果您的实例正在并行处理,那么所需的内存将是(所需的内存* DOP)+附加内存。服务器检查所需的内存是否超过每个查询限制,然后服务器减少“附加内存”,直到总数达到限制。这个修改后的大小称为请求内存。SQL Server有一个内部工具称为资源信号量(RESOURCE SEMAPHORE),用于将此请求的内存授予查询。如果无法通过资源信号量向该请求的内存授予查询,那么如果查询sys.sysprocesses系统表或sys.dm_exec_request DMV,则该查询将处于等待状态,并出现RESOURCE_SEMAPHORE等待类型。
当资源信号量(Resource_semaphore)接收到新的请求时,它首先检查是否有任何查询正在等待中。只要发现存在即是一个等待查询,那么会将新查询(新请求)放入队列中,因为等待队列是以先到先得的方式设计的,并且有小权重以支持于小型查询。当没有等待查询或查询返回保留的内存时。资源信号量尝试授予内存。如果找到足够的内存,那么请求内存被授予并且查询可以开始运行,并且如果没有找到足够的可用内存来授予所请求的内存,那么它将当前查询放入等待队列中,并且给当前会话RESOURCE_SEMAPHORE等待类型, 此时服务器开始面临内存压力。
识别RESOURCE_SEMAPHORE等待
步骤1
首先,我们需要研究我们的实例,弄清楚为什么在SQL Server中出现内存压力。要查看所有事务的大概信息,我们可以查询sys.sysprocesses,或者我们可以使用sys.dm_exec_requests DMV。
SELECT ),另一个表示小型查询(resource_semaphore_id为1),小于5 MB。在这里,您可以获得实例的总授予内存和总可用内存。请参阅grantee_count和waiter_count上的数字,grantee_count是已经分配了内存的总查询数,waiter_count是队列中等待获取内存的总查询数量。所以在这里我们可以看到大约100个查询正在等待获得他们要求的内存。
SELECT * FROM sys.dm_exec_query_resource_semaphores

步骤3
现在我们将获取所有正在等待队列中获取所请求的内存的所有查询的详细信息,我们将使用DMV sys.dm_exec_query_memory_grants来获取队列中等待分配内存的查询总数。对于等待获取其请求的内存的查询,grant_time和granted_memory_kb列将为NULL。您可以在下面的截图中查看所请求的内存量及其等待状态,因为它们的grant_time和granted_memory_kb值为NULL。我们还可以使用该DMV获取所有查询的plan_handle和sql_handle。稍后我们将使用这些值来获取确切的查询。
注意:有太多列要显示,可以只显示部分所需的列。
SELECT * FROM sys.dm_exec_query_memory_grants

步骤4
现在,我们将找到内存密集型查询。我们可以看到所有等待查询的请求内存。在这里我们可以看到所请求的内存对于大多数事务来说太大了。我们将获得所有这些查询的plan_handle,以获得确切的SQL文本来查看查询计划。
从sys.dm_exec_query_memory_grants中选择前10个*
select top 10 * from sys.dm_exec_query_memory_grants

步骤5
现在我们将使用上面查询所获得的plan_handle和sql句柄来获取SQL代码。
运行以下语句从上述查询中获取SQL代码,使用sql_handle。
SELECT * FROM sys.dm_exec_sql_text(sql_handle)

我们还可以使用步骤4中查询中的plan_handle获取SQL计划。
SELECT * FROM sys.dm_exec_sql_plan(plan_handle) --译者注 实际没有sys.dm_exec_sql_plan, 而是sys.dm_exec_query_plan,估计是作者笔误。
结论
现在我们已经找到内存密集型查询及其执行计划,我们的下一步是研究这些查询,并找出如何调整、优化它们。我们应该查看查询中是否使用的错误的索引或是否存在索引缺失的情况,并创建正确的索引。在我们这种情况下,这是由于糟糕的索引设计导致了内存紧张。在创建、调整合适的索引之后,相同的查询运行的时候请求的内存就会少得多。
下一步
- 使用此提示来识别由于内存不足而消耗更多内存并将剩余的事务置于等待状态的查询。
- 还要查看上述DMV的其他列,并将它们联系起来,以便更好地分析和了解性能问题。
- 这些DMV应提供大量信息,以便您能够识别问题。
- 阅读有关性能调优的更多提示,以提高系统性能。
Troubleshooting SQL Server RESOURCE_SEMAPHORE Waittype Memory Issues的更多相关文章
- SQL Server 内存泄露(memory leak)——游标导致的内存问题
原文:SQL Server 内存泄露(memory leak)--游标导致的内存问题 转自:http://blogs.msdn.com/b/apgcdsd/archive/2011/07/01/sql ...
- 《Troubleshooting SQL Server》读书笔记-CPU使用率过高(下)
<Troubleshooting SQL Server>读书笔记-CPU使用率过高(下) 第三章 High CPU Utilization. CPU使用率过高的常见原因 查询优化器会尽量从 ...
- 《Troubleshooting SQL Server》读书笔记-内存管理
自调整的数据库引擎(Self-tuning Database Engine) 长期以来,微软都致力于自调整(Self-Tuning)的SQL Server数据库引擎,用以降低产品的总拥有成本.从SQL ...
- 將sql server 2008R2 Max memory 意外設為0
做sql server 內存Max memory 設定時大意,誤把最大值設為0,怎麼著都連不上DataBase,哪真叫個急呀,最後還是看到一條文命令把救回來了,其它很簡單急的時候就是沒想出來. 1.暫 ...
- 《Troubleshooting SQL Server》读书笔记-CPU使用率过高(上)
第三章 High CPU Utilization. CPU使用率过高问题很容易被发现,但是诊断却不是很容易.CPU使用过高很多时候会成为其它问题的替罪羊,所以在确认和故障诊断时要抽丝剥茧. 调查CPU ...
- 高老大 ‘SQL Server 优化器特性导致的内存授予相关BUG’ 学习笔记
今天高老大出了好文章.在这里 自己本来对这一块比较混乱,正好借这个机会学习一下. 就用高老大的脚本.需要的直接去他那里找吧,这里就省了. 加查询优化标记前后对比 可以看到GrantedMemory是5 ...
- Memory Manager surface area changes in SQL Server 2012
here were various changes to memory related DMVs, DBCC memory status, and Perfmon counters in SQL Se ...
- 非常全面的SQL Server巡检脚本来自sqlskills团队的Glenn Berry 大牛
非常全面的SQL Server巡检脚本来自sqlskills团队的Glenn Berry 大牛 Glenn Berry 大牛会对这个脚本持续更新 -- SQL Server 2012 Diagnost ...
- SQL Server 内存相关博文
Don’t confuse error 823 and error 832 本文大意: 错误832: A page that should have been const ...
随机推荐
- 发福利了!!超过100本的linux免费书籍
New Books Kindle Fire App Development Essentials iPhone iOS 6 Development Essentials CentOS 6 Essent ...
- virualbox 虚拟机管理
虚拟机调换后提示UUID一致,需要重新生成新的虚拟机文件的UUID,使用如下命令: D:\Program Files\Oracle\VirtualBox>VBoxManage internalc ...
- MVC学习之路【小补充】
1]:在js中使用ViewBag 需要添加“”,否则程序报错,无法正常运行 .例如:正确格式 var ss = "@ViewBag.ts"
- 第一册:lesson ninety-seven。
原文: A small blue case. I left a suitcase on the train to London the other day. Can you describe it , ...
- oracle expdp自动备份脚本
windows: @echo off echo ================================================ echo Windows环境下Oracle数据库的自动 ...
- ASP.NET MVC3 在_ViewStart设置Layout使用RenderAction的注意事項
来源:https://dotblogs.com.tw/lastsecret/archive/2012/03/26/71052.aspx ASP.NET MVC3 在_ViewStart設定Layout ...
- ASP.NET Core 中使用EF Core 将实体映射到数据库表的方法(SQL Server)
前段时间听过一个关于使用ASP.NET Core建立项目的视频.其中使用EF Core映射到数据库的部分是按部就班地学习.今天自己建立项目时,有些步骤已经有一些遗忘.所以写下这篇文章,顺便理清思路. ...
- 46.Linux-创建rc红外遥控平台设备,实现重复功能(2)
上章链接:46.Linux-分析rc红外遥控平台驱动框架,修改内核的NEC解码函数BUG(1) 在上章分析了红外platform_driver后,已经修改bug后,接下来我们自己创建一个红外platf ...
- 4.2 explain 之 select_type
一.查询类型,主要用于区别 普通查询.联合查询.子查询等的复杂查询 二.常用常见的类型 1. simple : 简单的select查询,查询中不包含子查询或union 2. primary : 查询中 ...
- 自己用HashMap来模拟一个Session缓存(简易版)
本文记录:Hibernate中一级缓存的特点. 一级缓存的细节什么操作会向一 1.级缓存放入数据 save,update,saveOrUpdate,load,get,list,iterate,lock ...