我们的测试表明,该索引上发生了大量的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