• 利用DBMS_ROWID.ROWID_CREATE来找出事务等待的行数据


    在v$session视图中有四个字段,如下:

    Wait information in v$session view
    ROW_WAIT_OBJ# NUMBER Object ID for the table containing the row specified in ROW_WAIT_ROW#
    ROW_WAIT_FILE# NUMBER

    Identifier for the datafile containing the row specified in ROW_WAIT_ROW#.This column is valid only if the session is currently waiting for another transaction to commit and the value of ROW_WAIT_OBJ# is not -1.

    ROW_WAIT_BLOCK# NUMBER

    Identifier for the block containing the row specified in ROW_WAIT_ROW#.This column is valid only if the session is currently waiting for another transaction to commit and the value of ROW_WAIT_OBJ# is not -1.

    ROW_WAIT_ROW# NUMBER Current row being locked. This column is valid only if the session is currently waiting for another transaction to commit and the value of ROW_WAIT_OBJ# is not -1

    当我们在遭遇:enq: TX - row lock contention,这些等待事件时,可通过dbms_rowid.rowid_create(xx,xx,xx,xx,xx)来创建等待的数据行的rowid.

    而在此要注意的是这个内建的procedure的第二个参数,先看下oracle 的doc对于dbms_rowid.rowid_create的解释:

    BMS_ROWID.ROWID_CREATE (
        rowid_type            IN NUMBER,
        object_number       IN NUMBER,
        relative_fno          IN NUMBER,
        block_number         IN NUMBER,
        row_number           IN NUMBER)
    参数:
    rowid_type:rowid类型(restricted或者extended)。设置rowid_type为0时,代表restricted ROWID(此时,将忽略参数object_number):设置rowid_type为1时,代表extended ROWID。
    object_number:数据对象编号(仅restricted类型rowid可用)。
    relative_fno:所在数据文件编号。
    block_number:该数据文件中的数据块编号。
    row_number:在该块中的行编号。

    第二个参数写的是object_number,而其解释中的是数据对象编号,其对应的应该是dba_objects中的data_object_id字段。如下:

    SQL> desc dba_objects
     名称                                      是否为空? 类型
     ----------------------------------------- -------- ------------------------
     OWNER                                              VARCHAR2(30)
     OBJECT_NAME                                   VARCHAR2(128)
     SUBOBJECT_NAME                             VARCHAR2(30)
     OBJECT_ID                                        NUMBER
     DATA_OBJECT_ID                              NUMBER
     OBJECT_TYPE                                    VARCHAR2(19)
     CREATED                                            DATE
     LAST_DDL_TIME                                DATE
     TIMESTAMP                                        VARCHAR2(19)
     STATUS                                              VARCHAR2(7)
     TEMPORARY                                        VARCHAR2(1)
     GENERATED                                        VARCHAR2(1)
     SECONDARY                                        VARCHAR2(1)

    一般而言,object_id是这个table在oracle中的对象编号,而data_object_id,指的是数据物理存放的对象编号,应该是段编号。通常情况下,这二者相等,当然分区表除外(分区表只有一个object_id,有多个data_object_id)。

    当我们对table行truncate,move等操作的时候,可能就会引起二者不相等,如下例证:

    SQL> drop table t1;
    表已删除。
    SQL> create table t1(id number);
    表已创建。
    SQL> col object_name for a20
    SQL> select object_id,data_object_id,object_name from dba_objects where object_name='T1';
     OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
    ---------- -------------- --------------------
         52961          52961 T1

    (1):此时t1是个空表,无数据,我们进行truncate操作。

    SQL> truncate table t1;
    表被截断。
    SQL> select object_id,data_object_id,object_name from dba_objects where object_name='T1';
     OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
    ---------- -------------- --------------------
         52961          52961 T1

    我们发现空表时进行truncate操作,object_id 和data_object_id仍然是相等的。

    (2):插入数据,再次truncate

    SQL> insert into t1(id) values(1);
    已创建 1 行。
    SQL> commit;
    提交完成。
    SQL> select * from t1;
            ID
    ----------
             1
    SQL> truncate table t1;
    表被截断。
    SQL> select object_id,data_object_id,object_name from dba_objects where object_name='T1';
     OBJECT_ID DATA_OBJECT_ID OBJECT_NAME
    ---------- -------------- --------------------
         52961          52962 T1

    此时,二者已经不相等了。下面测试move操作。

    (3):表中无数据时进行move操作。

    下面是使用dbms_rowid.rowid_create的一个例子

    sys@JINGYONG> select rowid, t.*,dbms_rowid.rowid_relative_fno(rowid) relative_fno ,
      2  dbms_rowid.rowid_object(rowid) object_number ,
      3  dbms_rowid.rowid_block_number(rowid) block_number ,
      4  dbms_rowid.rowid_row_number(rowid) row_number
      5   from t where rownum<2;
    
    ROWID                      ID TEXT                           RELATIVE_FNO OBJECT_NUMBER BLOCK_NUMBER ROW_NUMBER
    ------------------ ---------- ------------------------------ ------------ ------------- ------------ ----------
    AAANB1AABAAAPAaAAA         20 ICOL$                                     1  53365        61466          0
    
    
    sys@JINGYONG>  select data_object_id from dba_objects where object_id=53365;
    
    DATA_OBJECT_ID
    --------------
             53365
    
    sys@JINGYONG>  select dbms_rowid.rowid_create(1,53365,1,61466,0) create_rowid fr
    om dual;
    
    CREATE_ROWID
    ------------------
    AAANB1AABAAAPAaAAA

    通过dbms_rowid.rowid_create(1,53365,1,61466,0)构造的rowid与原始的rowid是一样的.
    参数的意思:

    1表示rowid的类型为扩展rowid,类型为1;

    data_object_id 为53365,也就是文中t表对象的id;

    数据文件id为1 ,即system表空间文件;

    块的编号为61466号; 行数为第一行(第一行为值0) 。

    通过dbms_rowid.rowid_create函数查询被锁定的具体行
    查询被锁的会话和持有锁的会话,如果是exclusive锁则xidusn非零的表示已经执行并持有锁

    column o_name format a10
    column lock_type format a20
    column object_name format a15
    select rpad(oracle_username,10) o_name,
           session_id sid,
           decode(locked_mode,0,'None',1,'Null',2,'Row share',3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_type,
           object_name,
           all_objects.object_id,
           xidusn,
           xidslot,
           xidsqn
    from v$locked_object,all_objects
    where v$locked_object.object_id=all_objects.object_id;
    O_NAME SID     LOCK_TYPE      OBJECT_NAME   OBJECT_ID   XIDUSN    XIDSLOT   XIDSQN
    ---------- ------- -------------------- ---------------        -------------- ----------   ------------ ----------
    SYS   145     Row Exclusive    T                    53365            8             17               724
    SYS   148     Row Exclusive    T                    53365           0              0                 0

    下面的查询可以得到被锁定的session,被锁定的对象id和row number

    select sid,
           row_wait_obj# object_id,
           row_wait_file# file_no,
           row_wait_block# block,
           row_wait_row# row_num
    from v$session
    where row_wait_obj#=&object_id;
    Enter value for object_id: 53365
    old   7: where row_wait_obj#=&object_id
    new   7: where row_wait_obj#=53365
           SID OBJECT_ID        FILE_NO          BLOCK        ROW_NUM
    ---------- --------------   ----------       ----------   ----------
           148   51207           1               61466            0

    如果要对应行rowid则:

    sys@JINGYONG>  select dbms_rowid.rowid_create(1,53365,1,61466,0) create_rowid from dual;
    
    CREATE_ROWID
    ------------------
    AAANB1AABAAAPAaAAA
    

    有了rowid,具体的行就能定位了

  • 相关阅读:
    [Everyday Mathematics]20150226
    [Everyday Mathematics]20150225
    [Everyday Mathematics]20150224
    [Everyday Mathematics]20150223
    [Everyday Mathematics]20150222
    [Everyday Mathematics]20150221
    [Everyday Mathematics]20150220
    [Everyday Mathematics]20150219
    [Everyday Mathematics]20150218
    [Everyday Mathematic]20150217
  • 原文地址:https://www.cnblogs.com/princessd8251/p/3984066.html
Copyright © 2020-2023  润新知