DRM 分析及案例讲解

什么是DRM

DRM(Dynamic Resource management)是oracle10.10.2里面推出来的一个新特性,一直到现在最新的12cR1,都存在,且bug非常多而著称。在10gR1 RAC是每个实例都有其自己的SGA和buffer cache。RAC为了确保这些块发生时的最大化性能,确保数据完整。每个缓冲区副本也称为缓存资源有一个主要的将做为一个主要的集群节点。在数据库版本10g(10.1.0.2)一个主要的缓存资源负责掌管一个实例,re-mastering或改变主节点只会发生在重新配置,会自动在两个正常操作实例启动或实例关闭,异常节点集群管理器将对其进行逐出。因此,如果节点B这个时候作为一个主缓存的资源,这个资源仍将掌握在节点B直到重新配置。10g中引入了一个新概念,通过DRM资源进行remaster。与DRM资源可以在另一个节点上重新优化,从节点B节点如果发现更频繁地访问缓存资源从节点a重新配置不再是资源重新优化的唯一原因。

到10gR2是基于相关对象的,下面是DRM的跟踪trace文件,在Oracle日志中的LMD进程信息里面。

Sample LMD trace file during a DRM operation

Begin DRM(202) - transfer pkey 4294951314 to0 oscan 1.1
*** 2006-08-01 17:34:54.645
Begin DRM(202) - transfer pkey 4294951315 to 0 oscan 1.1
*** 2006-08-01 17:34:54.646
Begin DRM(202) - transfer pkey 4294951316 to 0 oscan 1.1
*** 2006-08-01 17:34:54.646
Begin DRM(202) - transfer pkey 4294951317 to 0 oscan 1.1

remastering的发生:

Remastering问题发生时会影响性能。以下AWR报告显示了DRM重配置问题导致的实例冻结。同样类型的冻结在其它的所有节点上也都可以看见。gc buffer busy等待只是DRM冻结的副作用(不是总有,但是在这个case是这样)。

Top5 Timed Events                                        Avg%Total
~~~~~~~~~~~~~~~~~~ wait Call
Event Waits Time(s) (ms) TimeWait Class
------------------------------ ------------ ----------- ------ ------ ----------
gc buffer busy 1,826,073 152,415 83 62.0 Cluster
CPUtime 30,192 12.3
enq: TX - indexcontention 34,332 15,535 453 6.3 Concurrenc
gcs drm freeze inenter server 22,789 11,279 495 4.6 Other
enq: TX - row lock contention 46,926 4,493 96 1.8 Applicatio
?

在同一时刻,DRM大量发生,导致了重复的DRM冻结、实例重配置,从而引发严重的性能问题。

 Top 5 Timed Events                                         Avg %Total
~~~~~~~~~~~~~~~~~~ wait Call
Event Waits Time (s) (ms) Time Wait Class
------------------------------ ------------ ----------- ------ ------ ----------
latch: cache buffers lru chain 774,812 140,185 181 29.7 Other
gc buffer busy 1,356,786 61,708 45 13.1 Cluster
latch: object queue header ope 903,456 55,089 61 11.7 Other
latch: cache buffers chains 360,522 49,016 136 10.4 Concurrenc
gc current grant busy 112,970 19,893 176 4.2 Cluster

可以看到,TOP 5中,有3个是latch相关的等待,而另外2个则是跟RAC相关的等待。
如果再查看更细的等待数据,可以发现其他问题:

                                                   Avg
%Time Total Wait wait Waits
Event Waits -outs Time (s) (ms) /txn
---------------------------- -------------- ----- ----------- ------- ---------
latch: cache buffers lru cha 774,812 N/A 140,185 181 1.9
gc buffer busy 1,356,786 6 61,708 45 3.3
latch: object queue header o 903,456 N/A 55,089 61 2.2
latch: cache buffers chains 360,522 N/A 49,016 136 0.9
gc current grant busy 112,970 25 19,893 176 0.3
gcs drm freeze in enter serv 38,442 97 18,537 482 0.1
gc cr block 2-way 1,626,280 0 15,742 10 3.9
gc remaster 6,741 89 12,397 1839 0.0
row cache lock 52,143 6 9,834 189 0.1

