我们看到非常高的 PAGELATCH_EX 和 PAGELATCH_SH 等待类型以及高 WRITELOG 等待。我已经诊断出导致 PAGELATCH 等待的查询,并且可以通过降低插入到使用 IDENTITY 值定义的繁忙集群主键的插入率来消除它们。我知道这种现象被称为最后一页插入闩锁争用。
但是我的问题是,当插入新记录时,SQL Server 是否在缓冲区页面上采用独占 PAGELATCH_EX,将记录插入缓冲区页面,将记录写入事务日志,然后详细释放独占 PAGELATCH_EX https:// www.microsoft.com/en-ie/download/details.aspx?id=26665第24页。还是先将记录写入事务日志,然后再将PAGELATCH_EX作为详细的“解决高并发上的PAGELATCH争用”插入工作负载-背景信息SQLCAT's Guide to: Relational Engine
如果记录被写入锁存机制之外的日志,那么我可以排除缓慢写入磁盘是导致高 PAGELATCH 等待的原因。但是,如果锁存器一直保持到记录被硬化记录,那么我可能应该考虑 WRITELOG。
还有多个非聚集索引会导致 PAGELATCH_* 锁存器保持更长时间,即如果一个表有一个聚集的并且多个非聚集索引是同时添加并释放到每个索引缓冲区页面的锁存器?
更新 1 在阅读了 conio-sql-server-writelog-wait幻灯片二和一般 WAL 架构之后。我现在了解到,两份白皮书中详述的“记录已修改行的日志条目”步骤是指 SQL Server 在事务日志缓存中记录更改,而不是在磁盘中记录更改。一旦事务完成或缓冲区已满,所有记录都会立即刷新到磁盘。
您必须注意,锁存器仅在页面位于内存中时保护页面的物理完整性,因此当页面位于内存中时会使用锁存器。假设正在插入一条记录,并且需要获取该页面。首先,页面将被锁定并带入内存,然后将被锁存并写入信息。之后的过程是
生成日志记录
更新页面 LSN 以匹配日志记录
更改数据(弄脏页面)
释放闩锁
提交事务开始
提交的 FlushToLSN
释放锁
提交事务完成
有关上述步骤的更多详细信息和说明,请阅读Bob Dorr 的 I/O 演示博客
Pagelatch* 等待是非 I/O 等待,我看到大多数时候这些等待由于分配争用而很突出。我的预感是它必须与 how
tempdb is configured
. 那么您的 tempdb 是如何配置的?存在多少 tempdb 数据文件?确保它们具有相同的自动增长和相同的大小。当创建新页面时,需要更新或访问诸如GAM、SGAM 和 PFS 页面之类的系统页面,并且当 SQL Server 在访问这些页面时发现争用时,就会出现这种等待。