关于Latch争用
Latch是什么
- Buffer Latch:当工作线程访问缓冲池中的某个页之前,必须要先获得此页的Latch。主要用于保护用户对象和系统对象的页。等待类型表现为PAGELATCH_*
- I/O Latch:当工作线程请求访问的页未在缓冲池中时,就会发一个异步I/O从存储系统将对应的页加载到缓冲池中。这个过程会获取相应页上 I/O Latch,避免其它线程使用不兼容的Latch加载同一页到缓冲池中。等待类型表现为PAGEIOLATCH_*
- Non-Buffer Latch:保护缓冲池页之外的内部内存结构时使用。等待类型表现为LATCH_XX。
- KP – Keep Latch 保证引用的结构不能被破坏
- SH – Shared Latch, 读数据页的时候需要
- UP – Update Latch 更改数据页的时候需要
- EX – Exclusive Latch 独占模式,主要用于写数据页的时候需要
- DT – Destroy Latch 在破坏引用的数据结构时所需要
KP | SH | UP | EX | DT |
Y | Y | Y | Y | N |
Y | Y | Y | N | N |
Y | Y | N | N | N |
Y | N | N | N | N |
N | N | N | N | N |
- 影响Latch争用的因素
因素
|
明说 |
使用过多的逻辑CPU
|
任何多核的系统都会出现Latch争用。Latch争用超过可接受程度的系统,多数使用16个或者以上的核心数。 |
架构设计和访问模式
|
B树深度,索引的大小、页密度和设计,数据操作的访问模式都可能会导致过多的Latch争用
|
应用层的并发度过高
|
多数Latch争用都会伴有应用层的高并发请求。
|
数据库逻辑文件的布局
|
逻辑文件布局影响着分配单元结构(如PFS,GAM,SGAM,IAM等)的布局,从而影响Latch争用程度。最著名的例子就是:频繁创建和删除时临表,导致tempdb的PFS页争用
|
I/O子系统性能
|
大量的PAGEIOLATCH等待就说明SQL Server在等待I/O子系统。
|
- 观察性能监视器的CPU利用率和SQL Server等待时间,判断两者是否具有关联性。
- 通过DMV获取引起Latch争用的具体类型和资源。
- 诊断某些Non-Buffer Latch争用,可能还需要获取SQL Server进程的内存转储文件并结合Window调试工具一起分析。
- 使用“Query sys.dm_os_waiting_tasks Ordered by Session ID”脚本或者“Calculate Waits Over a Time Period”脚本观察当前的等待任务和平均Latch等待时间情况。
- 使用“QueryBufferDescriptorsToDetermineObjectsCausingLatch”脚本确定争用发生的位置(索引和表)。
- 使用性能计数器观察MSSQL%InstanceName%\Wait Statistics\Page Latch Waits\Average Wait Time或者查询sys.dm_os_wait_stats观察页平均Latch等待时间。
SELECT wt.session_id, wt.wait_type
, er.last_wait_type AS last_wait_type
, wt.wait_duration_ms
, wt.blocking_session_id, wt.blocking_exec_context_id, resource_description
FROM sys.dm_os_waiting_tasks wt
JOIN sys.dm_exec_sessions es ON wt.session_id = es.session_id
JOIN sys.dm_exec_requests er ON wt.session_id = er.session_id
WHERE es.is_user_process = 1
AND wt.wait_type <> 'SLEEP_TASK'
ORDER BY wt.wait_duration_ms desc
列
|
说明
|
Session_id
|
task所属的session id
|
Wait_type
|
当前的等待类型 |
Last_wait_type
|
上次发生等待时的等待类型 |
Wait_duration_ms
|
此等待类型的等待时间总和(毫秒) |
Blocking_session_id |
当前被阻塞的session id
|
Blocking_exec_context_id
|
当前task的ID |
Resource_description
|
具体等待的资源 |
列 |
说明
|
Latch_class
|
Latch类型
|
Waiting_requests_count
|
当前Latch类型发生的等待次数
|
Wait_time_ms
|
当前Latch类型发生等待的时间总和
|
Max_wait_time_ms
|
当前Latch类型发生等待最长时间
|
- 高并发的INSERT,DELETE,UPDATE和SELECT操作
- 页密度较大,行较窄
- 表的行数较少,所以B树也较浅,索引深度在2~3级。
select o.name as [table], i.name as [index],
indexProperty(object_id(o.name), i.name, 'indexDepth')
+ indexProperty(object_id(o.name), i.name, 'isClustered') as depth, --clustered index depth reported doesn't count leaf level
i.[rows] as [rows], i.origFillFactor as [fillFactor],
case (indexProperty(object_id(o.name), i.name, 'isClustered'))
when 1 then 'clustered'
when 0 then 'nonclustered'
else 'statistic'
end as type
from sysIndexes i
join sysObjects o on o.id = i.id
where o.type = 'u'
and indexProperty(object_id(o.name), i.name, 'isHypothetical') = 0 --filter out hypothetical indexes
and indexProperty(object_id(o.name), i.name, 'isStatistics') = 0 --filter out statistics
order by o.name
view index depth
- 增加Tempdb的数据文件个数,个数=CPU的核心数
- 启用跟踪标记TF 1118
create table table1
(
TransactionID bigint not null,
UserID int not null,
SomeInt int not null
)
go
alter table table1
add constraint pk_table1
primary key clustered (TransactionID, UserID)
go
方式1.:使用UserID做为索引首键,将INSERT操作分布到所有数据页上。需要注意的是:索引修改后,所有SELECT的WHERE等式中需要同时指定UserID和TransactionID。
create table table1
(
TransactionID bigint not null,
UserID int not null,
SomeInt int not null
)
go
alter table table1
add constraint pk_table1
primary key clustered (UserID, TransactionID)
go
方式2:使用TransactionID对CPU核数取模做为索引首键,将INSERT操作较均匀分布到表上。
create table table1
(
TransactionID bigint not null,
UserID int not null,
SomeInt int not null
)
go
-- Consider using bulk loading techniques to speed it up
ALTER TABLE table1
ADD [HashValue] AS (CONVERT([tinyint], abs([TransactionID])%(32))) PERSISTED NOT NULL
alter table table1
add constraint pk_table1
primary key clustered (HashValue, TransactionID, UserID)
go
- 新建或者使用现有的文件组承载各分区
- 如果使用新文件组,需要考虑IO子系统的优化和文件组中数据文件的合理布局。如果INSERT负载占比较高,则文件组的数据文件个数建议为物理CPU核心数的1/4(或者1/2,或者相等,视情况而定)。
- 使用CREATE PARTITION FUNCTION将表分成N个分区。N值等于上一步的数据文件的个数。
- 使用CREATE PARTITION SCHEME绑定分区函数到文件组,然后再添加一个smallint或者tinyint类型的Hash列,再计算出合适的Hash分布值(例如HashBytes值取模 或者取Binary_Checksum值)。
--Create the partition scheme and function, align this to the number of CPU cores 1:1 up
to 32 core computer
-- so for below this is aligned to 16 core system
CREATE PARTITION FUNCTION [pf_hash16] (tinyint) AS RANGE LEFT FOR VALUES
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
CREATE PARTITION SCHEME [ps_hash16] AS PARTITION [pf_hash16] ALL TO ( [ALL_DATA] ) -- Add the computed column to the existing table (this is an OFFLINE operation)
-- Consider using bulk loading techniques to speed it up
ALTER TABLE [dbo].[latch_contention_table]
ADD [HashValue] AS (CONVERT([tinyint], abs(binary_checksum([hash_col])%(16)),(0)))
PERSISTED NOT NULL
--Create the index on the new partitioning scheme
CREATE UNIQUE CLUSTERED INDEX [IX_Transaction_ID]
ON [dbo].[latch_contention_table]([T_ID] ASC, [HashValue])
ON ps_hash16(HashValue)



