DRM原理及案例探讨
Master节点
•主要作用为调度、协调、管理或者是走流程。主要分为以下几大类:
ØClusterware级别。查看方法如下:
cd $GRID_HOME/log/hostname/cssd
grep -i "master node" ocssd.log | tail -1
Ø全局资源级别。查看方法如下:
查询视图V$GES_RESOURCE.MASTER_NODE
ØDatabase block。查看方法如下:
查询视图V$GCSPFMASTER_INFO.CURRENT_MASTER
Buffer lock
•进程访问buffer前,都需要申请持有buffer lock。Lock mode的兼容性如下:
N | S | X | |
N | Yes | Yes | Yes |
S | Yes | Yes | No |
X | Yes | No | No |
场景:节点之间请求修改数据块
简单流程如下:
1)节点B(申请者)向节点D(主节点)发出请求,要求以X模式锁定块1008。
2) 节点D (主节点)发现节点C(持有者)已经以S模式获得了对应的锁,而且S锁于X锁之间是不兼容的,所以,需要锁的转换,节点D要求节点C将对应的锁级别降低为N,所得属性为NL0。
3) 节点B将自己的锁降级,并且将本地的块1008 标识为CR。之后,节点B将块1008 修改为块1009,同时将通知节点D锁的属性为XL0。
•主节点在持有者节点和申请者节点之间不停地调度、传递消息
•如果锁的角色是全局(数据块在其他远程节点buffer里被修改过),那么我们要做的事情更多,也意味着访问的代码深度也越深
DRM(Dynamic Resource management)
•指定时间内(默认10分钟,受_gc_policy_time 控制),对某一个数据库对象的 (10gR1以数据文件为单位)的访问次数和方式,来决定数据库对象对应的block应该被mastering 到哪一个实例
•指定时间内,如果某一个实例访问某个数据库对象次数高于其他实例一定倍数(默认50倍,受_gc_affinity_ratio控制),则oracle 会把这个对象所有的buffer的master信息,转移到对应实例
注意:
•DRM的过程是渐进式的。
•请不要修改以上参数的值,除非您很清楚自己在做什么。
•Remaster数据块的过程如下(可能不完善):
(1) Oracle停止所有在需要进行remastering的buffer上的操作
(2)LMD0进程读取等待remaster数据块队列
(3)GRD(Global Resource Directory)内存结构可能会frozen
(4)LMON进程通知所有实例协调LMS进程进行reconfigration
(5)在旧的master实例清除对应buffer的master信息
(6)将master信息传递给新的master实例
(7)在新的master实例构建资源的最新状态
(8)结束,并释放所有之前所有步骤占用的资源
再次强调:
DRM进行remaster时,转移的并不是块本身,而是master节点。通过master节点可以知道当前哪个节点在访问这个块,访问时的lock mode是什么。
•数据块的Master节点信息保存在内存结构中,实例重启也就意味着失效。DRM重构风暴?没听说过。
•在reconfiguration或者繁忙的系统中,GRD可能会处于frozen状态(Bug 14641937/14618938),所以remaster时系统可能会短时间hang(Oracle一直在改进该算法,可是。。。)
DRM的应用场景
•如果是应用分离,那么最好使用DRM特性。
•如果是负载均衡,那么建议关闭DRM特性。
•DRM相关的bug让人防不胜防(数据库宕机,节点驱逐, 数据库挂起, ORA-00600),其bug列表如下:
•关闭DRM特性(请谨慎评估,三思而后行)
ØOracle 10g中,设置如下参数:
_gc_affinity_time=0
_gc_undo_affinity=FALSE
或者(实时生效,不需要重启实例)
_gc_affinity_limit=10000000
_gc_affinity_minimum=10000000
ØOracle 11g中,设置如下参数:
_gc_policy_time=0
也可关闭DRM的局部特性(这个很重要):
_gc_read_mostly_locking=false
_gc_bypass_readers=false
进一步解析DRM
•跟BUFFER CACHE的访问机制类似,ORACLE会使用HASH 算法来决定每个BLOCK的MASTER是哪个节点(可以查询内部视图x$kjbl、x$le)
•默认情况下,HASH产生的BUCKET是 128(由隐含参数_lm_contiguous_res_count 决定)
案例:DRM引起的select hang
•案例背景:
ØAIX主机,数据库版本为10.2.0.4,2节点RAC
Ø业务主要在1号节点运行,2号节点处于空闲状态
Ø1号节点在create table之后马上进行全表select,不定时出现hang
ØHang的时间段为凌晨,主机资源和数据库资源非常空闲
•解决思路:
Ø同时对hang进程进行10046 level 12跟踪。跟踪结果显示如下:
WAIT #3: nam='i/o slave wait' ela= 12313 msg ptr=2 p2=56 p3=2147483647 obj#=98754 WAIT #3: nam='db file scattered read' ela= 14260 file#=4 block#=142603 blocks=126 obj#=98754 WAIT #3: nam='gc cr multi block request' ela= 2859 file#=4 block#=142803 class#=1 obj#=98754 WAIT #3: nam='gc cr multi block request' ela= 6321 file#=4 block#=142820 class#=1 obj#=98754 WAIT #3: nam='gc cr multi block request' ela= 2262 file#=4 block#=142841 class#=1 obj#=98754 WAIT #3: nam='gc cr multi block request' ela= 6427 file#=4 block#=142847 class#=1 obj#=98754 WAIT #3: nam='i/o slave wait' ela= 11540 msg ptr=2 p2=56 p3=2147483647 obj#=98754 WAIT #3: nam='db file scattered read' ela= 13207 file#=4 block#=142731 blocks=126 obj#=98754 |
•解决办法:
Ø使用oradebug命令手动remaster表:
oradebug lkdebug -m pkey
Ø将oradebug写进ddl triger中
诊断DRM的故障流程:
(1)查看 lmon,lmd,lms和diag进程的trace file
(2)查看AWR/ASH报告
(3)使用hanganalyze和systemstate:
sqlplus '/ as sysdba'
oradebug setorapname reco
oradebug unlimit
oradebug -g all hanganalyze 3
oradebug -g all hanganalyze 3
oradebug -g all dump systemstate 266
oradebug -g all dump systemstate 266
exit