从上面的数据还可以看到,除了TOP 5等待,还有”gcs drm freeze in enter servermode“以及”gc remaster”这2种比较少见的等待事件,从其名称来看,明显与DRM有关。那么这2种等待事件与TOP5的事件有没有什么关联?。MOS文档”Bug 6960699- “latch: cache buffers chains” contention/ORA-481/kjfcdrmrfg: SYNC TIMEOUT/OERI[kjbldrmrpst:!master] [ID 6960699.8]”提及,DRM的确可能会引起大量的”latch: cache buffers chains”、”latch: objectqueue header operation”等待,虽然文档没有提及,但不排除会引起”latch: cachebuffers lru chain“这样的等待。

为了进一步证实性能问题与DRM相关,使用tail -f命令监控LMD后台进程的trace文件。在trace文件中显示开始进行DRM时,查询v$session视图,发现大量的 “latch: cache buffers chains” 、”latch:object queue header operation”等待事件,同时有”gcs drm freezein enter server mode“和”gc remaster”等待事件,同时系统负载升高,前台反映性能下降。而在DRM完成之后,这些等待消失,系统性能恢复到正常。

* received DRM start msg from2 (cnt 5,last1, rmno 404)
Rcvd DRM(404) Transfer pkey 1598477 from3to2 oscan 1.1
Rcvd DRM(404) Dissolve pkey 6100030 from2 oscan 0.1
Rcvd DRM(404) Dissolve pkey 5679943 from2 oscan 0.1
Rcvd DRM(404) Transfer pkey 6561036 from0to2 oscan 1.1
Rcvd DRM(404) Transfer pkey 5095243 to2 oscan 0.1
...
?

A small test case 
我们来看一个测试,观察一下DRM的产生。使用了索引读路径的查询从一个大索引中读取了几乎所有数据块。

?
Session #1:
selectdata_object_idfromdba_objectswhereobject_name='WMS_N1';
DATA_OBJECT_ID
-------------
6099472 REM 还没有affinity统计信息 select*fromx$object_affinity_statisticswhereobject=6099472; norowsselected. REM 执行高代价的查询语句 select/*+ index(a WMS_N1) */count(*)frombig_table1 a; Session #2: 观察DRM表: REM DRM字段现在是409,。我们将持续观察这个数值。在这个视图中还有其它比较有趣的字段。 selectdrmsfromX$KJDRMAFNSTATS; DRM
----
409 REM 观察到自从会话#1开始运行在该索引上已经有23442个OPENs select*fromx$object_affinity_statisticswhereobject=6099472; ADDR INDX INST_ID OBJECT NODE OPENS
---------------- ---------- ---------- ---------- ---------- ----------
FFFFFFFF7C05BFA8 14 1 6099472 1 23442 REM 该对象上还没有发生mastering select*fromv$gcspfmaster_infowhereobject_id=6099472; norowsselected REM 几秒后,OPENs计数从23442上升到33344 select*fromx$object_affinity_statisticswhereobject=6099472;
ADDR INDX INST_ID OBJECT NODE OPENS
---------------- ---------- ---------- ---------- ---------- ----------
FFFFFFFF7C05BFA8 16 1 6099472 1 33344 REM该对象上还没有发生mastering select*fromv$gcspfmaster_infowhereobject_id=6099472;
norowsselected REM 让人诧异,会话#1还在运行,OPENs计数忽然清零即使DRM还未发生过 REM OPENs从0又升到1229因为会话#1还在运行 ADDR INDX INST_ID OBJECT NODE OPENS
---------------- ---------- ---------- ---------- ---------- ---------- FFFFFFFF7C05BFA8 0 1 6099472 1 1229 REM 大约10分钟以后,remastering发生了。DRMS从409上升到411。 selectdrmsfromX$KJDRMAFNSTATS; DRM
----
411 REM 该索引的remastering发生了。现在该对象的属主是0,也就是实例1 select*fromv$gcspfmaster_infowhereobject_id=6099472; FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
---------- ---------- -------------- --------------- ------------
0 6099472 0 32767 1 REM OPENs还在上升,但是remastering已经发生了。 select*fromx$object_affinity_statisticswhereobject=6099472; ADDR INDX INST_ID OBJECT NODE OPENS
---------------- ---------- ---------- ---------- ---------- ----------
FFFFFFFF7C05AF78 2 1 6099472 1 42335
FFFFFFFF7C05AF78 3 1 6099472 2 1 REM LMON trace文件也指出pkey的传递。注意pkey和object_id是相同的。 *** 2010-03-23 10:41:57.355
BeginDRM(411) - transfer pkey 6099472to0 oscan 0.0
ftd received fromnode 1 (4/0.30.0)
allftds received REM 几秒后,OPENs被再次重置。 select*fromx$object_affinity_statisticswhereobject=6099472; ADDR INDX INST_ID OBJECT NODE OPENS
---------------- ---------- ---------- ---------- ---------- ----------
FFFFFFFF7C05BFA8 0 1 6099472 1 7437 REM 属主仍然是实例1。 select*fromv$gcspfmaster_infowhereobject_id=6099472; FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
---------- ---------- -------------- --------------- ------------
0 6099472 0 32767 1

