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 ...
随机推荐
- CentOS 7配置MariaDB允许指定IP远程连接数据库
防火墙 CentOS7 之前的防火墙是不一样的,比如你要添加3306端口: ## 全部 iptables -A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT # ...
- MHA+ProxySQL实现读写分离高可用
最近在研究ProxySQL,觉得还挺不错的,所以就简单的折腾了一下,ProxySQL目前也是Percona在推荐的一个读写分离的中间件.关于详细的介绍可以参考官方文档.https://github.c ...
- 微信公众号授权,支付,退款总结【shoucang】
1.支付前准备 1.1首先两个平台接入账户. 商户平台:https://pay.weixin.qq.com/index.php/core/home/login?return_url=%2F 公众平台: ...
- 使用wubi安装ubuntu14.04出现的常见错误的解决办法
花了一天的时间终于安装上了Ubuntu14.04,过程坎坷,是血泪史,开始报“cannot download the metalink and therefore the ISO”错误,解决后,又报“ ...
- [angularjs] angularjs系列笔记(四)过滤器
过滤器可以使用一个管道字符(|)添加到表达式和指令中,这不就是模板函数吗 <body> <div ng-app="Home"> <div ng-con ...
- Linux-cut命令(22)
cut剪切命令cut命令通常用来对某个文本文件进行解析,擅长处理以一个字符间隔的文本内容 -b :以字节(bytes)为单位进行分割.这些字节位置将忽略多字节字符边界,除非也指定了 -n 标志. -c ...
- maven插件调试方法
前言 以IntelliJ IDEA为例,通常我们调试maven项目时,都是直接点击调试按钮即可.但maven编写的插件就不同了,由于插件需要打包成Jar加载到项目中,所以如果我们需要在编写插件源码时调 ...
- js作用域面试题大全
什么是作用域:浏览器给js的生存环境叫作用域. 什么是变量提升: Js代码执行前,浏览器会给一个全局作用域window Window分两个模块一个是存储模块一个是执行模块 存储模块找到所有的var和f ...
- Javascript继承4:洁净的继承者----原型式继承
//原型式继承 function inheritObj(obj){ //声明一个过渡函数对象 function F(){} //过渡对象的原型继承父对象 F.prototype = obj; //返回 ...
- jstack 排查 java 进程占用大量 CPU 问题
1. top 看看哪个进程是罪魁祸首 2.将这个进程的jstack dump 到一个文件里面,以备使用. jstack -l 25886 > /tmp/jstack.log # 如果报错,则加 ...