在SQL Server 列存储索引性能总结(10)——行组的大小影响一文中,实验过程当把服务器的max server memory(MB)值调到300MB并创建聚集列存储所以时,整整跑了5个小时都还没完成,然后查看对应的会话阻塞情况,发现了这个我过去很少见到过的等待状态,所以找了一些资料了解一下。当然,光从行为上,我大概能猜出是内存不够的原因,但是还是需要了解一下具体情况。
背景
在 “SQL Server 列存储索引性能总结(10)——行组的大小影响”一文的实验过程中,在把可用内存调到300MB之后,出现了很多问题,首先创建索引很慢,还有出现服务器启动不了,还有就是重启后数据库直接置疑等情况。
在创建很慢得时候,通过sys.sysprocesses查看对应的SPID,发现等待状态为RESOURCE_SEMAPHORE,这个等待状态比较少见,毕竟内存只有300MB的系统几乎不会出现在正式环境下。基于好奇,我整理了一下资料并分享一下。
RESOURCE_SEMAPHORE等待
这个等待类型发生在一个查询所需内存由于其他并发查询的影响,不能马上被授予(grant)的时候。这个等待信息如果处于非常高的出现频率及其时间很长的话,从定义里面分析可知有两种可能:
- 过度的内存请求量,也有可能是本身内存不足。
- 过度的并发量。
抛开这次把内存降低导致的“内存不足”的可能,在正式环境下更多的意味着资源与负载不对等,或者存在低效语句导致内存申请不合理。这个等待类型的出现几乎必然会导致所有数据库用户的使用感受降低,需要尽早干预。
出现这个等待类型的时候,应该关联Memory Grants Pending(SQLServer:Memory Manager\Memory Grants Pending)和Memory Grants Outstanding(SQLServer:Memory Manager\Memory Grants Outstanding)计数器或者使用SQL Server 列存储索引性能总结(9)——重建和重组聚集列存储索引所需的内存中提到的内存请求量的查询来检查一下当前的服务器状态:
SELECT cast(requested_memory_kb / 1024. as Decimal(9,2)) as RequestedMemoryMB
,cast(granted_memory_kb / 1024. as Decimal(9,2)) as GrantedMemoryMB
,cast(required_memory_kb / 1024. as Decimal(9,2)) as RequiredMemoryMB
,cast(used_memory_kb / 1024. as Decimal(9,2)