精华内容
下载资源
问答
  • 什么是闩锁;闩锁的使用;MUTLI-LATCH;LATCH的模拟算法;LATCH相关的时间开销;调整_SPIN_COUNT;闩锁使用的例子;如何发现闩锁等待;LATCH分析的主要思路;一种特殊的闩锁-MUTEX;STATSPACK/AWR报告;闩锁总体情况;闩锁休眠...
  • 什么是闩锁效应?

    千次阅读 2014-04-25 18:06:39
    闩锁效应CMOS工艺所特有的寄生效应,严重会导致电路的失效,甚至烧毁芯片。闩锁效应由NMOS的有源区、P衬底、N阱、PMOS的有源区构成的n-p-n-p结构产生的,当其中一个三极管正偏时,就会构成正反馈形成闩锁。避免...

      原文出自:http://blog.163.com/lai_laite/blog/static/77510524200853942235/

    闩锁效应是CMOS工艺所特有的寄生效应,严重会导致电路的失效,甚至烧毁芯片。闩锁效应是由NMOS的有源区、P衬底、N阱、PMOS的有源区构成的n-p-n-p结构产生的,当其中一个三极管正偏时,就会构成正反馈形成闩锁。避免闩锁的方法就是要减小衬底和N阱的寄生电阻,使寄生的三极管不会处于正偏状态。

       静电是一种看不见的破坏力,会对电子元器件产生影响。ESD 和相关的电压瞬变都会引起闩锁效应(latch-up)是半导体器件失效的主要原因之一。如果有一个强电场施加在器件结构中的氧化物薄膜上,则该氧化物薄膜就会因介质击穿而损坏。很细的金属化迹线会由于大电流而损坏,并会由于浪涌电流造成的过热而形成开路。这就是所谓的“闩锁效应”。在闩锁情况下,器件在电源与地之间形成短路,造成大电流、EOS(电过载)和器件损坏。

       MOS工艺含有许多内在的双极型晶体管。在CMOS工艺下,阱与衬底结合会导致寄生的n-p-n-p结构。这些结构会导致VDD和VSS线的短路,从而通常会破坏芯片,或者引起系统错误。
     例如,在n阱结构中,n-p-n-p结构是由NMOS的源,p衬底,n阱和PMOS的源构成的。当两个双极型晶体管之一前向偏置时(例如由于流经阱或衬底的电流引起),会引起另一个晶体管的基极电流增加。这个正反馈将不断地引起电流增加,直到电路出故障,或者烧掉。
     可以通过提供大量的阱和衬底接触来避免闩锁效应。闩锁效应在早期的CMOS工艺中很重要。不过,现在已经不再是个问题了。在近些年,工艺的改进和设计优化已经消除了闩锁的危险。


    展开全文
  • 闩锁超时故障排除翻译自:https://mssqlwiki.com/2012/09/07/latch-timeout-and-sql-server-latch/在一个多线程的进程里,当一个线程在内存里更新一个数据或索引页,而另一个线程正在读取相同的页,将会发生什么?...

    SQL Serer闩锁 和 闩锁超时故障排除

    翻译自:https://mssqlwiki.com/2012/09/07/latch-timeout-and-sql-server-latch/


    在一个多线程的进程里,当一个线程在内存里更新一个数据或索引页,而另一个线程正在读取相同的页,将会发生什么?

    当第一个线程在内存里读取一个数据或索引页,而第二个线程正在从内存里释放相同的页,将会发生什么?

    答案是:我们将获得数据或数据结构不一致的结果。为了避免不一致,SQL Server使用同步机制像锁(Locks)、闩锁(Latches)和自旋锁(Spinlocks)。

    在这篇博文里,我们将讨论关于闩锁的一些关键点和如何排除闩锁超时dump故障。

    什么是闩锁(Latch)?

    它们通过多线程控制对数据页和结构的并发访问。闩锁提供数据页的物理数据一致性,并提供数据结果的同步。闩锁不可以像锁一样被用户控制。

    闩锁的类型:

    Buffer(BUF) Latch
    用于同步访问BUF结构和它们相关的数据库页。

    Buffer "IO" Latch
    Buffer Latch的一个子集,用于当BUF和相关的数据/索引页正在一个IO操作(从磁盘读取页或者写入页到磁盘)中间时。

    Non-Buffer(Non-BUF) Latch
    这些闩锁被用于同步一般的内存中数据结构,这些结构通常被并行线程、自动增长操作和收缩操作等查询/任务执行所使用。

    闩锁模式:

    Keep(KP) Latches
    用于确保当页面正在使用时,不会从内存释放。

    Shared(SH) Latches
    用于对数据结构的只读访问,和阻止其他线程的写访问。
    这个模式允许共享访问。
    SH可兼容于KP、SH和UP。应该注意的是,尽管通常SH表明了只读访问,但不总是这样。对于Buffer Latches,SH是为了读取一个数据页的最小模式要求。

    Update(UP) Latches
    允许对数据结构(兼容于SH和KP)的读访问,但是阻止其他EX-latch访问。
    当页分裂检测关闭并且当AWE没有启用时用于写操作。

    Exclusive(EX) Latches
    阻止发生在被闩锁结构上的读取活动。EX只兼容于KP。
    当页分裂检测开启或者AWE启用时在读IO和写IO期间。

    Destroy(DT) Latches
    用于当从Buffer Pool移除BUFS,要么通过添加它们到空闲列表,要么取消映射AWE Buffers。

    闩锁兼容性:

          KP     SH     UP     EX     DT
    KP     Y     Y     Y     Y     N
    SH     Y     Y     Y     N     N
    UP     Y     Y     N     N     N
    EX     Y     N     N     N     N
    DT     N     N     N     N     N

    如何识别闩锁争用?

    闩锁争用可以通过在sysprocesses里的等待类型来识别。

    PAGEIOLATCH_*:
    这个sysprocesses里的等待类型表明SQL Server正在等待一个Buffer Pool页的物理I/O完成。
        1.PAGEIOLATCH_*通常通过调优查询来解决,该查询会执行大量的IO操作(通常通过添加、修改和移除索引或统计信息来介绍物理IO数量)。
        2.识别是否有磁盘瓶颈并修复它们(PAGEIOLATCH等待时间(例如大于30ms))。

    PAGELATCH_*:
    这个sysprocesses里的等待类型表明SQL Server正在等待访问一个数据库页,但是该页没有经历物理IO。
        1.这个问题通常由在同一时间试图访问相同物理页的大量会话导致。你有应该查看spid的等待资源。这个wait_resource是被访问的页号(格式是dbid:file:pageno)。
        2.我们可以使用DBCC PAGE来识别对象或者发生争用的页类型。它也帮助我们确定是否争用是用于分配、数据或文本。
        3.如果SQL Server最频繁等待的页面在tempdb数据库,在dbid为2对于一个页号检查等待资源列。你可能面临着在这里提到的tempdb闩锁争用:http://support.microsoft.com/kb/328551
        4.如果页在一个用户数据库,检查是否表在一个单调键像标识列上有一个聚集索引,所有的线程正在争用表末尾的相同页。在这种情况下,我们需要选择一个不同的聚集索引键,将工作分散到不同的页。

    LATCH_*:
    Non-buf闩锁等待可以被各种事情导致。我们可以在sysprocesses里使用这个等待资源列来确定包含的闩锁类型(KB 822101)。
        1.一个非常普通的LATCH_EX等待是由于运行一个Profiler跟踪或者sp_trace_getdata参考KB 929728获取更多信息。
        2.自动增长和自动收缩。

    当一个闩锁被线程请求,并且如果由于其他线程在相同的页或数据结构上持有一个不兼容的闩锁,而这个闩锁不能被立即授予,那么这个请求者必需等待闩锁可被授予。如果等待间隔达到5分钟(waittime 300),类似以下的一条警告信息在SQL Server错误日志中输出,并且所有线程的一个mini dump被捕获。警告信息对buffer和non-buffer latches有所区别。

    844: Time out occurred while waiting for buffer latch — type %d, bp %p, page %d:%d, stat %#x, database id: %d, allocation unit id: %I64d%ls, task 0x%p : %d, waittime %d, flags 0x%I64x, owning task 0x%p.  Continuing to wait.
    846: A time-out occurred while waiting for buffer latch — type %d, bp %p, page %d:%d, stat %#x, database id: %d, allocation unit Id: %I64d%ls, task 0x%p : %d, waittime %d, flags 0x%I64x, owning task 0x%p. Not continuing to wait.
    847: Timeout occurred while waiting for latch: class ‘%ls’, id %p, type %d, Task 0x%p : %d, waittime %d, flags 0x%I64x, owning task 0x%p. Continuing to wait.


    拆分以上警告

    类型(type):
    当前闩锁获取请求的闩锁模式。这个一个使用如下匹配的numerical值:
    0 – NL (not used); 1 – KP; 2 – SH; 3 – UP; 4 – EX; 5 – DT.

    任务(task):
    我们尝试得到闩锁的任务。

    等待时间(Waittime):
    等待闩锁获取请求的以秒为单位的总时间。

    拥有的任务(owning task):
    可用的拥有闩锁的任务地址。

    bp(只有Buffer latches):
    与Buffer latch对应的BUF结构的地址。

    page(只有Buffer latches):
    对于当前包含在BUF结构中的页的页ID。

    database id(只有Buffer latches):
    对于在BUF里的页的数据库ID。

    像排除SQL Server里的阻塞问题一样,当有一个闩锁争用或者超时dump,识别闩锁的所有者并故障排除为什么闩锁被该所有者长时间持有。

    当有闩锁超时dump,你可以看到类似以下一个的警告信息。在dump是非常重要的用于找到闩锁的所有者线程之前,警告错误信息打印在SQL Server错误日志里。

    2012-01-18 00:52:03.16 spid69      A time-out occurred while waiting for buffer latch — type 4, bp 00000000ECFDAA00, page 1:6088, stat 0x4c1010f, database id: 4, allocation unit Id: 72057594043367424, task 0x0000000006E096D8 : 0, waittime 300, flags 0x19,
    owning task 0x0000000006E08328. Not continuing to wait.
    spid21s     **Dump thread – spid = 21, PSS = 0x0000000094622B60, EC = 0x0000000094622B70
    spid21s     ***Stack Dump being sent to E:\Data\Disk1\MSSQL.1\MSSQL\LOG\SQLDump0009.txt
    spid21s     * *******************************************************************************
    spid21s     * BEGIN STACK DUMP:
    spid21s     *   02/28/12 00:32:03 spid 21
    spid21s     * Latch timeout
    Timeout occurred while waiting for latch: class ‘ACCESS_METHODS_HOBT_COUNT’, id 00000002D8C32E70, type 2, Task 0x00000000008FCBC8 : 7, waittime 300, flags 0x1a, owning task 0x00000000050E1288. Continuing to wait.
    Timeout occurred while waiting for latch: class ‘ACCESS_METHODS_HOBT_VIRTUAL_ROOT’, id 00000002D8C32E70, type 2, Task 0x00000000008FCBC8 : 7, waittime 300, flags 0x1a, owning task 0x00000000050E1288. Continuing to wait.

    从以上错误信息,我们可以很容易理解,我们正尝试在数据库ID为4,页1:6088(第一个文件的6088页)请求闩锁,并且因为任务0x0000000006E08328(在警告信息中拥有任务0x0000000006E08328)正在它上面持有一个闩锁而超时。

    注意:任务只是被线程执行的一个工作请求。(就像system task、login task和ghost cleanup task等)。执行这个任务的线程将按需持有需要的闩锁。

    让我们看看如何分析闩锁超时dump和使用拥有任务0x0000000006E08328获取闩锁的拥有线程。

    去分析dump,从这里http://sdrv.ms/MO6ytG下载和安装Windows Debugger。

    步骤1:
    打开Windbg。选择“File”菜单,选择“Open crash dump”,选择“Dump file”(SQLDump000#.mdmp)。

    步骤2:
    在命令行窗口输入
    .sympath srv*c:\Websymbols*http://msdl.microsoft.com/download/symbols;

    步骤3:
    输入.reload /f并回车。这将强制debugger立即加载所有的符号。

    步骤4:
    通过使用debugger命令lmvm验证是否符号被SQL Server加载。

    0:002> lmvm sqlservr
    start             end                 module name
    00000000`01000000 00000000`03679000   sqlservr T (pdb symbols)          c:\websymbols\sqlservr.pdb\21E4AC6E96294A529C9D99826B5A7C032\sqlservr.pdb
        Loaded symbol image file: sqlservr.exe
        Image path: C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\Binn\sqlservr.exe
        Image name: sqlservr.exe
        Timestamp:        Wed Oct 07 21:15:52 2009 (4ACD6778)
        CheckSum:         025FEB5E
        ImageSize:        02679000
        File version:     2005.90.4266.0
        Product version:  9.0.4266.0
        File flags:       0 (Mask 3F)
        File OS:          40000 NT Base
        File type:        1.0 App
        File date:        00000000.00000000
        Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4

    步骤5:
    使用以下命令来搜索线程堆栈来识别与拥有的任务相关的线程,并且它是拥有闩锁的线程。在你的错误日志里使用拥有的任务替代0X0000000006E08328
    ~*e .echo ThreadId:; ?? @$tid; r? @$t1 = ((ntdll!_NT_TIB *)@$teb)->StackLimit; r? @$t2 = ((ntdll!_NT_TIB *)@$teb)->StackBase; s -d @$t1 @$t2 0X0000000006E08328

    ThreadId:
    unsigned int 0x93c
    ThreadId:
    unsigned int 0x9a0
    ThreadId:
    unsigned int 0x9b4
    00000000`091fdaf0  06e08328 00000000 00000000 00000000  (……………
    00000000`091fdcb8  06e08328 00000000 091fdd70 00000000  (…….p…….
    00000000`091fded0  06e08328 00000000 06e0e798 00000000  (……………
    00000000`091fdf38  06e08328 00000000 00000002 00000000  (……………
    00000000`091fec60  06e08328 00000000 0168883a 00000000  (…….:.h…..
    00000000`091ff260  06e08328 00000000 000007d0 00000000  (……………
    00000000`091ff2d0  06e08328 00000000 00000020 00000000  (……. …….
    00000000`091ff5f8  06e08328 00000000 800306c0 00000000  (……………
    00000000`091ff6c0  06e08328 00000000 00000000 00000000  (……………
    00000000`091ff930  06e08328 00000000 00000000 00000001  (……………
    00000000`091ff9b8  06e08328 00000000 00000000 00000000  (……………
    00000000`091ffa38  06e08328 00000000 00000000 00000000  (……………
    00000000`091ffc10  06e08328 00000000 03684080 00000000  (……..@h…..
    00000000`091ffc90  06e08328 00000000 00000000 00000000  (……………
    ThreadId:
    unsigned int 0x9b8
    ThreadId:
    unsigned int 0x9bc
    ThreadId:
    unsigned int 0x9c0
    ……………
    …………..

    步骤6:
    从以上输出,我们可以看到线程0x9b4与拥有的任务的指针相关,并且它是拥有闩锁的线程。让我们切换到线程(0x9b4),它正在执行拥有的任务,然后浏览这个堆栈来查看为什么这个线程长时间持有闩锁。

    步骤7:
       ~~[0x9b4]s      ==> Switching to the thread (Replace 0x9b4 with your thread id which has reference to the po
    ntdll!ZwWaitForSingleObject+0xa:
    00000000`77ef047a c3              ret

    步骤8:
    0:002> kC  ==>  Print the stack
    Call Site
    ntdll!ZwWaitForSingleObject
    kernel32!WaitForSingleObjectEx
    sqlservr!SOS_Scheduler::SwitchContext
    sqlservr!SOS_Scheduler::Suspend
    sqlservr!SOS_Event::Wait
    sqlservr!BPool::FlushCache
    sqlservr!checkpoint2
    sqlservr!alloca_probe
    sqlservr!ProcessCheckpointRequest
    sqlservr!CheckpointLoop
    sqlservr!ckptproc
    sqlservr!SOS_Task::Param
    ::Execute
    sqlservr!SOS_Scheduler::RunTask
    sqlservr!SOS_Scheduler::ProcessTasks
    sqlservr!SchedulerManager::WorkerEntryPoint
    sqlservr!SystemThread::RunWorker
    sqlservr!SystemThreadDispatcher::ProcessWorker
    sqlservr!SchedulerManager::ThreadEntryPoint
    msvcr80!endthreadex
    msvcr80!endthreadex

    从以上堆栈,我们可以理解,拥有闩锁的线程正执行检查点并刷新缓存(脏页)到磁盘。如果刷新缓存到磁盘(检查点)花费很长时间,那么显然是有磁盘瓶颈。

    类似的,对于其他闩锁超时问题,首先识别闩锁的拥有者线程,读取拥有者线程的堆栈,来理解拥有者线程执行的任务,并排除由拥有者线程执行的任务引起的性能故障。

    如果你想查看等待的线程的堆栈,那么在错误日志里从闩锁超时警告信息获取任务(任务0x0000000006E096D8)代替拥有者任务(任务0x0000000006E08328),并使用在步骤5中提到的命令。

    我希望这篇博文将帮助你学习和排除闩锁超时故障。

    展开全文
  • 闩锁是SQL Server存储引擎使用轻量级同步对象,用来保护多线程访问内存内结构。文章的第1部分我会介绍SQL Server里为什么需要闩锁,在第2部分我会给你介绍各个闩锁类型,还有你如何能对它们进行故障排除。 为什么...
  • ORACLE 闩锁介绍

    2011-10-16 22:52:26
    不同点是:闩锁是一个低级别,轻量级的锁,获得和释放的速度非常快。而锁定则持续的时间较长,通过队列,按照先进先出的方式实现。可以这么说:闩锁是微观领域的,锁定则是宏观领域的。  那闩锁到底起的是什么作用...

           oracle通过闩锁(latch)和锁定(lock)来实现资源的串行化。闩锁和锁定相同点是:都是用于实现保护数据的完整与准确性。不同点是:闩锁是一个低级别,轻量级的锁,获得和释放的速度非常快。而锁定则持续的时间较长,通过队列,按照先进先出的方式实现。可以这么说:闩锁是微观领域的,锁定则是宏观领域的。

          那闩锁到底起的是什么作用?这么说吧,只要涉及到内存地址的读和写,都需要通过获得闩锁(latch)来实现串行化。一次只能有一个服务器进程读或者写内存地址,这样就保证了存放在该内存地址数据的准确性。

          一个会话请求闩锁的时候,有可能这个闩锁正被其他会话占用。这个时候是否选择等待取决于你以什么模式请求闩锁,如果选择willing to wait(愿意等待),我们的会话就会睡眠一段时间继续请求。如果选择immediate(立即),我们的会话就会做其他的事情(比如获取另外一个相当的空闲闩),而不是等待这个闩直到可用。

          由于一个闩可能有很多会话在等待其变得可用,这些等待者是否会排队呢,比如先等的排在前面?其实这个不会,这些等待者是在不断重复请求这个闩锁的,一旦这个闩锁被释放,最先请求的就会先得到。

         那这些等待者是如何进行等待的呢?其实等待闩锁是一个开销比较大的事情,如果闩锁不可用,我们就得等待。在一台多cpu的机器上(如果单cpu,就没有等待闩锁这一说了),我们的会话就会自旋(spin)。

          什么叫做自旋?就是我们的会话不切出cpu,会一直呆在cpu上,不断循环请求得到这个闩。因为切出cpu,醒来之后又要调入cpu非常浪费时间,而且这个闩的持有者非常有可能正在另外一个cpu上忙于处理,而且会很快释放这个闩。大多数情况,我们的会话会很快得到这个闩的。如果请求很多次之后,还是不能得到这个闩,我们的会话就会进行睡眠,让出cpu。

          由此可以看出,即使有的时候我们的cpu看起来很忙,其实没干多少事情。如果你的程序写得足够糟糕,那cpu大多数的时间在不断循环请求闩锁,其实没干多少实际的工作。这就是为什么写sql语句最好用绑定变量的方法。

          下面我们做一个测试:。我们会把一个编写得很好的程序和一个编写得不太好的程序进行比较,前者使用了绑定变量,而在编写得不好的程序中,每条语句使用了SQL直接量或各不相同的SQL。为此,我们使用了一个很小的Java程序,它只是登录Oracle,关掉自动提交,并通过一个循环执行25 000条不同的INSERT语句。

     

         要评估这些程序以及它们在多用户环境中的行为,我们用Statspack来收集度量信息(什么是statspack参考我的这篇博文:http://liwenshui322.iteye.com/admin/blogs/1183027),

         如下:
    (1) 执行一个Statspack快照来收集系统的当前状态。
    (2) 运行程序的N个副本,每个程序向其自己的数据库表中插入(INSERT),以避免所有程序都试图向一个表中插入而产生的竞争。
    (3) 在最后一个程序副本执行后,紧接着取另一个快照。
    然后只需打印出Statspack报告,并查看完成N个程序副本需要多长时间,使用了多少CPU时间,主要的等待事件是什么,等等。

     

        使用绑定变量java源码:

    package cn.netjava.latch; import java.sql.Connection; import java.sql.PreparedStatement; public class LatchTestMain { public static void main(String args[]) throws Exception{ Connection conn = ConnectOracle.getConn(); conn.setAutoCommit(false); String sql = "insert into latch_test1(id) values(?)"; PreparedStatement ps = conn.prepareStatement(sql); for(int i=0;i<25000;i++){ ps.setInt(1, i); ps.executeUpdate(); } conn.commit(); conn.close(); } }

    
    

     

     

    不使用了绑定变量的java源码

    package cn.netjava.latch; import java.sql.Connection; import java.sql.Statement; public class LatchTestMain { public static void main(String args[]) throws Exception{ Connection conn = ConnectOracle.getConn(); conn.setAutoCommit(false); Statement st = conn.createStatement(); for(int i=0;i<25000;i++){ String sql = "insert into latch_test1(id) values("+i+")"; st.execute(sql); } conn.commit(); conn.close(); } }

     

     

    
    

      

     

     

     

     

      不使用绑定变量与使用了绑定变量Statspack报告对比

     

       不使用绑定变量:

     使用绑定变量:



     

            对比可以看出1S硬解析的次数不是一个数量级的。

     

        不使用绑定变量

       

     
        使用绑定变量



     

       对比可以看出cpu的时间也有很大区别。说明如果不使用绑定变量,大部分时间都会耗在硬解析这项重复没有意义的事情上面。

     

       上面的报告都是单用户模式下(一个用户)。在实际情况当中,肯定是多用户模式了,假如我们一次跑4个程序副本看看报告是什么样子。

       不使用绑定变量

     

     

     

        使用绑定变量

     

     

     

       发现不使用绑定变量的话,随着用户的增加,硬解析次数也增加了。而使用了绑定变量的话,硬解析次数没有什么改变。在这里是0,因为我们以前跑过一次了。

     

      不使用绑定变量

     


     
     使用绑定变量

     


     
     对比单用户模式,不使用绑定变量的话,cpu耗时4用户是单用户的4倍多(理论上应该是4倍,至于多出来的时间,应该是耗在闩自旋上面了。)使用了绑定变量只有3倍。

       以共享池为例,我们来看闩自旋。

       单用户模式不使用绑定变量

      

      

       4用户模式不使用绑定变量

     


     

       很明显,对于shared pool 请求的次数后者是前者的4倍左右,但是Misses次数(请求闩锁失败)要高出好多,屡次请求不到而进入睡眠的也高出好多。由此可以看出,如果不使用绑定变量的话,在数以百计的用户同时访问的时候,简直是自寻死路。 同时访问的用户越多,闩自旋的概率越大,浪费cpu的时间就越多。
     

     

     

     

    展开全文
  • SQL Server里的闩锁介绍

    2017-11-14 15:01:00
    什么我们需要闩锁? 闩锁首次在SQL Server 7.0里引入,同时微软首次引入了行级别锁(row-level ...如我所说的,闩锁是存储引擎使用的轻量级同步对象,是SQL Server用来保护内存结构的。闩锁只不过是类似于多线程编...

    为什么我们需要闩锁?

    闩锁首次在SQL Server 7.0里引入,同时微软首次引入了行级别锁(row-level locking)。对于行级别锁引入闩锁的概念是非常重要的,不然的话在内存中会出现丢失更新(Lost Updates)的现象。如我所说的,闩锁是存储引擎使用的轻量级同步对象,是SQL Server用来保护内存结构的。闩锁只不过是类似于多线程编程里的所谓的临界区(Critcal Section)概念。

    在传统并发编程里,临界区是同时只能一个线程运行的代码。闩锁本身是个临界区的特殊版本,因为它允许多个并发读操作。在SQL Server的上下文里这意味着多个线程可以并发读取一个共享数据结构,例如内存中的页,但是写入共享数据结构必须是单个线程进行。

    闩锁是用来协调数据库里多个线程物理执行,然而锁是基于选择的事务隔离级别,用来逻辑获得需要的隔离级别。作为开发者或DBA的你,你可以用不同方式影响锁——例如通过SQL Server里的隔离级别,或者通过各种可用锁提示。另一方面闩锁是不能以直接方式控制的。在SQL Server里没有闩锁提示,也没有可用闩锁隔离级别。下表是锁和闩锁之间的比较:

                     锁(Locks)         闩锁(Latches)

    • 控制……      事务              线程
    • 保护……    数据库内容          内存中数据结构
    • 模式……     共享的(Shared),      保持(Keep),

                     更新(Update),         共享的(Shared),

                     排它的(Exclusive),     更新(Update),排它的(Exclusive),

                     意向的(Intension)      销毁(Destroy)

    • 死锁…… 检测并解决(detection&resolution)  通过严谨代码来避免
    • 保持在……  锁管理器的哈希表(Hashtable)   保护的数据结构(Protected Data Structure)

    从表里可以看到,闩锁支持更细粒度保持(Keep)和销毁(Destroy)模式。保持闩锁主要用来引用计数,例如当你想知道在指定闩锁上有多少其它闩锁在等待。销毁闩锁是最有限制的一个(它甚至会阻塞保持闩锁),当闩锁被销毁时会用到,例如当惰性写入器(Lazy Writer)想要释放内存中的页时。我们先介绍下各种闩锁模式,然后说下各个闩锁模式的兼容性。

    NL(空闩锁):

    • 内部
    • 未使用

    KP(保持闩锁):

    • 可以由多个任务同时持有
    • 只被一个DT模式的闩锁阻塞

    SH(共享闩锁):

    • 读取数据页的时候使用
    • 可以由多个任务同事持有
    • 阻塞EX模式和DT模式的闩锁

    UP(更新闩锁):

    • 写入系统分配页面和tempdb的行版本化页面时使用
    • 一个这种模式的闩锁只能被一个单独的任务持有

    EX(排它闩锁):

    • 写入数据页的时候使用
    • 一个这种模式的闩锁只能被一个单独的任务持有

    DT(销毁闩锁):

    • 很少使用
    • 一个这种模式的闩锁只能被一个单独的任务持有

     

    在SQL Server里,一致性不能只用锁来获得。SQL Server还是可以访问没被锁管理器保护的共享数据结构,例如页头。还有SQL Server基于闩锁基础的其他组件也是,有单线程代码路径。好了,我们继续讲解SQL Server里的各种闩锁类型,还有如何对它们进行故障排除。

    闩锁类型与故障排除

    SQL Server区分3个不同闩锁类别

    • IO闩锁
    • 缓冲区闩锁(BUF)
    • 非缓冲区闩锁(Non-BUF)

    我们来详细看下这3个不同类别。当在缓冲池的页读写操作未完成——即当你读自/写入你的存储子系统时(2者未同步),SQL Server会使用IO闩锁(I/O Latches)。对于这些I/O闩锁,SQL Server在统计信息里以PAGEIOLATCH_为前缀出现。你可以在DMV sys.dm_os_wait_stats 查看下这些闩锁类型的等待。

    1 SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE 'PAGEIOLATCH_%'

    使用这些闩锁,SQL Server保证那些页不会并发多次读入缓存池,那些页也不会从缓存池忽略,在那些页需要被查询访问的时候。

    除这些I/O闩锁外,SQL Server也支持所谓的缓存区闩锁(Buffer Latches),它用来保护缓冲池里页不会被并发运行的线程影响。这些闩锁,SQL Server使用它们来阻止内存中的丢失更新(Lost Updates)。没有这类闩锁,在缓存池里会有并发的读写页,它们会引发主内存里页的损坏。对于这些缓存闩锁,SQL Server在统计信息里以PAGELATCH_为前缀出现。你可以在DMV sys.dm_os_wait_stats 查看下这些闩锁类型的等待。这里最重要的是你涉及了主内存的竞争,因为他们的等待类型名称里不包含IO字样。

    1 SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE 'PAGELATCH_%'

    最后SQL Server内部使用所谓的非缓存区闩锁(Non-Buffer Latches)来保护除缓冲池外的共享数据结构。对于这些非缓存闩锁,SQL Server在统计信息里以LATCH_为前缀出现。你可以在DMV sys.dm_os_wait_stats 查看下这些闩锁类型的等待。

    1 SELECT * FROM sys.dm_os_wait_stats WHERE wait_type LIKE 'LATCH_%'

    但在这个DMV里这些对于非缓存区闩锁的等待只是SQL Server内部使用的各个闩锁的概况信息,你可以在单独的DMV sys.dm_os_latch_stats找到更详细的信息。

    1 SELECT * FROM sys.dm_os_latch_stats

    SQL Server 2014内部使用163个闩锁来同步共享数据结构的访问。其中一个著名的闩锁是FGCB_ADD_REMOVE,它用来保护文件组的文件组控制阻塞( File Group Control Block (FGCB)),在以下特定操作期间:

    • 文件增长(手动或自动)
    • 增加/删除文件组文件
    • 重新计算填充比重(Recalculating proportional fill weightings
    • 在循环分配期间,通过文件组的文件回收。

    当你看到这个闩锁排在前列是,你肯定有太多自动增长操作的问题,原因是你数据库糟糕的默认配置。当查询尝试读/写保护的数据结构且需要等待一个闩锁时,查询就会进入挂起状态,直到闩锁可以成功获取。因此查询经过的整个查询生命周期包括运行(RUNNING)挂起(SUSPENDED)可运行(RUNNABLE),最后再次运行(RUNNING)。因此,当查询长时间把持闩锁时,强制共享数据结构保护才有意义。那是因为改变查询状态也意味着进行Windows系统里的上下文切换,依据引入的CPU周期是个很昂贵的操作。

    因此对于读写频繁或极短时间内的共享数据结构上放上闩锁没有意义。在这个情况下,需要的上下文切换会杀死SQL Server的整体性能,它需要花费太多的时间来完成整个查询生命周期(运行(RUNNING)挂起(SUSPENDED)可运行(RUNNABLE))。那就是是SQL Server引入的所谓自旋锁(Spinlocks)。锁管理器就是这样数据结构的好例子:当锁定或解锁数据对象(例如记录,页等)时只需要单个线程访问。但当你查看sys.dm_os_latch_stats时,你会发现没有闩锁保护锁管理器本身。锁管理器使用的哈希表里对应的哈希桶使用自旋锁来保护——LOCK_HASH自旋锁通过锁管理器执行锁定和解锁操作前,必须获得自旋锁。但今天我不想再讲解自旋锁了,因为我会在专门的文章里详细介绍——耐心期待下吧:)

    小结

    在这个文章里,我们探讨了SQL Server里的闩锁。如你所见,闩锁是SQL Server使用的轻量级同步对象,用来保存内存里的共享数据结构。SQL Server区分3个不同闩锁类型——IO闩锁,缓存区闩锁和非缓存区闩锁。你也看到了如何使用DMV sys.dm_os_wait_stats sys.dm_os_latch_stats进行闩锁等待的故障排除


    本文转自Woodytu博客园博客,原文链接:http://www.cnblogs.com/woodytu/p/4673814.html,如需转载请自行联系原作者

    展开全文
  • 闩锁效应latch_up

    2015-11-29 13:01:51
    闩锁效应(latch up)CMOS必须注意的现象,latch解释为回路更合适,大家以后看到latch up就联想到在NMOS与PMOS里面的回路。 为什么它这么重要?因为它会导致整个芯片的失效,所以latch upQUAL测试的一种,并且与...
  • 一、什么是锁?这个问题很简单,你一定对锁有一个认识,但你未必对锁有一个明确的定义。官方文档这样描述:Locksare mechanisms that prevent destr...
  • Oracle系列之六

    2011-11-09 23:56:22
    锁是协调对共享资源访问的一种机制。此处共享资源可能是数据行、表或者别的什么很多人都需要访问的资源。 Oracle数据库实现锁的机制跟别的数据库不同,在Oracle数据库中锁并不算的上是稀缺的资源,当然不合适的...
  • 本文主要内容 1.transaction的可串行化 2.数据库并发带来的问题, dirty read, Nonrepeatable reads, Phantoms幻读 ...什么是transaction可串行化 通常,不管数据库初态怎样,一个调度对数据库状态的影响都和某...
  • (lock)和(latch)

    2016-03-02 16:16:00
    开发多用户、数据库驱动的应用时,最大的难点之一:一方面要力争取得最大限度...5.1 什么是锁锁(lock)机制用于管理对共享资源的并发访问。注意,这里说的“共享资源”而不是“数据库行”。Oracle会在行级对表...
  • 开发[b]多用户[/b]、[b]数据库驱动[/b]的应用时,最大的难点之一:一方面要力争取得[b]最大限度的并发[/b]访问,与此同时还要确保每个用户能以[b]一致[/b...[b]5.1 什么是锁[/b] [b](lock)机制用于管理对共享...
  • Mysql(Innodb)中的机制

    2020-07-13 10:22:02
    Innodb中的锁机制什么是锁latchlock行级锁与表级锁锁的分类共享锁和排他锁共享锁排他锁意向锁...latch 一般称为闩锁(轻量级的锁) ,其应用对象为线程,保护的内存数据结构。在InnoDB存储引擎中,latch有可以分为mute
  • mysql中的

    2017-10-17 10:31:26
    什么是锁? 对于一个数据库来说,有两点需要保证,第一速度,第二安全。数据库既要保证能支持高并发的数据访问,...mysql中的锁可以基本划分为lock和latch(闩锁\轻量级的锁),lock分为行锁、表锁、意向锁。 latch
  • InnoDB-

    千次阅读 2021-02-22 13:31:10
    1.什么是锁机制用于管理对共享资源的并发访问。InnoDB会在行级别上对数据上,也会在数据库内部其他多个地方使用,从而允许对多种不同资源提供并发访问。 2.lock 与 latch 在数据库中,lock与latch都可以...
  • InnoDB--

    2018-03-06 10:34:19
    1. 什么是锁 锁是数据库系统区别于文件系统的一个关键特性。锁机制用于管理对共享资源的并发访问。InnoDB存储引擎会在行级别上对表数据上锁。InnoDB存储引擎也会在数据库内部共他多个地方使用锁,从而允对许多种...
  • MySQL进阶-与事务

    2020-06-15 08:59:00
    latch一般称为闩锁(轻量级锁),因为其要求锁定的时间必须非常短。在InnoDB中,latch又可以分为mutex(互斥量)和rwlock(读写锁)。其目的用来保证并发线程操作临界资源的正确性,并且通常没有死锁检测的机制 ...
  • MySQL (lock与latch)

    2019-05-23 19:59:00
    一、什么是锁 锁机制用于管理对共享资源的并发访问,它是数据库系统区别于文件系统的一个关键特性。 数据库系统使用锁是为了支持对共享资源的并发访问,提供数据的完整性和一致性。...1、Latch是闩锁(轻量级的锁...
  • 1.latch一般称为闩锁(轻量级的锁),在InnoDB存储引擎中,latch又可以分为mutex(互斥量)和rwlock(读写锁)。其目的保证并发线程操作临界资源的正确性,并且通常没有检测死锁的机制。 2.lock的对象事务,用来...
  • latch又称为闩锁轻量级锁。又可分为mutex和rwlock。其目的用来保证并发线程操作临街资源的正确性并且没有死锁检测机制。 lock的对象事务,用来锁定的数据库中的对象,如表、页、行。 6.3 InnoDB存储引擎...
  • ORACLE深入分析

    2011-08-19 19:12:34
    1.什么是ORACLE 数据库一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性...
  • 关于oracle mutex和latch的问题

    千次阅读 2010-01-07 14:45:00
    关于latch和mutex的问题From:http://www.itpub.net/thread-1004815-1-1.htmlA:latch是闩锁,是一种串行化机制,用来保护SGA中的内存结构。mutex是什么,也是一种串行化机制,是互斥锁?个人对mutex没有什么概念。这...
  • 我们相当简单的解决方案:我们有一个连接到继电器的树莓派pi,该继电器打开和关闭门上的闩锁,一个磁条阅读器作为键盘设备连接。 当某人刷卡时,将读取事件,对卡数据进行哈希处理,然后将哈希与访问控制文件...
  • Latch-up初认识

    2011-12-26 11:05:00
    在TI芯片SN74CB3T16210的Datasheet里面看到这么一句:Latch-Up Performance Exceeds 250 mA Per JESD17显示对JESD17感兴趣,想找来看下,额,没...lathch-up的一般叫法是闩锁效应,wiki的英文解释:a term used i...

空空如也

空空如也

1 2 3 4
收藏数 63
精华内容 25
关键字:

闩锁是什么