什么是Oracle Past Image(pi)

什么是Oracle Past Image(pi)

Past Image是一种RAC环境中脏缓冲块的状态,是集群中不同实例对同一个数据缓冲块写而又写后的间接结果。简而言之,Past Image是一种特殊的脏数据块,它保留了前一次更改后的样子。浪漫些,它是一个残像。针对一个特定的数据块,每一个实例最多只能有一个残像(pi)。

实例间争夺、修改热块很容易观察到Past Image,即残像。

当前环境是这样的:HR.EMPLOYEES中的100号员工和101号员工都在5号文件的88号数据块中。从此称此数据块为球,让两个实例争夺这个球。

# 观测1: 球不在任何节点上。
SYS@RAC1//scripts> select inst_id,status from gv$bh where file#=5 and block#=88;
no rows selected

# 节点1要球。(可怜的Steve King, 你本来有24000薪水的。)
SYS@RAC1//scripts> update hr.employees set salary=1 where employee_id=100;
1 row updated.

# 观测2: 球在节点1上。xcur表示写调用的当前数据缓冲,即排他当前数据块。
SYS@RAC1//scripts> select inst_id,dirty,status from gv$bh where file#=5 and  block#=88;
   INST_ID + D + STATUS
---------- + - + -------
         1 + Y + xcur
1 row selected.

# 节点2要球。
SYS@RAC2//scripts> update hr.employees set salary=2 where employee_id=101;
1 row updated.

# 观测3: 球在节点2上,残像在节点1上。pi表示Past Image,也就是残像。它保留了数据块前一次更改后的样子。
SYS@RAC1//scripts> select inst_id,dirty,status from gv$bh where file#=5 and  block#=88;
   INST_ID + D + STATUS
---------- + - + -------
         1 + Y + pi
         2 + Y + xcur
2 rows selected.

# 节点1要球。
SYS@RAC1//scripts> update hr.employees set salary=3 where employee_id=100;
1 row updated.

# 观测4: 球在节点1上,残像在节点2和节点1上都存在。节点2上的残像比节点1上的残像更新
SYS@RAC1//scripts> select inst_id,dirty,status from gv$bh where file#=5 and  block#=88;
   INST_ID + D + STATUS
---------- + - + -------
         1 + Y + pi
         1 + Y + xcur
         2 + Y + pi
3 rows selected.

# 节点2又要球。
SYS@RAC2//scripts> update hr.employees set salary=4 where employee_id=101;
1 row updated.

# 观测5: 球在节点2上,很不巧这时候发生了增量检查点,DBWR醒了,想到要工作了,残像(pi)变成了陈旧的一致性读缓存块(cr)。它们完全可以被覆盖。坑爹的我辛苦产生的残像都没了。
SYS@RAC1//scripts> select inst_id,dirty,status from gv$bh where file#=5 and  block#=88;
   INST_ID + D + STATUS
---------- + - + -------
         1 + N + cr
         1 + N + cr
         2 + Y + xcur
3 rows selected.

# 重来。节点1要球。
SYS@RAC1//scripts> update hr.employees set salary=5 where employee_id=100;
1 row updated.

# 观测6: 球在节点1上,残像在节点2上。陈旧的一致性读缓存块不用理会,它们随时可以消失。
SYS@RAC1//scripts> select inst_id,dirty,status from gv$bh where file#=5 and  block#=88;
   INST_ID + D + STATUS
---------- + - + -------
         1 + Y + xcur
         1 + N + cr
         1 + N + cr
         2 + Y + pi
4 rows selected.

# 节点2要球。
SYS@RAC2//scripts> update hr.employees set salary=6 where employee_id=101;
1 row updated.

# 观测7: 球在节点2上,残像在节点1和2上。节点1上的残像比节点2上的残像更新。回顾一下观测4,很相似。两节点上的残像都出现了。
SYS@RAC1//scripts> select inst_id,dirty,status from gv$bh where file#=5 and  block#=88;
   INST_ID + D + STATUS
---------- + - + -------
         1 + Y + pi
         2 + Y + pi
         2 + Y + xcur
3 rows selected.

# 节点1要球。
SYS@RAC1//scripts> update hr.employees set salary=7 where employee_id=100;
1 row updated.

# 观测8: 球在节点1上,残像在节点2和1上。节点2上的残像比节点1上的残像更新。原来在节点2上的残像变成了陈旧的一致性读缓存块。没有破坏每一个实例最多只能有一个残像(针对同一个数据块)的规则。
SYS@RAC1//scripts> select inst_id,dirty,status from gv$bh where file#=5 and  block#=88;
   INST_ID + D + STATUS
---------- + - + -------
         1 + Y + pi
         1 + Y + xcur
         2 + Y + pi
         2 + N + cr
4 rows selected.

不考虑任何检查点的话, 当xcur块移动到另一个节点时:原来节点上的xcur块转变成pi块、原来的pi块(如果有的话)转变为cr块,结果是cr块越来越多,pi则最多和节点数一样多。

接下来让两个节点进行一次弹珠球大战:同时在两个节点上执行匿名块A和B。

A:
SYS@RAC1//scripts> run
  1  begin
  2  for i in 1..100000 loop
  3  update hr.employees set salary=i where employee_id=100;
  4  end loop;
  5* end;

B:
SYS@RAC2//scripts> run
  1  begin
  2  for i in 1..100000 loop
  3  update hr.employees set salary=i where employee_id=101;
  4  end loop;
  5* end;

等到它们执行完毕后,看一下5号文件88号数据块在buffer cache中占了几个位置:
SYS@RAC2//scripts> select count(*) from gv$bh where file#=5 and block#=88;
  COUNT(*)
----------
       412
1 row selected.

其中409个是一致性读块缓冲(cr):
SYS@RAC2//scripts> select count(*) from gv$bh where file#=5 and block#=88 where status='cr';
  COUNT(*)
----------
       409
1 row selected.

1个排他当前块缓冲(xcur):
SYS@RAC2//scripts> select count(*) from gv$bh where file#=5 and block#=88 where status='xcur';
  COUNT(*)
----------
           1
1 row selected.

还有...2个我们的主角--残像缓冲(pi)。分别在两个节点上。
SYS@RAC1//scripts> select inst_id,dirty,status from gv$bh where file#=5 and block#=88 and status='pi';
   INST_ID + D + STATUS
---------- + - + -------
         1 + Y + pi
         2 + Y + pi
2 rows selected.

某些时候,当你在RAC环境中发现大量的一致性读缓冲(cr)时,可能你看到的是实例间争夺热块的搏斗痕迹。这是一个xcur到pi再到cr的过程。

那么pi有什么作用? 至少有两个作用。
一,需要时节点可以从本地的pi块制造cr块,避免从其他节点请求cr块。
二,当拥有xcur块的实例崩溃后,pi块重新转变为xcur块,提高了实例恢复的速度。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值