我们的测试表明,该索引上发生了大量的BL锁请求,之后对象被remastering。

Undo and affinity
回滚段的Mastering和其它段不同。对于非回滚段而言,一个段上的所有数据块通过哈希算法被分散在各个实例间。只有在经过大量的BL锁请求以后,段才会被mastering。但是对于回滚段而言,激活了一个回滚段的实例立刻成为该段的属主。这是合乎情理的,因为在大多数情况下回滚段将会被打开这个segment的实例使用。初始化参数_gc_undo_affinity控制这种动态undo remastering动作是否发生。

因为回滚段没有真正的object_id,所以使用4294950912作为虚拟object_ids的基准值。比如说,回滚段1(usn=1)的object_id是4294950913,回滚段2(usn=2)的object_id就是4294950914,依次类推(4294950912 = power(2,32) – power (2,14)= xFFFFC000)。

 select objecT_id, object_id-4294950912 usn, current_master, previous_master,

remaster_cnt  from v$gcspfmaster_info where object_id>4294950912;

 OBJECT_ID        USN CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
---------- ---------- -------------- --------------- ------------
4294950913 1 0 32767 1
4294950914 2 0 32767 1
4294950915 3 0 32767 1
4294950916 4 0 32767 1
4294950917 5 0 32767 1
4294950918 6 0 32767 1
4294950919 7 0 32767 1
4294950920 8 0 32767 1
4294950921 9 0 32767 1
4294950922 10 0 32767 1
4294950923 11 1 32767 1
4294950924 12 1 32767 1
4294950925 13 1 32767 1
...

REM 注意usn 0在两个实例中都存在,这是系统回滚段。



REM 下面结果显示,头10个回滚段被node1掌控,而接下来的3个被实例2掌控。

select inst_id, usn, gets from gv$rollstat where usn <=13 order by inst_id, usn;

   INST_ID        USN       GETS
---------- ---------- ----------
1 0 3130
1 1 108407
1 2 42640
1 3 43985
1 4 41743
1 5 165166
1 6 43485
1 7 109044
1 8 23982
1 9 39279
1 10 48552
2 0 4433
2 11 231147
2 12 99785
2 13 1883

