• 说说Oracle的rowid


    在Oracle中rowid唯一标识每条记录所在的位置,它作为一个伪列在查询中出现:

    select rowid,id                                  
    from test_table
    where rownum<=10 ;
    ROWID                      ID
    ------------------ ----------
    AAAVcbAAPAAAAALAAA          1
    AAAVcbAAPAAAAALAAB          2
    AAAVcbAAPAAAAALAAC          3
    AAAVcbAAPAAAAALAAD          4
    AAAVcbAAPAAAAALAAE          5
    AAAVcbAAPAAAAALAAF          6
    AAAVcbAAPAAAAALAAG          7
    AAAVcbAAPAAAAALAAH          8
    AAAVcbAAPAAAAALAAI          9
    AAAVcbAAPAAAAALAAJ         10

    rowid是由18个字符组成分4个部分,分别是:

    6个字符的对象编号,3个字符的文件号,6个字符的块编号,3个字符的行编号。

    每一个字符的取值范围以及对应的数值是:

    --------------------------------
    | A|  0|    | a| 26|    | 0| 52|
    | B|  1|    | b| 27|    | 1| 53|
    | C|  2|    | c| 28|    | 2| 54|
    | D|  3|    | d| 29|    | 3| 55|
    | E|  4|    | e| 30|    | 4| 56|
    | F|  5|    | f| 31|    | 5| 57|
    | G|  6|    | g| 32|    | 6| 58|
    | H|  7|    | h| 33|    | 7| 59|
    | I|  8|    | i| 34|    | 8| 60|
    | J|  9|    | j| 35|    | 9| 61|
    | K| 10|    | k| 36|    | +| 62|
    | L| 11|    | l| 37|    | /| 63|
    | M| 12|    | m| 38|    |  |   |
    | N| 13|    | n| 39|    |  |   |
    | O| 14|    | o| 40|    |  |   |
    | P| 15|    | p| 41|    |  |   |
    | Q| 16|    | q| 42|    |  |   |
    | R| 17|    | r| 43|    |  |   |
    | S| 18|    | s| 44|    |  |   |
    | T| 19|    | t| 45|    |  |   |
    | U| 20|    | u| 46|    |  |   |
    | V| 21|    | v| 47|    |  |   |
    | W| 22|    | w| 48|    |  |   |
    | X| 23|    | x| 49|    |  |   |
    | Y| 24|    | y| 50|    |  |   |
    | Z| 25|    | z| 51|    |  |   |
    --------------------------------

    可以看到rowid是一个64进制的表示方式,利用上述对应表即可计算出:

    对象编号:AAAVcb  = 87835

    文件号:AAP = 41

    块号:AAAAAL =11

    行号:AAA~AAJ = 0 ~ 9

    16进制的转换完全可以交给机器去做,Oracle也是这么认为的,于是提供了一个叫做dbms_rowid的包,它包含了一系列的方法,我们借助这个包就可完成上述的工作了:

    select rowid ,
      substr(rowid,1,6) ||' : '|| dbms_rowid.rowid_object(rowid)       "数据对象编号/object_id",
      substr(rowid,7,3) ||' : '|| dbms_rowid.rowid_relative_fno(rowid) "文件编号/file_id",
      substr(rowid,10,6)||' : '|| dbms_rowid.rowid_block_number(rowid) "块编号/block_id",
      substr(rowid,16,3)||' : '|| dbms_rowid.ROWID_ROW_NUMBER(rowid)   "行编号/row_num"
    from test_table 
    where rownum<=10;
    ROWID              数据对象编号/object_id    文件编号/file_id     块编号/block_id      行编号/row_num
    ------------------ ------------------------- -------------------- -------------------- ---------------
    AAAVcbAAPAAAAALAAA AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAA : 0
    AAAVcbAAPAAAAALAAB AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAB : 1
    AAAVcbAAPAAAAALAAC AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAC : 2
    AAAVcbAAPAAAAALAAD AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAD : 3
    AAAVcbAAPAAAAALAAE AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAE : 4
    AAAVcbAAPAAAAALAAF AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAF : 5
    AAAVcbAAPAAAAALAAG AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAG : 6
    AAAVcbAAPAAAAALAAH AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAH : 7
    AAAVcbAAPAAAAALAAI AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAI : 8
    AAAVcbAAPAAAAALAAJ AAAVcb : 87835            AAP : 15             AAAAAL : 11          AAJ : 9

    这个结果对不对呢?我们可以这样验证,注意,以下查询需要DBA权限。

    首先是object_id:

    select 
      owner,object_name,object_id 
    from dba_objects 
    where object_name='TEST_TABLE';
    OWNER      OBJECT_NAME           OBJECT_ID
    ---------- -------------------- ----------
    TEST       TEST_TABLE                8783

    然后是文件编号和块编号:

    select 
      owner,segment_name,segment_type,extent_id,
      file_id,block_id,blocks,bytes 
    from dba_extents 
    where segment_name='TEST_TABLE';
    OWNER  SEGMENT_NAME  SEGMENT_TYPE   EXTENT_ID  FILE_ID  BLOCK_ID  BLOCKS  BYTES
    ------ ------------- ------------- ---------- -------- --------- ------- ------
    TEST   TEST_TABLE    TABLE                  0       15         8       8  65536
    TEST   TEST_TABLE    TABLE                  1       15        16       8  65536

    编号为11的块落在了编号为0的exntent上,只能说是验证了一半,接下来我们将数据块dump出来看看,不过做之前先为这一行打上“标记”,看以下过程:

    test$logdw@logdw SQL> select rowid,t.* from test_table t where rownum<=5; 
    
    ROWID                      ID DATA
    ------------------ ---------- ------------------------------
    AAAVcbAAPAAAAALAAA          1                              Q
    AAAVcbAAPAAAAALAAB          2                              Q
    AAAVcbAAPAAAAALAAC          3                              Q
    AAAVcbAAPAAAAALAAD          4                              Q
    AAAVcbAAPAAAAALAAE          5                              Q
    
    5 rows selected.
    test$logdw@logdw SQL> update test_table set data=lpad('killkill',30) where id=1;
    
    1 row updated.
    test$logdw@logdw SQL> select rowid,t.* from test_table t where rownum<=5;      
    
    ROWID                      ID DATA
    ------------------ ---------- ------------------------------
    AAAVcbAAPAAAAALAAA          1                       killkill
    AAAVcbAAPAAAAALAAB          2                              Q
    AAAVcbAAPAAAAALAAC          3                              Q
    AAAVcbAAPAAAAALAAD          4                              Q
    AAAVcbAAPAAAAALAAE          5                              Q
    
    5 rows selected.
    test$logdw@logdw SQL> commit; 

    做好了“标记”,可以dump数据块了:

    sys$logdw@logdw SQL> select get_trace_name() from dual ; 
    
    GET_TRACE_NAME()
    -----------------------------------------------------------------
    /u01/app/oracle/diag/rdbms/logdw/logdw/trace/logdw_ora_29284.trc
    
    sys$logdw@logdw SQL> alter system dump datafile 15 block 11 ;
    
    System altered.

    打开trc文件,摘录如下:

    Start dump data blocks tsn: 10 file#:15 minblk 11 maxblk 11
    ......
    ......
    Dump of memory from 0x0000002A96F31A00 to 0x0000002A96F33A00
    ......
    ......
    2A96F31F20 20202020 20202020 20202020 6C696B20  [             kil]
    2A96F31F30 6C696B6C 02002C6C 1E03C102 20202020  [lkill,......    ]
    ......
    ......
    block_row_dump:
    tab 0, row 0, @0x4ac
    tl: 37 fb: --H-FL-- lb: 0x2  cc: 2
    col  0: [ 2]  c1 02
    col  1: [30]
     20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6b 69 6c
     6c 6b 69 6c 6c
    ......
    ......

    你找到killkill了吗?

  • 相关阅读:
    keras使用AutoEncoder对mnist数据降维
    maven插件生成可执行jar包
    python基于opencv实现人脸定位
    使用Jieba提取文章的关键词
    汉语词性对照表
    SQL优化
    keras基于卷积网络手写数字识别
    统计学习
    log4j和slf4j的区别
    log4j配置详解(非常详细)
  • 原文地址:https://www.cnblogs.com/killkill/p/1765851.html
Copyright © 2020-2023  润新知