sqlserver latch

什么是bool pool

sqlserver运行内存分为两类,一类是bool pool;一类是非bool pool.

开发人员只需要关注一点,bool pool是内存区域即可。

pin与spin

pin

pin是对对象内容的请求。可以与get一起理解 ,get是对对象的请求。

举例有一个蛋糕切成8块,对某个蛋糕的请求就是get,而对申请到的蛋糕具体的哪一块就是pin。

spin

中文翻译就是旋转。当前进程不能获得latch,那它会绕着cpu空转(执行一段空循环),而不是放弃cpu。这个过程就叫spin。

什么是latch

latch是sqlserver用来同步资源的手段。这里的同步跟通讯里的同步不是一个意思。如果同步跟资源两个字,大家可以直观理解为——如何保证同一个资源在某个时间只能被一个东西(线程、事务等)访问。

latch在作用上很像一个轻量锁。latch主要作用在内存上。我们数据库中的表,在物理上本质是由很多数据页组成。latch就是作用于如何把页从磁盘加载到内存中,如何在DDL访问数据库的时候同步资源。

当我们发起线程请求的时候,首先这个线程有可能会获得锁。然后找到资源对应的数据页,获取到该数据页的latch以后,才可以在该页中继续搜索到对应的数据行。通过这个流程可以清晰的体会到lock和latch不同的地方。

那么如何获取latch呢,流程就是——请求-SPIN-休眠-请求-SPIN-休眠(如此往复)。为什么要一直spin而不是切时间片呢?因为如果你需要做上下文切换(context switch),那么cpu需要保存节点信息,处理完再原换回来。这种在高并发的场景里,会相当消耗资源,所以选择以spin的方式,直到获取请求的资源 。或者达到_spin_count值,此时会放弃CPU,进行短暂的休眠,再重复刚才的动作。

latch与lock的区别

  • latch作用于内存中,lock作用于数据库对象。
  • latch不存在死锁,lock死锁很正常啦。
  • latch占用时间非常少,lock占用时间由事务决定。

latch分类

分为pagelatch和pageiolatch。他们又有细分,其实是根据缩写来分为不同的状态。不同的场景用不用的latch保证资源同步。例如你把数据页从磁盘读到内存中,这时候需要加PAGELATCH_EX。如果在加载内存完之前需要访问该数据页(因为加载是民异步的,所以该线程可以先去做其他事情),则该线程可以自己给自己加一个PAGELATCH_SH,先等待PAGELATCH_EX释放再去做其他事,同时可以避免在加载完毕前有其他线程过来请求或修改该页。

pagelatch分为

  • PAGELATCH_DT : Destroy buffer page  latch
  • PAGELATCH_EX : Exclusive buffer page  latch
  • PAGELATCH_KP : Keep buffer page  latch
  • PAGELATCH_NL : Null buffer page latch
  • PAGELATCH_SH : Shared buffer page   latch
  • PAGELATCH_UP : Update buffer page latch

pageiolatch细分为

  • PAGEIOLATCH_DT : Destroy buffer page I/O latch
  • PAGEIOLATCH_EX : Exclusive buffer page I/O latch。如果出现在这个状态,表示正在将disk中的数据页加载到内存
  • PAGEIOLATCH_KP : Keep buffer page I/O latch
  • PAGEIOLATCH_NL : Null buffer page I/O latch
  • PAGEIOLATCH_SH : Shared buffer page I/O latch。如果出现在这个状态,表示在加载数据页到内存期间,试图读取内存中的数据页,此时加载数据页的过程没有完成,处于loading状态。如果经常出现PageIOLatch_SH,表明Loading数据页的时间太长,可能出现IO bottleneck。
  • PAGEIOLATCH_UP : Update buffer page I/O latch

 

pagelatch和pageiolatch的区别

pagelatch是为了保证page在buff pool中读写正确。例如,往数据页中插入数据是从空闲位置开始往后写入。若现在有一个数据页A,现在有两个线程都想往页A里插入数据。如果没有pagelatch,那么大家在同一时间读取到的空闲位置都是相同的。那么两个线程在写入的时候,后写入的线程会把先写入的线程写入的东西覆盖。

pageiolatch是为了保证异步访问数据的时候保证数据的一致性。最多的情况就是把数据页从disk加存到memory时。sql server会首先在内存中为这个page空出一块空间,并且加上PAGEIOLATCH_EX ,然后在这个page真正从disk读取到内存当中之前,其他线程不能对这片内存进行操作。因为异步操作,所以这个线程会去访问这个page,此时申请PAGEIOLATCH_SH ,但是与之前的PAGEIOLATCH_EX ,最终导致自己被自己阻塞了。

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章