我没有成功试验出触发下一次回滚段remastering。我创建了一个活动事务在一个节点上产生了200K回滚数据块,然后另外一个节点在读这个表,我观察到在回滚数据块上有大量等待。但是我没有发现这个回滚段上有任何remastering事件。无法确认为什么没有产生,也许是回滚段remastering的条件有所不同吧。

译者注:回滚段的remastering是不会因为另外一个节点对于回滚段有大量读取而发生的,只有在某个实例失效,然后负责进行实例恢复的另外那个实例会暂时的成为这些回滚段的master,这是为了进行实例恢复的需要,在恢复完毕以后所有的undo buffers都会被flush到磁盘上。

PS:我能够使用后面将描述的lkdebug命令手动remaster回滚段,所以oracle也应该可以自动remaster回滚段,只是可能还有一个其它条件也必须满足。

 select * from v$gcspfmaster_info where object_id=431+4294950912;

   FILE_ID  OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
---------- ---------- -------------- --------------- ------------
0 4294951343 0 32767 1 Oradebug lkdebug –m pkey 4294951343 * kjdrchkdrm: found an RM request in the request queue Transfer pkey 4294951343 to node 1 *** 2010-03-24 12:47:29.011 Begin DRM(520) - transfer pkey 4294951343 to 1 oscan 0.1 ftd received from node 0 (4/0.31.0) all ftds received select * from v$gcspfmaster_info where object_id=431+4294950912; SQL> / FILE_ID OBJECT_ID CURRENT_MASTER PREVIOUS_MASTER REMASTER_CNT
---------- ---------- -------------- --------------- ------------ 0 4294951343 1 0 2

我不是在劝你们应该去修改这些隐含参数。只是要去理解这些参数,如果你们碰到诸如’gc remaster’, ‘gcs freeze for instancereconfiguration’这样的等待事件,那么应该知道是不是因为默认值太低了。跟技术支持沟通尝试是否能够调整。

Manual remastering
你可以使用oradebug命令来手动remaster一个对象:

?
1
oradebug lkdebug -m pkey 

这会将一个对象remaster请求放入队列。LMD0和LMON进程会完成这个请求。

当前属主是从0开始计数的。

?
 
*** 2010-01-08 23:25:54.948
* received DRM start msg from1 (cnt 1,last1, rmno 191)
Rcvd DRM(191) Transfer pkey 6984154 from0to1 oscan 0.0
ftd received fromnode 1 (8/0.30.0)
ftd received fromnode 0 (8/0.30.0)
ftd received fromnode 3 (8/0.30.0) select*fromv$gcspfmaster_info whereobject_id=6984154; SQL> / FILE_ID OBJECT_ID CURRENT_MASTERPREVIOUS_MASTER REMASTER_CNT
---------- ---------- ----------------------------- ------------
0 6984154 1 0 2 SQL> oradebug lkdebug -m pkey 6984154 Statement processed. SQL>select*fromv$gcspfmaster_infowhereobject_id=6984154; FILE_ID OBJECT_ID CURRENT_MASTERPREVIOUS_MASTER REMASTER_CNT
---------- ---------- ----------------------------- ------------
0 6984154 2 1 3

Summary
总结一下,remarstering是个很棒的功能。不过遗憾的是,我们有时候会成为它负面效果的受害者。所以,如果你碰到remastering引起的问题,不要直接就禁用它,而是应该去看看能否调优那些参数从而控制remastering事件。如果你仍然想完全禁用DRM,那么我建议设置_gc_affinity_limit和_gc_affinity_minimum参数到一个较高值,比如说1千万。将参数_gc_affinity_time设置为0也可以完全禁用DRM,但是这也意味着再也无法手工remaster对象了。另外,Arup也提到如果DRM被禁用那么x$object_affinity_statistics表也不会再被维护。

