• 如何在asm上定位数据块


    转自 https://blogs.oracle.com/database4cn/%e5%a6%82%e4%bd%95%e5%9c%a8asm%e4%b8%8a%e5%ae%9a%e4%bd%8d%e6%95%b0%e6%8d%ae%e5%9d%97

     

    我们都知道当db使用传统的文件系统时,定位block是就是通过dba_extents 中的blockid即可,然后通过bbed或dd 直接操作对应数据文件的相应block即可,从10g开始,oracle使用ASM来管理磁盘,因为所有数据文件都在ASM上,所以传统的bbed,dd都不能直接访问新型"文件系统"上的某个数据文件了。

    当我们需要在特殊场景下修改某个block的内存的时候该怎么办呢?下面给您演示一下:

    首先我在这里先普及一下ASM的一点基础知识,需要知道的是ASM在磁盘上存储数据,分配的时候都是AU(allocation unit)为单位的,默认情况AU是1M,所以一个2G的数据文件需要至少分配2×1024=2048个AU,当然存储这些AU的相关信息(如编号)也是需要存储空间的,这种元数据也是需要占用AU的,所以实际上从ASM层面来看分配给某个数据文件的au数量要高于它的需求数量。对于ASM来讲,数据库的所有文件,如控制文件,spfile,数据文件都是作为一种叫文件目录(file directory)类型的数据进行管理的。每一条这种类型的数据就是一个ASM管理的文件,其中ASM为了管理方便会给每个文件目录分配一个唯一的编号,并且会在第一个文件目录的AU里面为其分配一个4k的block来存放它分配的AU情况。而这个block编号就是分配给文件目录的编号。因为au默认是1M,所以一个au能分配出来256个block,也就是文件目录编号前255(oracle 里面编号都是从0开始的)都在第一个AU里面,大于255小于512的都在第一个文件目录第二个au里面某个4kblock里面,那么如何知道某个数据文件的编号呢,实际上oracle在创建文件的时候就已经告诉我们了。例如我们在往users表空间添加数据文件名为user2.dbf的文件后,oracle在ASM上创建数据文件的名字类似如下:

    user2.dbf => +DATA/R11204/DATAFILE/USERS.328.944473935
    

    其中328就是表明这个数据文件的ASM 文件目录的编号。所以我们就通过它来入手。

    介绍完如上的知识,我们看看如何定位一个数据文件的某个block:

    首先创建一个表,为了好验证,我插入的数据都是a,

    create table test_t ( a number, b varchar2(100));
    insert into test_t values(1,'abcdefg');
    insert into test_t select * from test_t;
    insert into test_t select * from test_t;
    insert into test_t select * from test_t;
    commit;
    

    查询这个表的block情况

    select * from dba_extents where segment_name='TEST_T';
    
    OWNER   SEGMENT_NAME    SEGMENT_TYPE   TABLESPACE_NAME  EXTENT_ID  FILE_ID   BLOCK_ID  BYTES  BLOCKS  RELATIVE_FNO
    ------- --------------- -------------- ---------------- ---------- --------- --------- ------ ------- ------------
    MAOB    TEST_T          TABLE          USERS                     0         4       168  65536       8            4
    
    select file_id,file_name from dba_data_files;
    
    FILE_ID FILE_NAME
    ------- ------------------------------------------
          4 +DATA/r11204/datafile/users.300.908780493          <<file_number=300


    我们可以看到这个表在 file_id=4 的数据文件里只分配了一个 8个block 的extent,第一个 blockid 是168,根据oracle ASSM表空间的存储相关的知识,extent0 的前三个block分别是L1,L2,L3的metadata,所以第一个data block是171,那么我们就找blockid=171这个block的ASM上存储位置:

    首先我们根据file_id=4 blockid=171信息计算出这个数据文件在文件目录里面AU信息和block信息

    AU信息:因为oracle数据块默认是8k的,所以171个block会占用多少个1M的au呢?

    select  171*8/1024 from dual
    1.3359375

    是1.3个Au,所以这个171的block一定放在第二个au里面的某个block上

    au里的block信息:

    select (171*8-1*1024)/8 from dual
    43
    

    这个blockid=171的block放在第二个au里面的第43个block位置,然后我们就需要找到这个数据文件的第二个au相对于磁盘的位置,根据之前介绍的知识,

    我们用kfed来读取磁盘头信息:我们要得到第一个文件目录的au信息

    [grid@rac1 disks]$ kfed read /dev/oracleasm/disks/VOL1 |grep f1b1
    kfdhdb.f1b1locn:                     10 ; 0x0d4: 0x0000000a  file1的第一个au

    磁盘头里面的f1b1locn存放 就是目录文件1的第一个au,之前介绍了,第一个au里面只能存放文件编号小于256的文件目录,我们的数据文件4的名字是 users.300.908780493,所以这个文件编号是300-256=44,也就是说会放在au=2的第44个block里面

    查看文件目录1里面的au分配信息

    [oracle@rac1 ~]$ kfed read /dev/oracleasm/disks/VOL1 aun=10 blkn=1 |grep au
    kfffde[0].xptr.au:                   10 ; 0x4a0: 0x0000000a
    kfffde[1].xptr.au:                   61 ; 0x4a8: 0x0000003d   <<第二个au的编号
    kfffde[2].xptr.au:           4294967295 ; 0x4b0: 0xffffffff

    查看文件目录44的au分配信息

    [grid@rac1 ~]$ kfed read /dev/oracleasm/disks/VOL1 aun=61 blkn=44 | grep au
    kfffde[0].xptr.au:                 9931 ; 0x4a0: 0x000026cb
    kfffde[1].xptr.au:                 9932 ; 0x4a8: 0x000026cc <<file 300的第二个au编号
    kfffde[2].xptr.au:                 9933 ; 0x4b0: 0x000026cd
    kfffde[3].xptr.au:                 9934 ; 0x4b8: 0x000026ce

    得到file 300的第二个au编号之后,我们就可以直接copy他的信息进行验证

    dd if=/dev/oracleasm/disks/VOL1 skip=9932 of=/tmp/users.300 bs=1024k count=1
    
    BBED> set blocksize 8192
    BBED> set block 0
    BBED-00309: out of range block number (0)  说明blockid是从1开始的,那么block43对应44
    BBED> set block 44
    BBED> p kcbh                
    struct kcbh, 20 bytes       @0
       ub1 type_kcbh            @0        0x06
       ub1 frmt_kcbh            @1        0xa2
       ub1 spare1_kcbh          @2        0x00
       ub1 spare2_kcbh          @3        0x00
       ub4 rdba_kcbh            @4        0x010000ab  <<file4 block 171
       ub4 bas_kcbh             @8        0x0080737b
       ub2 wrp_kcbh             @12       0x0000
       ub1 seq_kcbh             @14       0x01
       ub1 flg_kcbh             @15       0x04 (KCBHFCKV)
       ub2 chkval_kcbh          @16       0xffc6
       ub2 spare3_kcbh          @18       0x0000
    
    BBED> set offset 8100
        OFFSET             8100
    BBED> dump /v
     File: users.300 (1)
     Block: 44      Offsets: 8100 to 8191  Dba:0x0040002C
    -------------------------------------------------------
     64656667 2c010202 c1020761 62636465 l defg,......abcde
     66672c01 0202c102 07616263 64656667 l fg,......abcdefg
     2c010202 c1020761 62636465 66672c01 l ,......abcdefg,.
     0202c102 07616263 64656667 2c010202 l .....abcdefg,...
     c1020761 62636465 66672c01 0202c102 l ...abcdefg,.....

    其中在定位文件目录300的au编号的时候也可以通过如下简单办法:

    select disk_kffxp, AU_kffxp, xnum_kffxp from x$kffxp
    where group_kffxp=1  
    and number_kffxp=300 ;
    DISK_KFFXP   AU_KFFXP XNUM_KFFXP
    ---------- ---------- ----------
         0     9931           0
         0     9932           1
  • 相关阅读:
    rsyslog
    java实现黄金分割数
    java实现黄金分割数
    java实现黄金分割数
    java实现黄金分割数
    java实现黄金分割数
    java实现低碳生活大奖赛
    java实现低碳生活大奖赛
    java实现低碳生活大奖赛
    java实现低碳生活大奖赛
  • 原文地址:https://www.cnblogs.com/zylong-sys/p/12016085.html
Copyright © 2020-2023  润新知