sql server中PAGELATCH_x和PAGEIOLATCH_x解析

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
全局流量管理 GTM,标准版 1个月
简介:

0.参考文献

Microsoft SQL Server企业级平台管理实践 第11章

Buffer Latch Timeout的解析

什么是PAGELATCH和PAGEIOLATCH

1.PAGELATCH_x和PAGEIOLATCH_x介绍

 在分析SQL server 性能的时候你可能经常看到 PAGELATCH和PAGEIOLATCH。比方说执行如下TSQL语句

Select * from sys.dm_os_wait_stats

它输出结果里面就有Latch的有关信息,如下图所示:

1.1什么是LATCH呢?

Latch是SQL server内部用来同步资源访问的一个数据结构,和操作系统的critical section 或 ReaderWriterLock类似。Latch保护了那些想保护的资源,使得访问同步有序。比方说,当某个线程获得某个资源的latch的独占使用权的时候,别的线程如果也需要访问这个latch则它必须等待。那么又有新的疑问,latchlock有什么区别呢?主要是使用的地方和目的不一样。Latch用来保护SQL server内部的一些资源(如page)的物理访问,可以认为是一个同步对象。而lock则强调逻辑访问。比如一个table,就是个逻辑上的概念,物理上一个表是有很多页组成的。访问一个表的记录的时候,首先可能需要获得表的共享锁,然后获得某个页的latch,然后就可以读取该页的记录。Lock是全局性的,由统一的lock manager管理。而latch没有统一的manager管理的。

1.2什么是PAGELATCH呢?

PAGELATCH_x类型的latch是SQL Server在缓冲池里的数据页面上经常加的一类latch。它用来同步访问buff pool中的数据页。SQL server中的Buff pool里每个page都有一个对应的LATCH。 要访问某个PAGE必须首先获得这个PAGE的LATCH。PAGELATCH有很多种,如共享的PAGELATCH_SH,独占的PAGELATCH_EX等。独占的意思是排他性访问,只有一个线程可以访问,一般用户update,insert和delete操作。共享的意思是可以有多个线程同时获得这个latch。下面以在同一个data page中插入输入数据来说明pagelatch。可以参考博客:Buffer Latch Timeout的解析

每个SQL Server的数据页面大致分成3个部分:页头、页尾偏移量和数据存储部分。假设现在有一个表格的结构是:

CREATE TABLE test (
    a int, 
    b int
)

它在1:100这个页面上存储数据。那么这个页面结构大致如下图所示:

在页头部分,会记录页面属性,包括页面编号等,还会记录当前页面空闲部分的起始位置在哪里(m_freedata)。这样SQL Server在要插入新数据的时候,就能够很快地找到开始插入的位置。而页尾部的偏移记录了每一条数据行的起始位置。这样SQL Server在找每一条记录的时候,就能很快找到,不会把前一条记录和后一条搞混。在上图中page:100里现在有两条记录,(1,100)和(2,200)。第一条记录的开始位置是96,第二条的开始位置是111。从126开始,是空闲的空间。这页表明一列的长度是15。当页面里的数据行发生变化的时候,SQL Server不但要去修改数据本身,还要修改这些偏移量的值,以保证SQL Server能够继续准确地管理数据页面里的每一行。

现在假设有两个用户 同时要向这张表里插入数据,一个人插入(3,300),另一个插入(4,400)。那么这两个用户会读取相同的 (m_freedata=126)
假如没有latch,这两条插入语句可以同时运行。在事务逻辑上,这两条语句插入的是两条不相干的记录,所以不应该相互阻塞,这样处理是正确的。 某进程在页面100上,插入如下数据:INSERT VALUES(3, 300),其结果如下:

这时,另外一个进程要在页面100上,插入如下数据: INSERT VALUES(4, 400), 因为没有Latch锁,所以会覆盖之前的数据。导致数据插入出问题。如下图所示:

在逻辑层面上,插入两条数据是互不干扰的,但是在物理存储层面上,就出现了问题。要插入的两条数据读取的空闲空间位置m_freedata=126,都要往这个位置上面插入,那么总有一条数据会被另外一条数据所覆盖,从而导致插入错误。要想办法解决这个冲突,一定要定义出一个先后顺序。SQL Server为了解决这类问题,引入了另一类页面上的latch:PAGELATCH。当一个任务要修改页面时,它必须先申请一个EX的latch。只有得到这个latch,才能修改页面里的内容。所以这里的两个插入任务,不仅申请了页面上的锁,还要申请页面上的排他latch。假设(3,300)这个插入任务先申请到了,那(4,400)这个任务就会被阻塞住。所以,(3,300)这条记录能够被先插入,如下图所示。

当(3,300)插入完成后,它申请的latch被释放,m_freedata的数据被更新。此时(4,400)就能得到latch资源,这是才读取m_freedata,然后往m_freedata位置插入数据。(4,400)被插在了(3,300)的后面。这样,两个插入都正确地完成了,如下图所示。

