(原)dbms_rowid.rowid_create来创建一个rowid

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

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 s-                ession 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 ses-                sion 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 transactio                n 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的解释:

DBMS_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>
SQL> col object_name for a20
SQL>
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

SQL>

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

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

原文地址:https://www.cnblogs.com/taowang2016/p/3129615.html