- 通常SELECT语句的查询谓词部分需要修改,使其包含Hash分区列。这会导致查询计划的分区消除不可用。
- 某些其它查询(如基于范围查询的报表)也不能使用分区消除。
- 当分区表与另一个表JOIN时,如果使用分区消除,则另一个表需要在同样的键上实现Hash分区并且Hash键需要包括在JOIN条件里。
- Hash分区会使滑动窗口归档和分区归档功能不可用。
总结
1. 本文以SQLCAT的Latch Contention白皮书为基础,结合Paul Randal关于Latch的博文,以及本人的经验而成。
2. Buffer Latch Contention较容易定位和处理。Non-Buffer Latch 是较为棘手的,因为太少关于此类型Latch的说明资料,造成有时定位到类型,也不知道它是什么意思,无从下手。
附加代码:
关于Latch争用的更多相关文章
- 关于MySQL latch争用深入分析与判断
1.latch锁是什么锁? 2.latch锁是如何保护list? 3.latch争用的现象和过程? 4.latch什么时候会产生严重的争用? 5.如何监控latch争用情况? 6.如何确认latch争 ...
- [转载】——故障排除:Shared Pool优化和Library Cache Latch冲突优化 (文档 ID 1523934.1)
原文链接:https://support.oracle.com/epmos/faces/DocumentDisplay?_adf.ctrlstate=23w4l35u5_4&id=152393 ...
- Oracle Latch的学习【原创】
Latch详解 - MaxChou 本文以学习为目的,大部分内容来自网络转载. 什么是Latch 串行化 数据库系统本身是一个多用户并发处理系统,在同一个时间点上,可能会有多个用户同时操作数据库.多个 ...
- latch: cache buffers chains故障处理总结(转载)
一大早就接到开发商的电话,说数据库的CPU使用率为100%,应用相应迟缓.急匆匆的赶到现场发现进行了基本的检查后发现是latch: cache buffers chains 作祟,处理过程还算顺利,当 ...
- latch: cache buffers chains故障处理总结
一大早就接到开发商的电话,说数据库的CPU使用率为100%,应用相应迟缓.急匆匆的赶到现场发现进行了基本的检查后发现是latch: cache buffers chains 作祟,处理过程还算顺利,当 ...
- latch介绍
latch是一种锁,用来实现对Oracle所有共享数据结构的串行化访问.共享池就是这样一个例子, 这是系统全局区中一个庞大的共享数据结构,Oracle正是在这里存储已解析,已编译的SQL. 修改这个共 ...
- latch:library cache
一:硬解析造成的shared pool latch 争用: 每一个sql被执行之前,先要到library cache中根据hash_value查找parent cursor,这就需要先获得librar ...
- cache buffers chains latch
cache buffers chains latch 从 Oracle 8i Database 开始, 散列锁存器<-------(1:m)------>hash bucket<-- ...
- 热点块引发的cache buffers cahins latch
热点块引发的Cache buffer Chains latch: SQL语句即便适当进行了调优,有时也无法解决cache buffers cahins latch,若在编写SQL语句时的SQL工作方式 ...
随机推荐
- Mysql自动备份工具1.0(2013年11月15日更新)
Mysql自动备份工具1.0 下载地址 2013-11-15 1.解决日历控件在Windows7/8/8.1环境下遮挡按钮问题:2.解决按月备份当月没有该日期问题: 2013-11-13 1.Mysq ...
- linux-impdp的使用
数据库是在linux服务器上,需要用impdp方式导入一个dmp,用root用户登录该数据库服务器后,直接采用impdp命令执行导入操作,提示:KSH:impdp:not found.经查原来是操作的 ...
- SQLServer公历转农历函数(1900年-2049年)
ALTER FUNCTION [dbo].[f_SysGetLunar]( @solarDay DATETIME) RETURNS varchar(20 ...
- VS2013 修改TFS的本地映射路径
在源代码管理器里面 找到你的本地工作区 然后点击编辑按钮 修改本地目录
- centos7 Linux 安装mysql
安装过程如: http://blog.csdn.net/tengdazhang770960436/article/details/18361979 中间过程出现无法安装mysql-server 解决方 ...
- IIS网站属性中没有ASP.NET选项
打开IIS6,右击属性,居然没有发现ASP.NET的配置选项,虽然好久没搞这个了,但是印象中绝对是有一个ASP.NET选项卡的.我很奇怪,我以为是.net framework 2.0没安装,下载下来安 ...
- WP-PostViews的安装和设置方法
wordpress本身并没有文章浏览统计功能,必须借助插件.想要知道自己的文章被多数访客浏览,或者访客对哪些文章或者哪类文章更加有兴趣,这就是文章统计的重要性了.WP-PostViews插件是哥不错的 ...
- [Javascript] Limit Built Branches on Travis
By default, Travis will build all branches, tags, and Pull Requests. Because we're building our mast ...
- Xcode 8 新特性
在2016 苹果全球开发者大会(WWDC)期间, 苹果一如既往地给开发者们披露了新版的集成开发工具 – Xcode, 在过去的每一次大版本发布中,苹果都会积极地改进开发工具,添加一些极具吸引力的新功能 ...
- windows 程序设计自学:添加字符串资源
#include <windows.h> #include "resource.h" LRESULT CALLBACK MyWndProc( HWND hwnd, // ...