Update 1:
从11g开始,affinity管理更名为policy管理(策略管理)。比如说,x$object_affinity_statistics表改名为x$object_policy_statistics,与之相似的,初始化参数也发生了改变:参数_gc_affinity_limit改名为_gc_policy_limit;参数_gc_affinity_time改名为_gc_policy_time;出现了一个新的视图v$policy_history,其中所有policy_event = ‘initiate_affinity’的记录都是与DRM事件相关的。
本blog的其它部分仍然没问题,除了默认的_gc_policy_limit参数值降低为1500,这意味着,在理论上,11g可能会产生更多的DRM事件。

select*from v$policy_history

   INST_ID POLICY_EVENT         DATA_OBJECT_ID TARGET_INSTANCE_NUMBER  EVENT_DATE

---------- -------------------- -------------- ----------------------  --------------------
2 glru_on 0 1 10/15/2010 10:58:28
2 glru_on 0 1 10/15/2010 11:21:32
2 initiate_affinity 74809 1 10/15/2010 13:27:44

与DRM有关的一些参数

10g:

看起来,只需要关闭DRM就能避免这个问题。怎么样来关闭/禁止DRM呢?很多MOS文档提到的方法是设置2个隐含参数:

*._gc_affinity_time=0

    *._gc_undo_affinity=FALSE

不幸的是,这2个参数是静态参数,也就是说必须要重启实例才能生效。
实际上可以设置另外2个动态的隐含参数,来达到这个目的。按下面的值设置这2个参数之后,不能完全算是禁止/关闭了DRM,而是从”事实上“关闭了DRM。

甚至可以将以上2个参数值设置得更大。这2个参数是立即生效的,在所有的节点上设置这2个参数之后,系统不再进行DRM,经常一段时间的观察,本文描述的性能问题也不再出现。

11g

?

    *._gc_policy_limit=1500

    *._gc_policy_time=0

参考:

https://www.dbaleet.org/the_evolution_of_oracle_rac_drm_season_1/

https://www.dbform.com/html/tag/drm

https://wenku.baidu.com/link?url=DykRyVGrvpLkfHUMrgoUOKghYXLAzh3YRSu1AHksMwdSmL5b8XtEcEocQcC
7ziRrzd6OF54w9w4TBHuHo486MsXwJFhBrtKe5r3jdtA8joS

https://www.laoxiong.net/problem-caused-by-drm.html

