由于表3中的实验后半段在两个实例上都对表t04209_name做了更改。对于两个实例各自回滚段上的BI而言,激活了一个回滚段的实例立刻成为该段的master实例。如上一节所述回滚段没有真正的object_id,所以使用4294950912+回滚段号作为该回滚段的object_id。到此我们自然就会得出一个有意思的推论:一个事务产生的newvalue和old value(BI)可以被两个不同的实例master:因为实例1可以update一个实例2master的数据块,new value的master自然是实例2;oldvalue由于在实例1的回滚段上所以归实例1master。这样推导下去诸如“gc [current/cr] [multiblock] request”、“gc[current/cr] [2/3]-way“、”gc [current/cr] block busy“、”gc [current/cr] grant2-way“、”gc [current/cr] [block/grant] congested“和“gc [current/cr][failure/retry]“等待事件中的current(new value)和cr(old value)分别对应的master实例有可能不是同一个。可以顺便验证一下(见表4):



实验第16步:

查看回滚段信息

在任一个实例上执行:

selectrs.instance_num,rs.segment_name,rs.segment_id,rs.segment_id+4294950912from dba_rollback_segs rs;



INSTANCE_NUM

SEGMENT_NAME

SEGMENT_ID

RS.SEGMENT_ID+4294950912

1

1

SYSTEM

0

4294950912

2

1

_SYSSMU1$

1

4294950913

3

1

_SYSSMU2$

2

4294950914

4

1

_SYSSMU3$

3

4294950915

5

1

_SYSSMU4$

4

4294950916

6

1

_SYSSMU5$

5

4294950917

7

1

_SYSSMU6$

6

4294950918

8

1

_SYSSMU7$

7

4294950919

9

1

_SYSSMU8$

8

4294950920

10

1

_SYSSMU9$

9

4294950921

11

1

_SYSSMU10$

10

4294950922

12

2

_SYSSMU11$

11

4294950923

13

2

_SYSSMU12$

12

4294950924

14

2

_SYSSMU13$

13

4294950925

15

2

_SYSSMU14$

14

4294950926

16

2

_SYSSMU15$

15

4294950927

17

2

_SYSSMU16$

16

4294950928

18

2

_SYSSMU17$

17

4294950929

19

2

_SYSSMU18$

18

4294950930

20

2

_SYSSMU19$

19

4294950931

21

2

_SYSSMU20$

20

4294950932




实验第17步:

查看回滚段正被哪个实例Remaster:

在任一个实例上执行:

select* from v$gcspfmaster_info;



FILE_ID

OBJECT_ID

CURRENT_MASTER

PREVIOUS_MASTER

REMASTER_CNT

1

010.1版本以前,是以文件作为Remaster单元,现在以对象作为单元,这里都是0

4294950913

0

32767表示之前没有发生过Remaster事件

0

2

0

4294950914

0

32767

0

3

0

4294950915

0

32767

0

4

0

4294950916

0

32767

0

5

0

4294950917

0

32767

0

6

0

4294950918

0

32767

0

7

0

4294950919

0

32767

0

8

0

4294950920

0

32767

0

9

0

4294950921

0

32767

0

10

0

4294950922

0

32767

0

11

0

4294950923

1

32767

0

12

0

4294950924

1

32767

0

13

0

4294950925

1

32767

0

14

0

4294950926

1

32767

0

15

0

4294950927

1

32767

0

16

0

4294950928

1

32767

0

17

0

4294950929

1

32767

0

18

0

4294950930

1

32767

0

19

0

4294950931

1

32767

0

20

0

4294950932

1

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

selectkj.file#, kj.block#, kjblname,  kjblname2, kjblowner+1 "OWNER_Instance", kjblmaster+1  "MASTER_Instance", kjbllockpfrom

(

selectkjblname, 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,

(

selectblock_idblock#_begin,block_id+blocks-1block#_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#_endand kj.file#=e.file# 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 步:

在任一个实例上执行:

selectdistinctblock#,"MASTER_Instance"from myvieworder 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步:

在任一个实例上执行:

selectcount(*)from myviewwhere "OWNER_Instance" <> "MASTER_Instance"  ;



COUNT(*)

1

239


从以上结果可以看到存在大量的数据块的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



实验第22步:

现在让问题回到简单的状态,我们把第2个实例上的update结束。

在任一个实例上执行:

selectcount(*)from myviewwhere "OWNER_Instance" <> "MASTER_Instance"and "OWNER_Instance"=1;



COUNT(*)

1

118


selectcount(*)from myviewwhere "OWNER_Instance" <> "MASTER_Instance"and "OWNER_Instance"=2;



COUNT(*)

1

110



实验第23步:

过一会在任一个实例上执行再查:

selectcount(*)from myviewwhere "OWNER_Instance" <>  "MASTER_Instance"and  "OWNER_Instance"=1;



COUNT(*)

1

118


selectcount(*)from myviewwhere "OWNER_Instance" <> "MASTER_Instance"and "OWNER_Instance"=2;



COUNT(*)

1

20


从以上结果可以看到,当我们把第2个实例上的update结束后,第2个实例的owner计数在不断下降,但是仍然存在不少数据块的master实例和owner实例不是同一个实例的情况,这样在我们的密集OLTP应用模型下仍然存在实例间不必要的通信量。



实验第24步:

在任一个实例上执行:

select* from v$gcspfmaster_info where  object_id=52533;

没有输出


说明此刻没有发生自动Remaster(Object Affinity and Dynamic Remastering引起)。



实验第25步:

在任一个实例上执行(可执行多次):

select drms from X$KJDRMAFNSTATS;值始终为2也验证了此刻没有发生自动Remaster。


5:能够查出某个块Master实例和Owner实例的X$


5自动Remaster(Object Affinity and Dynamic Remastering引起)手工Remaster(oradebug命令)



实验第26步:

在任一个实例上执行:

select x.ksppinm name,y.ksppstvl value

from sys.x$ksppi x,sys.x$ksppcv y

where x.indx=y.indx and substr(x.ksppinm,0,1)='_'  and x.ksppinm like '_gc_affi%';



NAME

VALUE

1

_gc_affinity_time

1010秒查看一下是否要做Remastering(不是分钟)

2

_gc_affinity_limit

50要发生Remastering的实例必须比环境中其它所有实例访问某一个对象的总和还要多50个BL计数

3

_gc_affinity_minimum

2400每分钟最少要有的dynamic    affinity活动个数,才会发Remastering




下面我们来做自动remaster(Object  Affinity and Dynamic Remastering引起)的实验。

实验第27步:

在任一个实例上执行:

selectcount(*)from myviewwhere "OWNER_Instance"  <> "MASTER_Instance" ;



COUNT(*)

1

138


在任一个实例上执行:

select* from x$OBJECT_AFFINITY_STATISTICS where object=52533;

无输出,这是正常的。 x$OBJECT_AFFINITY_STATISTICS统计信息会定时清空。



实验第28步:

在实例1上:连续做以下两条语句,直到t04209_uname表中51200000行记录为止。

insert /*+ append */ into t04209_uname select * from  t04209_uname;

commit;


未完,最后一部分