Author: Bo Tang
摘要
本文探索Oracle RAC数据库的内部原理。探索Oracle RAC数据库的调优源头,弄清“Master实例”、“Owner实例”、“Past Image”和“Current Image”的概念。
目录
1.Oracle RAC数据库服务器实例间的网络通信 2.Oracle RAC数据库服务器中最重要的内存结构:GRD和GRD中的资源 3.数据块上的BL锁和PR授权 4.能够查出某个块Master实例和Owner实例的X$表 5.自动Remaster(Object Affinity and Dynamic Remastering引起)和手工Remaster(oradebug命令) 6.实例恢复过程中的Remaster(Dynamic Reconfiguration) 总结
正文 1. Oracle RAC数据库服务器实例间的网络通信 下图描述了Oracle RAC数据库服务器实例间内连网通信体系结构(见图1):
图1:Oracle RAC数据库服务器实例间内连网通信体系结构示意图 Oracle RAC数据库服务器调优的重要目标就是尽量减少实例间没有必要的内连网通信量。下节所讨论的“Oracle RAC数据库服务器中最重要的内存结构:GRD和GRD中的资源”,都是通过内连网通信来维护。 2.Oracle RAC数据库服务器中最重要的内存结构:GRD和GRD中的资源 在RAC的体系结构中(见图2),全局资源目录(Global Resource Directory简称GRD)是Oracle RAC数据库服务器中最重要的内存结构。它是一套哈希分布于各个实例间由被称为“gcs mastership buckets”、“gcs res hash bucket”和“gcs resources”等内存结构组成的的元数据集(见表1)。这个哈希分布元数据集用以描述Oracle RAC数据库服务器中数据块的状态、属主信息以及数据块内部和数据块自身的锁信息。GRD分布在所有实例的共享池中,每个实例维护GRD的一部份。所有实例维护的GRD合起来形成哈希分布式的整体集。GRD内部包含“转换队列”和“写队列”,这两个队列被GCS(Global Cache Service)和GES(Global Enqueue Service)维护。所有维护信息通过前面介绍过的内连网传输。
图2:Oracle RAC体系结构图
| POOL | NAME | BYTES | 1 | shared pool | KCL buffer header | 9664 | 2 | shared pool | KCL instance cache transf | 262144 | 3 | shared pool | KCL lock contexts | 14420 | 4 | shared pool | KCL lock state | 3584 | 5 | shared pool | KCL name table | 262144 | 6 | shared pool | KCL offline scn array | 1608 | 7 | shared pool | KCL partition table | 720896 | 8 | shared pool | KCL region array | 8 | 9 | shared pool | gcs I/O statistics struct | 32 | 10 | shared pool | gcs affinity | 4108 | 11 | shared pool | gcs close obj | 4104 | 12 | shared pool | gcs commit sga state | 67596 | 13 | shared pool | gcs mastership buckets | 4608 | 14 | shared pool | gcs opaque in | 4028 | 15 | shared pool | gcs res hash bucket | 32768 | 16 | shared pool | gcs res latch table | 15360 | 17 | shared pool | gcs resource freelist arr | 272 | 18 | shared pool | gcs resource freelist dyn | 32 | 19 | shared pool | gcs resources | 4812504 | 20 | shared pool | gcs scan queue array | 216 | 21 | shared pool | gcs shadow locks dyn seg | 32 | 22 | shared pool | gcs shadow locks freelist | 272 | 23 | shared pool | gcs shadows | 3418328 |
表1:共享池中的与RAC相关内存结构,数据来源于:V$SGASTAT 理论上每个数据块都有对应于它的GRD信息:无论它当前存在于某个实例的数据库缓冲区缓存中还是已经被写回硬盘数据文件中。这些信息加上管理这些信息的锁合在一起称为“资源”。 既然GRD是分布式的整体,对于一个数据块而言,管理该数据块的状态和属主信息以及数据块内部和数据块自身的锁信息的实例只有一个。这个实例就被称作为该数据块(或更准确地说:资源)的Master实例。Oracle这样做是为了将数据块状态和属主等信息均衡地哈希分布在不同实例上。从10g以后版本开始,数据块的状态和属主等信息被存储成每128个块的信息一个master单元,即128个数据块的状态和属主等信息构成一个“gcs mastership bucket”。但是要说明以下:一个“gcs mastership bucket”不一定要存满128个块的状态和属主等信息。这样就能理解:超过128个块的表的数据块可以被多个实例分布式地分段master。如果发生自动Remaster(Object Affinity and Dynamic Remastering引起)或手工Remaster(oradebug命令),整个对象将作为master单元而不进行多个实例分布式地分段master:即不管表多大,它的数据块都由同一个实例master。另外,任何时候undo段整段必需由同一个实例master。 数据库缓冲区缓存中拥有某个数据块内存拷贝的实例被称作该数据块的Owner实例。Owner实例的个数可以是0(最小)到集群节点总数(最大)中的任何数值。如果该数据块内存拷贝在多个实例的数据库缓冲区缓存中同时被找到,也就是说该数据块有多个Owner实例,那么证明在近期有多个实例先后修改或访问过它。在所有这些该数据块的内存拷贝中,SCN最大的那个内存拷贝被称为Current Image(XI),SCN不是最大的那些内存拷贝就都被统统称为该数据块的 Past Image(PI)。PI的存在主要是为了在实例恢复过程中能被利用来减少实例交叉恢复的时间。如果由于检查点事件XI被写回硬盘,那么所有它所对应的所有PI都将被从内存中直接flush掉。还有一点值得注意的是:XI和PI都可以包含各自的new value和old value。通常old value在Oracle文档中又被称为Before Image即:BI。 最后说一下:对于回滚段上的BI而言,激活了一个回滚段的实例立刻成为该段的master实例。因为该回滚段将会被打开这个回滚段的实例所使用,用以写入事务产生的BI。因为回滚段没有真正的object_id,所以在X$KJBL表中Oracle使用回滚段号作为该回滚段的object_id。 以下用一幅图来形象描绘了一下数据库服务器其中一个实例的GRD构成(见图3):
图3:某个实例的GRD构成示意图(其中:Null表示空锁,Shared表示共享锁,Exclusive表示独占锁)
3.数据块上的BL锁和PR授权 对于RAC,Buffer cache中的Buffer以及硬盘数据文件上的块,都是锁管理的对象之一。这种锁就被称为“BL锁”,单实例的数据库上没有这种类型的锁。对Buffer和硬盘数据文件上的块的修改或访问都要先得到它的master实例的“Protected Read”授权,简称PR授权(锁状态为:KJUSERPR)。PR授权就是获得BL锁的过程。下面列出查看BL锁和PR请求的SQL语句(见表2),同时形象展现GRD中的BL锁和PR请求的动态过程(见图4)。如前所述BL锁和被其锁住的信息合在一起就是一个BL锁资源。 select * from v$ges_resource where resource_name like '%BL%'; select * from v$ges_enqueue where resource_name2 like '%BL%'; 注:v$ges_resource和v$dlm_ress是相同的。 |
表2:查看BL锁资源和PR请求的SQL语句
图4:Buffer Cache中的数据块变化前必需询问GRD
某个实例是否有申请了BL锁资源,关键是理解该实例对数据块Open和Buffer Access之间的区别。如果缓存中的数据块已经处于适当的模式,就没有必要在数据块上再打开BL锁。所以如果会话反复存取同一个数据块而不请求额外的BL锁,那么在X$OBJECT_POLICY_STATISTICS中BL锁的Open计数就不会增加。这个计数可以从以下的查询语句中查出(见表3)。
实验第1步: 查看实验用表t04209_uname的定义 在任一个实例上执行: select t.TABLE_NAME, t.COLUMN_NAME, t.DATA_LENGTH, t.DATA_PRECISION from dba_tab_columns t where t.owner = 'HR' and t.table_name = 'T04209_UNAME';
| TABLE_NAME | COLUMN_NAME | DATA_LENGTH | DATA_PRECISION | 1 | T04209_UNAME | UNAME | 60 |
| 2 | T04209_UNAME | UVALUE | 22 | 9 |
|
实验第2步: 查看实验用表t04209_uname的内容 在任一个实例上执行: select * from hr.t04209_uname;
| UNAME | UVALUE | 1 | a1 | 1 | 2 | a2 | 2 | 3 | a3 | 3 | 4 | a4 | 4 | 5 | a5 | 5 | 6 | a6 | 6 | 7 | a7 | 7 | 8 | a8 | 8 | 9 | a9 | 9 | 10 | a10 | 10 | …... | …... | …... |
共10万行
|
实验第3步: 查看实验用表t04209_uname的数据块个数 在任一个实例上执行: select s.segment_name, s.blocks from dba_segments s where s.owner = 'HR' and s.segment_name = 'T04209_UNAME';
| SEGMENT_NAME | BLOCKS | 1 | T04209_UNAME | 256 ←该表共有256个块 |
|
实验第4步: 查看实验用表t04209_uname的object_id 在任一个实例上执行: select o.object_name, o.object_id from dba_objects o where o.owner = 'HR' and o.object_name = 'T04209_UNAME';
| OBJECT_NAME | OBJECT_ID | 1 | T04209_UNAME | 52533 |
| 实验第5步: 在任一个实例上执行: select * from x$OBJECT_POLICY_STATISTICS where object = 52533; 无输出
| 实验第6步: 在实例1上update这个表t04209_uname: update hr.t04209_uname set uvalue = 2 where uname = 'a1'; update hr.t04209_uname set uvalue = 3 where uname = 'a2'; update hr.t04209_uname set uvalue = 4 where uname = 'a3'; update hr.t04209_uname set uvalue = 5 where uname = 'a4'; update hr.t04209_uname set uvalue = 6 where uname = 'a5'; update hr.t04209_uname set uvalue = 7 where uname = 'a6'; update hr.t04209_uname set uvalue = 8 where uname = 'a7'; …… update hr.t04209_uname set uvalue = 99996 where uname = 'a99995'; update hr.t04209_uname set uvalue = 99997 where uname = 'a99996'; update hr.t04209_uname set uvalue = 99998 where uname = 'a99997'; update hr.t04209_uname set uvalue = 99999 where uname = 'a99998'; update hr.t04209_uname set uvalue = 100000 where uname = 'a99999'; update hr.t04209_uname set uvalue = 100001 where uname = 'a100000'; 共10万行
| 实验第7步: 在任一个实例上执行: select * from x$OBJECT_POLICY_STATISTICS where object = 52533;
| ADDR | INDX | INST_ID | OBJECT | NODE | SOPENS | XOPENS | 1 | B7F4C4C8 | 7 | 2 ↖INST_ID为2代表Mater实例为实例2 | 52533 | 1 ↖NODE为1代表Owner实例为实例1 |
| 245 ←BL Open次数,这个表共有256个块几乎占全部。说明update大部分的行。 |
| 实验第8步: 等实例1update结束后,再查x$OBJECT_POLICY_STATISTICS没有输出。 重新在实例1上做 update,x$OBJECT_POLICY_STATISTICS仍然没有输出。 这就说明:如果缓存中的数据块已经处于适当的模式,就没有必要在数据块上再打开BL锁。所以如果会话反复存取同一个数据块而不请求额外的BL锁,那么在x$OBJECT_POLICY_STATISTICS中BL锁的Open计数就不会增加。
| 实验第9步: 在实例1上alter system flush buffer_cache;后,再做同样的update。
| 实验第10步: 在任一个实例上执行: select * from x$OBJECT_POLICY_STATISTICS where object = 52533;
| ADDR | INDX | INST_ID | OBJECT | NODE | SOPENS | XOPENS | 1 | B688A1D0 | 7 | 2↖INST_ID为2代表Mater实例为实例2 | 52533 | 1↖NODE为1代表Owner实例为实例1 |
| 248 ←BL Open次数 |
| 实验第11步: 为了使情况更复杂点,在实例2同时进行(保证实例1还在执行刚才的update): update hr.t04209_uname set uvalue = 9 where uname = 'a8'; update hr.t04209_uname set uvalue = 99 where uname = 'a98'; update hr.t04209_uname set uvalue = 999 where uname = 'a998'; update hr.t04209_uname set uvalue = 9999 where uname = 'a9998'; update hr.t04209_uname set uvalue = 99999 where uname = 'a99998'; update hr.t04209_uname set uvalue = 99998 where uname = 'a99997'; update hr.t04209_uname set uvalue = 99997 where uname = 'a99996'; update hr.t04209_uname set uvalue = 99996 where uname = 'a99995'; update hr.t04209_uname set uvalue = 99995 where uname = 'a99994'; …… update hr.t04209_uname set uvalue = 10006 where uname = 'a10005'; update hr.t04209_uname set uvalue = 10005 where uname = 'a10004'; update hr.t04209_uname set uvalue = 10004 where uname = 'a10003'; update hr.t04209_uname set uvalue = 10003 where uname = 'a10002'; update hr.t04209_uname set uvalue = 10002 where uname = 'a10001'; update hr.t04209_uname set uvalue = 10001 where uname = 'a10000'; update hr.t04209_uname set uvalue = 10000 where uname = 'a9999'; update hr.t04209_uname set uvalue = 100001 where uname = 'a100000'; update hr.t04209_uname set uvalue = 100000 where uname = 'a99999'; 共10万行,这10万行update是不按顺序打乱后的组合。
| 实验第12步: 在任一个实例上执行: select * from x$OBJECT_POLICY_STATISTICS where object = 52533;
| ADDR | INDX | INST_ID | OBJECT | NODE | SOPENS | XOPENS | 1 | B688A1D0 | 20 | 2 | 52533 | 1 | 0 | 2562←由于两个实例同时更改,产生 了大量的BL Open | 2 | B688A1D0 | 21 | 2 | 52533 | 2 |
| 1053 ↙BL Open的增加是为了进行gc cr读 |
|
实验第13步: 在任一个实例上执行: select to_char(52533, 'xxxxxxxx') from dual;
| TO_CHAR(52533,'XXXXXXXX') | 1 | cd35 |
| 实验第14步: 在任一个实例上执行: 查看两个实例此时的资源状态 select inst_id, resource_name, on_convert_q, on_grant_q, master_node, next_cvt_level from gv$ges_resource where resource_name like '[0xcd35]%';
| INST_ID | RESOURCE_NAME | ON_CONVERT_Q | ON_GRANT_Q | MASTER_NODE | NEXT_CVT_LEVEL | 1 | 2 | [0xcd35][0x0],[TM] | 0 | 1 | 0 | KJUSERNL | 2 | 2 | [0xcd35][0xc09281d],[IV] | 0 | 1 | 0 | KJUSERNL | 3 | 1 | [0xcd35][0x0],[TM] | 0 | 1 | 0 | KJUSERNL | 4 | 1 | [0xcd35][0xc09281d],[IV] | 0 | 1 | 0 | KJUSERNL |
| 实验第15步: 在任一个实例上执行: 查看两个实例此时的锁状态 select inst_id, grant_level, request_level, resource_name2, PID, TRANSACTION_ID0, TRANSACTION_ID1 from gv$ges_enqueue where resource_name2 like '52533%';
| INST_ID | GRANT_LEVEL | REQUEST_LEVEL | RESOURCE_NAME2 | PID | TRANSACTION_ID0 | TRANSACTION_ID1 | 1 | 1 | KJUSERCW | KJUSERCW | 52533,0,TM | 27730 | 1835009 | 33 | 2 | 1 | KJUSERCW | KJUSERCW | 52533,0,TM | 0 | 0 | 0 | 3 | 1 | KJUSERPR | KJUSERPR | 52533,201926685,IV | 7283 | 0 | 0 | 4 | 1 | KJUSERPR | KJUSERPR | 52533,201926685,IV | 0 | 0 | 0 | 5 | 2 | KJUSERCW | KJUSERCW | 52533,0,TM | 9231 | 1703938 | 111 | 6 | 2 | KJUSERPR | KJUSERPR | 52533,201926685,IV | 7200 | 0 | 0 |
KJUSERPR是BL锁,KJUSERCW是表级共享锁,KJUSERTM是行级独占锁,KJUSERNL是空锁,KJUSEREX是lock table之类命令产生的独占锁
|
表3:Buffer Cache中的数据块变化前必需询问GRD的完整实验过程
由于表3中的实验后半段在两个实例上都对表t04209_name做了更改。对于两个实例各自回滚段上的BI而言,激活了一个回滚段的实例立刻成为该段的master实例。如上一节所述回滚段没有真正的object_id,所以使用回滚段号作为该回滚段的object_id。到此我们自然就会得出一个有意思的推论:一个事务产生的new value和old value(BI)可以被两个不同的实例master:因为实例1可以update一个实例2master的数据块,new value的master自然是实例2;old value由于在实例1的回滚段上所以归实例1master。这样推导下去诸如“gc [current/cr] [multiblock] request”、“gc [current/cr] [2/3]-way“、”gc [current/cr] block busy“、”gc [current/cr] grant 2-way“、”gc [current/cr] [block/grant] congested“和“gc [current/cr] [failure/retry]“等待事件中的current(new value)和cr(old value)分别对应的master实例有可能不是同一个。可以顺便验证一下(见表4):
实验第16步: 查看回滚段信息 在任一个实例上执行: select rs.instance_num, rs.segment_name, rs.segment_id from dba_rollback_segs rs;
| INSTANCE_NUM | SEGMENT_NAME | SEGMENT_ID | 1 | 1 | SYSTEM | 0 | 2 | 1 | _SYSSMU1$ | 1 | 3 | 1 | _SYSSMU2$ | 2 | 4 | 1 | _SYSSMU3$ | 3 | 5 | 1 | _SYSSMU4$ | 4 | 6 | 1 | _SYSSMU5$ | 5 | 7 | 1 | _SYSSMU6$ | 6 | 8 | 1 | _SYSSMU7$ | 7 | 9 | 1 | _SYSSMU8$ | 8 | 10 | 1 | _SYSSMU9$ | 9 | 11 | 1 | _SYSSMU10$ | 10 | 12 | 2 | _SYSSMU11$ | 11 | 13 | 2 | _SYSSMU12$ | 12 | 14 | 2 | _SYSSMU13$ | 13 | 15 | 2 | _SYSSMU14$ | 14 | 16 | 2 | _SYSSMU15$ | 15 | 17 | 2 | _SYSSMU16$ | 16 | 18 | 2 | _SYSSMU17$ | 17 | 19 | 2 | _SYSSMU18$ | 18 | 20 | 2 | _SYSSMU19$ | 19 | 21 | 2 | _SYSSMU20$ | 20 |
| 实验第17步: 查看回滚段正被哪个实例Remaster: 在任一个实例上执行: select * from v$gcspfmaster_info;
| FILE_ID | DATA_OBJECT_ID | CURRENT_MASTER | PREVIOUS_MASTER | REMASTER_CNT | 1 | 0↖10.1版本以前,是以文件作为Remaster单元,现在以对象作为单元,这里都是0 | 1 | 0 | 32767↖表示之前没有发生过Remaster事件 | 0 | 2 | 0 | 2 | 0 | 32767 | 0 | 3 | 0 | 3 | 0 | 32767 | 0 | 4 | 0 | 4 | 0 | 32767 | 0 |
|
表4:表3实验过程中伴随的undo段GRD信息
4.能够查出某个块Master实例和Owner实例的X$表 X$KJBL描述哪一个实例是某个表的带BL锁的块的master实例(见表5)。
让表3中所描述的两个实例继续update,不要停接着做以下的实验(如果两个实例,或其中一个结束了update重新update ) 实验第18步: 在任一个实例上执行: 创建一个基于X$KJBL的视图,后续实验需要它 create or replace view myview as select kj.block#, kjblname, kjblname2, kjblowner+1 "OWNER_Instance", kjblmaster+1 "MASTER_Instance", kjbllockp from ( select kjblname, kjblname2, kjblowner, kjblmaster, kjbllockp, (substr ( kjblname2, instr(kjblname2,',')+1, instr(kjblname2,',',1,2)-instr(kjblname2,',',1,1)-1))/65536 file#, substr ( kjblname2, 1, instr(kjblname2,',')-1) block# from x$kjbl ) kj, ( select block_id block#_begin, block_id+blocks-1 block#_end, e.file_id file# from dba_extents e where e.owner='HR' and e.segment_name='T04209_UNAME' ) e where kj.block# between e.block#_begin and e.block#_end order by block# ; | 实验第19步: 在任一个实例上执行: select * from myview;
| FILE# | BLOCK# | KJBLNAME | KJBLNAME2 | OWNER_Instance | MASTER_Instance | KJBLLOCKP | 1 | 4 | 387 | [0x183][0x40000],[BL] | 387,262144,BL | 1 | 1 | 237EC730 | 2 | 4 | 387 | [0x183][0x40000],[BL] | 387,262144,BL | 2 | 1 | 49A35F58 | 3 | 4 | 388 | [0x184][0x40000],[BL] | 388,262144,BL | 2 | 1 | 49A31B60 | 4 | 4 | 388 | [0x184][0x40000],[BL] | 388,262144,BL | 1 | 1 | 237F38A0 | 5 | 4 | 389 | [0x185][0x40000],[BL] | 389,262144,BL | 1 | 1 | 237FA490 | 6 | 4 | 389 | [0x185][0x40000],[BL] | 389,262144,BL | 2 | 1 | 49A321D0 | 7 | 4 | 390 | [0x186][0x40000],[BL] | 390,262144,BL | 2 | 1 | 49A32368 | 8 | 4 | 390 | [0x186][0x40000],[BL] | 390,262144,BL | 1 | 1 | 23BF2560 | 9 | 4 | 391 | [0x187][0x40000],[BL] | 391,262144,BL | 2 | 1 | 49A31BE8 | 10 | 4 | 391 | [0x187][0x40000],[BL] | 391,262144,BL | 1 | 1 | 237F16F0 | …... | …... | …... | …... | …... | …... | …... | …... |
从以上的查询结果可以看出:每个数据块内存拷贝在两个实例的数据库缓冲区缓存中都可以被找到,也就是说每个数据块都有两个个Owner实例,那么证明在近期有两个实例先后修改或访问过它。
|
实验第20 步: 在任一个实例上执行: select distinct block#, "MASTER_Instance" from myview order by 1;
| BLOCK# | MASTER_Instance | 1 | 387 | 1 | 2 | 388 | 1 | 3 | 389 | 1 | 4 | 390 | 1 | 5 | 391 | 1 | 6 | 392 | 1 | 7 | 393 | 1 | 8 | 394 | 1 | 9 | 395 | 1 | 10 | 396 | 1 | …... | …... | …... | 109 | 502 | 1 | 110 | 503 | 1 | 111 | 504 | 1 | 112 | 505 | 1 | 113 | 506 | 1 | 114 | 507 | 1 | 115 | 508 | 1 | 116 | 509 | 1 | 117 | 510 | 1 | 118 | 511 | 1 | 119 | 512 | 2←从这变成实例2 | 120 | 523 | 2 | 121 | 524 | 2 | 122 | 525 | 2 | 123 | 526 | 2 | 124 | 527 | 2 | 125 | 528 | 2 | 126 | 529 | 2 | 127 | 530 | 2 | 128 | 531 | 2 | 129 | 532 | 2 | 130 | 533 | 2 | …... | …... | …... | 220 | 628 | 2 | 221 | 629 | 2 | 222 | 630 | 2 | 223 | 631 | 2 | 224 | 632 | 2 | 225 | 633 | 2 | 226 | 635 | 2 | 227 | 636 | 2 | 228 | 637 | 2 | 229 | 638 | 2 | 230 | 639 | 2 | 231 | 640 | 1 | 232 | 641 | 1 | 233 | 642 | 1 | 234 | 643 | 1 | 235 | 644 | 1 | 236 | 645 | 1 | 237 | 646 | 1 | 238 | 647 | 1 | 239 | 648 | 1 |
这说明:从10g以后版本开始,数据块的状态和属主等信息被存储成每128个块的信息一个master单元,即128个数据块的状态和属主等信息构成一个“gcs mastership bucket”。但是要说明以下:一个“gcs mastership bucket”不一定要存满128个块的状态和属主等信息。这样就能理解:超过128个块的表的数据块可以被多个实例分布式地分段master。
|
实验第21步: 在任一个实例上执行: select count(*) from myview where "OWNER_Instance"<> "MASTER_Instance";
从以上结果可以看到,存在大量的数据块的master实例和owner实例不是同一个实例的情况。这是可以预料到的:我们在两个实例上同时密集地OLTP同一张表!这样会有大量的实例间的通信。以下内容来自此刻的AWR报告:
Top 5 Timed Events: Event | Waits | Time(s) | Avg Wait(ms) | % Total Call Time | Wait Class | gc cr block busy | 85,181 | 181 | 2 | 44.5 | Cluster ←对方CR块请求收到,但是无法立即发送 | CPU time |
| 79 |
| 19.4 |
| gcs log flush sync | 37,349 | 35 | 1 | 8.6 | Other ←日志系统太忙flush不过来 | gc cr multi block request | 1,623 | 27 | 16 | 6.5 | Cluster ← placeholder请求多 | gc current grant busy | 13,162 | 20 | 2 | 5.0 | Cluster ← 由于master实例和owner实例不是同一个实例导致master实例发送磁盘授权信息延迟或接收延迟。 |
RAC Statistics:
| Begin | End | Number of Instances: | 2 | 2 |
Global Cache Load Profile:
| Per Second | Per Transaction | Global Cache blocks received: | 264.26 | 1,108.00 | Global Cache blocks served: | 356.69 | 1,495.53 | GCS/GES messages received: | 452.07 | 1,895.44 | GCS/GES messages sent: | 462.24 | 1,938.10 | DBWR Fusion writes: | 0.16 | 0.67 | Estd Interconnect traffic (KB) | 5,146.16 |
|
Global Cache Efficiency Percentages (Target local+remote 100%): Buffer access - local cache %: | 99.69 | Buffer access - remote cache %: | 0.30 | Buffer access - disk %: | 0.00 |
Global Cache and Enqueue Services - Workload Characteristics: Avg global enqueue get time (ms): | 0.3 | Avg global cache cr block receive time (ms): | 2.0 | Avg global cache current block receive time (ms): | 1.4 | Avg global cache cr block build time (ms): | 0.1 | Avg global cache cr block send time (ms): | 0.0 | Global cache log flushes for cr blocks served %: | 23.9 | Avg global cache cr block flush time (ms): | 1.5 | Avg global cache current block pin time (ms): | 0.0 | Avg global cache current block send time (ms): | 0.0 | Global cache log flushes for current blocks served %: | 0.2 | Avg global cache current block flush time (ms): | 1.9 |
Global Cache and Enqueue Services - Messaging Statistics: Avg message sent queue time (ms): | 0.2 | Avg message sent queue time on ksxp (ms): | 0.8 | Avg message received queue time (ms): | 0.0 | Avg GCS message process time (ms): | 0.1 | Avg GES message process time (ms): | 0.0 | % of direct sent messages: | 73.86 | % of indirect sent messages: | 13.11 | % of flow controlled messages: | 13.03 |
|
续篇 本文创建t04209_uname表,和update用的脚本:
create_t04209_uname.sql.zip update2_t04209_uname.sql.zip update_t04209_uname.sql.zip |