由于数据页的修改都是在内存中完成的,所以每次修改的时间都应该非常短,几乎可以忽略不计。而PAGELATCH只是在修改的过程中才会出现,所以PAGELATCH的生存周期应该也非常短。如果这个资源成为了SQL Server经常等待的资源,可说明以下问题。

  1. SQL Server没有明显的内存和磁盘瓶颈(恭喜你!)。
  2. 应用程序发来大量的并发语句在修改同一张表格里的记录,而表格架构设计以及用户业务逻辑使得这些修改都集中在同一个页面,或者数量不多的几个页面上。这些页面有的时候也被称为Hot Page。这样的瓶颈通常只会发生在并发用户比较多的、典型的OLTP系统上。
  3. 这种瓶颈是无法通过提高硬件配置解决的,只有通过修改表格设计或者业务逻辑,让修改分散到尽可能多的页面上,才能提高并发性能。
  4. 要在修改表格的设计,从而引入了partition的概念,要解决上述问题,可以通过分区的方式分担hot page上面的压力。具体解决方法参考另外一篇博客:sql server中filegroup与partition解析 。

1.3什么是PAGEIOLATCH呢?

当缓存在内存缓冲池区域里的数据页面,和磁盘上数据文件里的数据页面进行交互时(就是data page不在内存中),为了保证不会有多个用户同时读取/修改内存里的数据页面,SQL Server会像对待表格里的数据一样,对内存中的页面实行加锁的机制,以同步多用户并发处理。不同的是,在这里,SQL Server加的是latch(轻量级的锁),而不是lock。

例如,当SQL Server将数据页面从数据文件里读入内存时,为了防止其他用户对内存里的同一个数据页面进行访问,SQL Server会在内存的数据页面上加一个排他的latch。而当有任务要读缓存在内存里的页面时,会申请一个共享的latch。像lock一样,latch也会出现阻塞的现象。根据不同的等待资源,在SQL Server里等待的状态会是:

复制代码
PAGEIOLATCH_DT : Destroy buffer page I/O latch
PAGEIOLATCH_EX : Exclusive buffer page I/O latch
PAGEIOLATCH_KP : Keep buffer page I/O latch
PAGEIOLATCH_NL : Null buffer page I/O latch
PAGEIOLATCH_SH : Shared buffer page I/O latch
PAGEIOLATCH_UP : Update buffer page I/O latch
复制代码

这里来举一个最容易发生的等待“PAGEIOLATCH_SH”,以它做例子,看看这种等待是怎么发生的。如下图所示:

过程解析

  1. 有一个用户请求,须读取整张X表,由Worker X执行。
  2. Worker X在执行表扫描的过程中发现它要读取数据页面1:100。一张表的数据量可能比一个page大,也可能比一个page小。如果进行table scan的话,那么就需要读取所有包含该表数据的page。
  3. SQL Server发现页面1:100并不在内存中的数据缓存里。
  4. SQL Server在缓冲池里找到一个页面的空间,在上面申请一个EX的latch,防止数据从磁盘里读出来之前,有别人也来读取或修改这个页面。对长个page加锁相当于是在内存中预定了一片空间用于存放需要从磁盘中physical read来的page。
  5. Worker X发起一个异步(Asynchronous)I/O请求,要求从数据文件(database file)里读出页面1:100。
  6. 由于是个异步I/O,Worker X可以接着做它下面要做的事情。而下面要做的,就是要读出内存中的页面1:100。读取的动作需要申请一个SH的latch。
  7. 由于Worker X之前已经对这个page1:100申请了一个EX latch还没释放,所以这个SH latch将被阻塞住。Worker X被自己阻塞住了,等待的资源就是PAGEIOLATCH_SH。
  8. 当异步I/O结束后,系统会通知Worker X,你要的数据已经写入内存了,如下图所示:
  9. 这时候EX latch就被释放。接着Worker X得到了它申请的SH latch。
  10. 数据页1:100终于被Worker X读到,读取工作结束,Worker X可以继续下面的操作。

由此可以看到,在发生PAGEIOLATCH类型的等待时,SQL Server一定是在等待某个I/O动作的完成。所以如果一个SQL Server经常出现这一类的等待,说明磁盘的速度不能满足SQL Server的需要,它已经成为了SQL Server的一个瓶颈。

要强调的是,PAGEIOLATCH_x类型等待最常见的是两大类,PAGEIOLATCH_SH和PAGEIOLATCH_EX。PAGEIOLATCH_SH经常发生在用户正想要去访问一个数据页面,而同时SQL Server却要把这个页面从磁盘读往内存。如果这个页面是用户经常有可能访问到的,那么说到底,问题是因为内存不够大,没能够将数据页面始终缓存在内存里。所以,往往是先有内存压力,触发SQL Server做了很多读取页面的工作,才引发了磁盘读的瓶颈。这里的磁盘瓶颈常常是内存瓶颈的副产品。

而PAGEIOLATCH_EX常常是发生在用户对数据页面做了修改,SQL Server要向磁盘回写的时候,基本意味着磁盘的写入速度明显跟不上。这里和内存瓶颈没有直接的联系。

