达梦8技术支持笔记(3)
1、闩锁 线程控制,内存结构,占用完成后自动释放,分为两种类型:
1、愿意等待(WILLING-TO-WAIT)
大部分LATCH都属于这种, 这种类型的LATCH都是通过TEST-AND-SET的方式获得的, 也就是说, 如果当前进程不能获得LATCH的时候会绕着CPU旋转, 而不放弃CPU, 这就是SPIN CPU。实际上就是执行一段空循环, 通过执行空循环, 一直占用着CPU。具体执行过程如上述。
2、不等待(NO-WAIT)
这种类型的LATCH较少, 对于这种类型的LATCH来说, 都会有很多个可用的LATCH。 当一个进程请求其中的一个LATCH时, 会以NO-WAIT模式开始请求, 如果所请求的LATCH不可用, 则进程不会等待, 而是立即请求另外一个LATCH, 只有当所有的LATCH都不能获得的时候, 才会进入等待。适用于存在多个可用LATCH时, 消耗资源较少。
进程获取Latch的详细过程
任何时候,只有一个进程可以访问内存中的某一个块(9I提出的Latch共享我不想考虑),如果进程因为别的进程正占用块而无法获得Latch时,他会对CPU进行一次spin(旋转),时间非常的短暂,spin过后继续获取,不成功仍然spin,直到spin次数到达阀值限制(这个由隐含参数_spin_count指定),此时进程会停止spin,进行短期的休眠,休眠过后会继续刚才的动作,直到获取块上的Latch为止。进程休眠的时间也是存在算法的,他会随着spin次数而递增,以厘秒为单位,如1,1,2,2,4,4,8,8,。。。休眠的阀值限制由隐含参数_max_exponential_sleep控制,默认是2秒,如果当前进程已经占用了别的Latch,则他的休眠时间不会太长(过长会引起别的进程的Latch等待),此时的休眠最大时间有隐含参数_max_sleep_holding_latch决定,默认是4厘秒。这种时间限制的休眠又称为短期等待,另外一种情况是长期等待锁存器(Latch Wait Posting),此时等待进程请求Latch不成功,进入休眠,他会向锁存器等待链表(Latch Wait List)压入一条信号,表示获取Latch的请求,当占用进程释放Latch时会检查Latch Wait List,向请求的进程传递一个信号,激活休眠的进程。Latch Wait List是在SGA区维护的一个进程列表,他也需要Latch来保证其正常运行,默认情况下share pool latch和library cache latch是采用这个机制,如果将隐含参数_latch_wait_posting设置为2,则所有Latch都采用这种等待方式,使用这种方式能够比较精确的唤醒某个等待的进程,但维护Latch Wait List需要系统资源,并且对Latch Wait List上Latch的竞争也可能出现瓶颈。
如果一个进程请求,旋转,休眠Latch用了很长时间,他会通知PMON进程,查看Latch的占用进程是否已经意外终止或死亡,如果是则PMON会清除释放占用的Latch资源。
2、TempDB配置
在默认配置里运行TempDb,数据文件初始大小有8M,对于事务日志是1M。2个文件都设置为10%的自动增长。这个配置会带来几个问题:
太多超时的自动增长操作
日志文件碎片
闩锁竞争(Latch contention)
我们来详细看下这些问题。使用默认的8M的初始大小,你的TempDb使用昂贵的自动增长操作会有超时增长。如果你知道你的TempDb在大小上需要一定的MB,你需要把它设置为初始大小,因为在Server启动期间,TempDb总从model数据里重新创建。那个方式你可以避免自动增长操作。如果你依赖于自动增长设置,你也应该使用固定大小,而不是百分比值。这也允许你估计自动增长操作需要花费的时间。使用百分比值,基于当前你的文件大小会花费越来越长的时间。
你也需要仔细TempDd的事务日志的大小,因为那里自动增长操作是非常昂贵的。对于任何事务日志,Server不能使用即时文件初始化(Instant File Initialization)。这意味着在事务日志的自动增长期间,你的数据库不能访问事务。对于性能关键系统,在事务日志上的自动增长操作基本是不可行的。
最后你也会碰到TempDb里的闩锁竞争问题,因为只有一个数据文件可用。当Server在TempDb里分配新对象时,Server需要读取特定页(SGAM,GAM,PFS)。这些页在去写期间必须被竞争。当你运行高度依赖于TempDB的工作时,在TempDb里这些热页上会有竞争问题。
这个问题的解决方法是对于TempDb使用多个数据文件,因为那时Server会通过多个数据文件使用循环分配算法(Round-Robin allocation algorithm),它会减少闩锁竞争问题。如果你使用多个数据文件,你也需要确保初始大小(一个可能的自动增长值)设置为一样的值,这样的话它们会同时增长。
3、简单优化。
加大buffer,不要频发commit,修改应用中同时对几张热表的频繁操作,调整hash链,打散热链。

浙公网安备 33010602011771号