语言
<< 返回文章列表

深入分析:12C ASM Normal冗余中PDB文件块号与AU关系与恢复(二)

2018年7月11日
李敏
1584

刚才说到 ASMTABLE 这个表是由 21 号文件的,128,129,130,131,132,133,134,135,注意这里不连续,160,161,162,163,164,165,166,167,这16个块构成。

 

以下是罗列的一些知识点:

数据文件上的块号也是连续的。

到这里就能把表的块号跟实际磁盘和AU对应起来了。

例如,假如说5号文件的17520块是哪个磁盘的哪个AU:

(17520*block_size)/au_size,就能得到extent_number号,根据分布图,找这个extent_number对应的AU和磁盘即可。

--但是注意:11.1以后,出现了可变extent,就是说在extent较大的时候,一个extent里有多个AU,具体数值应该是1M的AU size的时候,数据文件超过20G会触发可变extent。

 

附加验证:

 

用 dd 的方法,把一个表 dd 出来,然后,把这个表 delete 掉,然后再拿 dd 出来的块,覆盖回去,看看数据还在不在。


前面说过,数据库是 8192 的,AU 是 4M,所以一个 AU 可以存放,4*1024/8=512个块。  也就是说,这个表的所有块都在第一个 AU 里。


就是前面的这个 AU:

FILE_NAME                                    FILE_NUMBER     DISK_NUMBER       AU_NUMBER   EXTENT_NUMBER      P/S_EXTENT    GROUP_NUMBER PATH                                              AU_SIEZ_MB NAME

ASMRES.271.978291939                                 271               4             321               0               0               1 /dev/mapper/data07                                         4 DATAC1

 

在 /dev/mapper/data07 盘上的 .AU 号是 321。

 

下面我们从数据文件上的位置,dd 出来这个表的数据。然后 SQLPLUS 清空这个表,再把 dd 出来的表块放回去。以验证我们推测的分布是正确的。


注意知识点:

ASM 文件跟放在文件系统上的数据文件,头部不一样,ASM 上的文件头部会多出来一个块。

比如创建一个 10M 的数据文件,在文件系统上是 10240K,在 ASM 上,这个文件的size 是10240+8K。

 

下面从已经 dd 出来的数据文件上,把表的 16 个块都 dd 出来。

 

dd if=asmres.all.dbf of=8_block_1.dd  skip=129  bs=8192 count=8

dd if=asmres.all.dbf of=8_block_2.dd  skip=161  bs=8192 count=8

 

SQL> select BYTES/1024 from dba_segments where segment_name='ASMTABLE';

 

     BYTES/1024

---------------

            128

 

把这个表,delete,清空掉。(如果这里用 truncate 会影响后面的结果不?)

 

SQL> delete from asmtable;

511 rows deleted.

SQL> commit;

Commit complete.

SQL> select count(*) from asmtable;

 

       COUNT(*)

---------------

              0

 

然后把刚才 dd 出来的文件覆盖回去。覆盖 /dev/mapper/data07 这个盘的 321 号AU,为了方便,我们把这个 AU 拿出来。

 

dd if=/dev/mapper/data07 bs=4194304 count=1 skip=321 of=AU_321_0.dbf

 

把上面提取出来的表的两个 dd 写进这个 AU 的 dd,再把这个 AU 的 dd 写回磁盘。

dd if=asmres.all.dbf of=8_block_1.dd  skip=129  bs=8192 count=8

dd if=asmres.all.dbf of=8_block_2.dd  skip=161  bs=8192 count=8

 

dd if=8_block_1.dd of=AU_321_0.dbf seek=129 bs=8192 count=8 conv=notrunc

dd if=8_block_2.dd of=AU_321_0.dbf seek=161 bs=8192 count=8 conv=notrunc

 

dd if=AU_321_0.dbf bs=4194304 count=1 seek=321 of=/dev/mapper/data07 conv=notrunc

 

然后重启整个数据库。

SQL> alter session set container=ora122pdb1;

Session altered.

SQL> select count(*) from asmtable;

 

  COUNT(*)

----------

       511

 

验证完毕,这样方式对应的 block 号和 au 号是正确的。