和磁盘有关的另一个等待状态是WRITELOG,说明任务当前正在等待将日志记录写入日志文件。出现这个等待状态,也意味着磁盘的写入速度明显跟不上。

1.4pagelatch和pageiolatch对比

  1. pagelatch是为了保护在buff pool中page的正确读写,比如说有两个线程想同时往一个page中插入数据,如果没有latch控制的话,插入位置存在冲突。所以引入了pagelatch_ex,一次只有一个线程能够得到pagelatch_ex,只有得到pagelatch_ex的线程才能够修改page。
  2. 而pageiolatch是为了数据的异步访问。比如说我们想读取一个page,但是它不内存中,那么sql server会首先在内存中为这个page空出一块空间,并且加上ex_latch,然后在这个page真正从disk读取到内存当中之前,其他线程不能对这片内存进行操作。因为异步操作,所以这个线程会去访问这个page,此时申请sh_latch,但是与之前的ex_latch,最终导致自己被自己阻塞了。这就是pageiolatch_sh
 

本文转自xwdreamer博客园博客,原文链接:http://www.cnblogs.com/xwdreamer/archive/2012/08/30/2663232.html,如需转载请自行联系原作者
相关实践学习
使用SQL语句管理索引
本次实验主要介绍如何在RDS-SQLServer数据库中,使用SQL语句管理索引。
SQL Server on Linux入门教程
SQL Server数据库一直只提供Windows下的版本。2016年微软宣布推出可运行在Linux系统下的SQL Server数据库,该版本目前还是早期预览版本。本课程主要介绍SQLServer On Linux的基本知识。 相关的阿里云产品:云数据库RDS SQL Server版 RDS SQL Server不仅拥有高可用架构和任意时间点的数据恢复功能,强力支撑各种企业应用,同时也包含了微软的License费用,减少额外支出。 了解产品详情: https://www.aliyun.com/product/rds/sqlserver
目录
相关文章
|
2月前
|
SQL IDE 数据库连接
IntelliJ IDEA处理大文件SQL:性能优势解析
在数据库开发和管理工作中,执行大型SQL文件是一个常见的任务。传统的数据库管理工具如Navicat在处理大型SQL文件时可能会遇到性能瓶颈。而IntelliJ IDEA,作为一个强大的集成开发环境,提供了一些高级功能,使其在执行大文件SQL时表现出色。本文将探讨IntelliJ IDEA在处理大文件SQL时的性能优势,并与Navicat进行比较。
36 4
|
2月前
|
SQL Java 数据库连接
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
canal-starter 监听解析 storeValue 不一样,同样的sql 一个在mybatis执行 一个在数据库操作,导致解析不出正确对象
|
3月前
|
SQL 监控 数据库
SQL语句是否都需要解析及其相关技巧和方法
在数据库管理中,SQL(结构化查询语言)语句的使用无处不在,它们负责数据的查询、插入、更新和删除等操作
|
2月前
|
SQL 监控 安全
员工上网行为监控软件:SQL 在数据查询监控中的应用解析
在数字化办公环境中,员工上网行为监控软件对企业网络安全和管理至关重要。通过 SQL 查询和分析数据库中的数据,企业可以精准了解员工的上网行为,包括基础查询、复杂条件查询、数据统计与分析等,从而提高网络管理和安全防护的效率。
32 0
|
3月前
|
SQL 存储 数据库
SQL语句是否都需要解析及其相关技巧与方法
在数据库管理系统中,SQL(Structured Query Language)语句作为与数据库交互的桥梁,其执行过程往往涉及到一个或多个解析阶段
|
3月前
|
SQL 数据可视化 BI
SQL语句及查询结果解析:技巧与方法
在数据库管理和数据分析中,SQL语句扮演着至关重要的角色
|
3月前
|
SQL 监控 关系型数据库
SQL错误代码1303解析与处理方法
在SQL编程和数据库管理中,遇到错误代码是常有的事,其中错误代码1303在不同数据库系统中可能代表不同的含义
|
3月前
|
SQL 存储 关系型数据库
SQL默认索引是什么:深入解析与技巧
在SQL数据库中,索引是一种用于提高查询性能的重要数据结构
|
3月前
|
SQL 开发框架 .NET
ASP.NET连接SQL数据库:实现过程与关键细节解析an3.021-6232.com
随着互联网技术的快速发展,ASP.NET作为一种广泛使用的服务器端开发技术,其与数据库的交互操作成为了应用开发中的重要环节。本文将详细介绍在ASP.NET中如何连接SQL数据库,包括连接的基本概念、实现步骤、关键代码示例以及常见问题的解决方案。由于篇幅限制,本文不能保证达到完整的2000字,但会确保
|
3月前
|
SQL 分布式计算 大数据
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(一)
大数据-97 Spark 集群 SparkSQL 原理详细解析 Broadcast Shuffle SQL解析过程(一)
85 0