【Oracle】什么是DRM,怎么关闭的更多相关文章

  1. <Oracle Database>数据库启动与关闭

    启动和关闭Oracle数据库 要启动和关闭数据库,必须要以具有Oracle 管理员权限的用户登陆,通常也就是以具有SYSDBA权限的用户登陆.一般我们常用INTERNAL用户来启动和关闭数据库(INT ...

  2. Oracle 10g RAC启动与关闭命令

    一. 检查共享设备 一般情况下, 存放OCR 和 Voting Disk 的OCFS2 或者raw 都是自动启动的. 如果他们没有启动,RAC 肯定是启动不了的. 1.1 如果使用ocfs2的,检查o ...

  3. Oracle数据库的启动和关闭

    深刻理解Oracle数据库的启动和关闭 Oracle数据库提供了几种不同的数据库启动和关闭方式,本文将详细介绍这些启动和关闭方式之间的区别以及它们各自不同的功能. 一.启动和关闭Oracle数据库 对 ...

  4. 利用 bat 批量处理命令实现手动控制mysql /Oracle 服务的开启和关闭

    利用 bat 批量处理命令实现手动控制mysql /Oracle 服务的开启和关闭 因为最近在学习数据库的知识,主要学习的是oracle 数据库,然而好巧啊,java也是在学习,我们老师现在要我们做一 ...

  5. Oracle 监听/数据库 启动/关闭

    LSNRCTL命令启动.关闭和查看监听器的状态的方法 从lsnrctl status命令的输出中得到监听器状态,包括如下的信息: 监听器的启动时间 监听器的运行时间 监听器参数文件listener.o ...

  6. oracle 12c pdb开启和关闭

    oracle 12c pdb开启和关闭 //开启数据库 sqlplus / as sysdba;                  //登录连接CDB,默认是root container;startu ...

  7. 基于Linux的oracle数据库管理 part5( linux启动关闭 自动启动关闭 oracle )

    主要内容 1. 数据库自动启动与关闭 数据库自动启动与关闭 - 单数据库模式 启动监听器及数据库 启动脚本: #! /bin/bash su - oracle<<EOF lsnrctl s ...

  8. Oracle 10g RAC 启动与关闭

    一. 检查共享设备 一般情况下,存放OCR和Voting Disk的OCFS2 或者raw 都是自动启动的. 如果他们没有启动,RAC 肯定是启动不了. 1.1 如果使用ocfs2的 检查ocfs2 ...

  9. oracle服务的开始和关闭 CMD

    开始: @echo halt oracle service ...net start OracleServiceORCLnet start OracleOraDb11g_home1TNSListene ...

  10. 深刻理解Oracle数据库的启动和关闭 .

    Oracle数据库提供了几种不同的数据库启动和关闭方式,本文将详细介绍这些启动和关闭方式之间的区别以及它们各自不同的功能. 一.启动和关闭Oracle数据库 对于大多数Oracle DBA来说,启动和 ...

随机推荐

  1. git基础使用(超级详细)

    使用git前的步骤: 1. 安装git (安装步骤省略) 2. 使用git设置用户名和邮箱 git config --global user.name "Your Name" gi ...

  2. ThreadX——IPC应用之信号量

    一.应用简介 在RTOS的应用开发中,信号量也是经常使用到的一种用于多任务之间信息同步.资源互斥访问的一种手段,常用于协调多个任务访问同一资源的场景.信号量又分为计数信号量和互斥信号量.计数信号量可以 ...

  3. Spring Boot之搞定mongoTemplate

    最近使用MongoDB+Spring Boot的项目,发现相较于MyBatis来说,Spring Boot对于MongoDB进行操作变化更多,所以总结一下使用mongoTemplate库的知识点,以备 ...

  4. 登录linux时 shell执行顺序

    # .bash_history,.bash_logout,.bash_profile,.bashrc/etc/profile 全局.bash_history 记录当前登录用户历史操作的命令.bash_ ...

  5. css进阶 05-CSS的一些小知识

    05-CSS的一些小知识 #隐藏盒子的几种方式 隐藏盒子,有以下几种方式: (1)方式一: overflow:hidden; //隐藏盒子超出的部分   (2)方式二: display: none; ...

  6. [日常摸鱼]loj6000「网络流 24 题」搭配飞行员

    题面 应该是二分图匹配,不过我写的是网络最大流. dinic求二分图最大匹配:加个源点和汇点,源点连向二分图的一边所有点,二分图的另一边所有点连向汇点,很明显这样得到的最大流就是这个二分图的最大匹配. ...

  7. Eureka系列(五) 服务续约流程具体实现

    服务续约执行简要流程图   下面这张图大致描述了服务续约从Client端到Server端的大致流程,详情如下: 服务续约Client源码分析   我们先来看看服务续约定时任务的初始化.那我们的服务续约 ...

  8. JQuery ajax request及Java服务端乱码问题及设置

    今天花了半天功夫才搞定2个乱码问题 1. 原先一直用form提交,现在改作JQuery ajax 提交,发现乱码. 2. window.location url中含有中文提交后,乱码. 第一个问题: ...

  9. Word2Vec和LDA的区别与联系

    Word2vec是目前最常用的词嵌入模型之一.是一种浅层的神经网络模型,他有2种网络结构,分别是CBOW(continues bag of words)和 skip-gram.Word2vec 其实是 ...

  10. spring整合sharding-jdbc实现分库分表

    1.创建两个库,每个库创建两个分表t_order_1,t_order_2 DROP TABLE IF EXISTS `t_order_1`; CREATE TABLE `t_order_1` ( `i ...