oracle数据库闩锁锁定与并发专题.doc

Oracle并发和latch专题 Oracle本身是一个多用户并发处理系统,在同一个时间点上,可能会有多个用户同时操作数据库,这就涉及两个重要的问题 1、这些用户之间的操作不会互相破坏,比如两个用户同时在相同的物理位置上写数据时,不能发生互相覆盖的情况,这叫做串行化,也就是说,即便两个用户同时在写,也必须有先后,一个用户写完,另一个用户继续写,串行化会降低系统的并发性,但这对保护数据结构不被破坏来说则是必须的 2、在满足串行化的前提下,如何将并发性提升到最大 Oracle中通过使用闩锁(latch)和锁定(lock) Latch和lock都是实现串行化的方法 latch是一个低级别的,轻量级的锁,获得和释放的速度都很快 lock可能持续很长时间,通过使用队列,先进先出的方式实现 锁的白话意义:一种资源,如果可能发生多个进程同时访问的情况,造成资源的破坏,那么就需要给这种资源上一个锁,如果这种资源很简单,例如就是内存的分配和释放,那么就使用latch,如果这种资源相对复杂,有一定的逻辑判断,那么就需要使用lock 资源的意义很广泛,因为进程总是通过内存来做修改、读取,因此资源都分布在内存中。 闩锁的概述(latch) Oracle使用闩锁来实现内存的分配和释放 例如 某个用户进程A发出一条update语句,要去更新58号数据块里的某条记录,则该用户进程对应的服务器进程在写内存的时候,找到58号数据块,并往里写内容,A在写58号数据块的过程中,这时另外一个用户进程B发出insert语句,要将某个新的记录插入到58号数据块中,如果没有一定的保护机制,A正要写入的空间可能被B抢先写入,B要写入的空间可能被A抢先写入,不管哪个用户先抢先写入,造成的结果就是,58号数据块的数据都混乱了 如果使用latch来进行保护,简单的描述,任何进程要写数据块时,都必须先获得latch,在写入过程中,一直持有latch,写完以后,释放latch 当A在写入58号数据块的时候,先获得latch,B也要写58号数据块,这时B尝试获得latch,发现该latch被A持有,B进入等待状态,直到A释放latch,B获得latch以后,才能在58号数据块中写入数据 Latch用来锁住内存中的数据结构的,例如buffer,share pool,只要访问就有锁,因此latch是快速的锁,latch锁的是资源不是数据块,latch保护的是资源的分配和释放 不只是写数据块需要使用latch,shared pool中就没有数据块。 凡是涉及内存的读和写,就需要通过获得latch来实现,一次只能有一个服务器进程在读或写内存。 Oracle在实例管理中,不管是buffer cache、shared pool还是log buffer,都引入了各种各样的latch。 可以这样来理解latch,通过某个变量值的变化来实现,变量值为0则说明latch没有被其它进程获取,变量值为非0则说明latch被其他进程获取 Latch是以微妙来计算的(百万分之一秒),操作非常快 凡是涉及内存里的某个地址读写的,都要涉及到latch 所谓轻量级锁,就是实现非常的简单,起的作用也是非常的初级。 Latch 分为两种类型 1、愿意等待(willing – to - wait) 大部分的latch都属于这种 这种类型的latch都是通过test-and-set的方式获得的,也就是说,如果当前进程不能获得latch的时候,会绕着CPU旋转,而不放弃CPU,这就是所谓的SPIN CPU 实际上就是执行一段空循环,通过执行空循环,一只占用着CPU 1、进程没有获得latch,为什么还要占用着CPU呢?因为latch本身是一个很快速的动作,因此可能等一会就能够获得latch,进程一旦获得CPU,但是没有获得latch,如果放弃CPU,那么需要进行上下文的切换,下次再次尝试获得latch时,又要进行上下文切换,可能消耗更多的时间,因此进程不能获得CPU的时候,会通过执行一段空代码绕着CPU转,然后再次尝试获得latch。 2、如果仍然不能够获得,继续旋转,当反复旋转CPU并尝试获得latch的次数超过某个上限时(该上限由隐藏参数控制),这时进程会释放CPU,并进入sleep状态,进程一旦进入sleep状态,就会抛出一个等待事件,并记录在v$session_wait里,进程正在等待latch的信息会出现在这个视图中 3、一个进程会睡眠0.01秒,然后醒来,并再次尝试获得latch,如果旋转CPU的次数达到上限值,仍然不能获得latch,则再次进入睡眠,这时会睡眠两倍的时间,以此类推,直到达到睡眠的最大值:0.2秒 上面的情况是数据库服务器具有多个CPU的情况,如果只有一个CPU,就不存在旋转CPU的情况,一旦获得

文档评论(0)

1亿VIP精品文档

相关文档