應用ROWDEPENDENCIES行級跟蹤,查詢oracle表中資料行上最後的DML時間

lhrbest發表於2017-05-19

  在Oracle 10g中的引入了ORA_ROWSCN偽列新特性。基於此種偽列所提供的資訊,我們可以方便地找出某個資料塊或某一個行最近被修改
的時間戳。它又分為兩種模式:一種是基於block這是預設的模式(塊級跟蹤,非行依賴性(NOROWDEPENDENCIES));還有一種是基於row上,這種模式只能在建裡表時指定ROWDEPENDENCIES(行級跟蹤),不可以透過後期的alter  table語句來將表修改為ROWDEPENDENCIES
       我們知道,每個Block在頭部是記錄了該block最近事務的SCN的,所以預設情況下,只需要從block頭部直接獲取這個值就可以了,不需要其他任何的開銷,Oracle就能做到這一點。但是這明顯是不精確的,一個block中會有很多行記錄,每次事務不可能影響到整個block中所有的行,所以這是一個非常不精準的估算值,同一個block的所有記錄的ORA_ROWSCN都會是相同的,基本上沒有多大的使用價值。
       如果在建表的時候開啟行級跟蹤選項,Oracle則可以為每一行記錄精確的SCN,那麼顯然不能再直接從block頭部獲取。要獲得足夠的資訊,肯定要付出一定的代價,Oracle必須為每一行儲存這個實際的SCN。所以這個行級跟蹤的選項,只能在建表的時候指定,而不能透過alter table來修改現有的表,否則需要修改每一行記錄的物理儲存格式,代價是可想而知的。

在10g之前,很多系統要實現增量資料抽取,要麼透過解析日誌,要麼加觸發器,要麼就在表上加一個時間截欄位。ORA_ROWSCN其實就是第三種方式,只是這個欄位由Oracle來維護,這樣可以避免一些應用繞過時間截去更新其他欄位帶來的問題。
下面是官方說明:
NOROWDEPENDENCIES | ROWDEPENDENCIES
This clause lets you specify whether table will use row-level dependency tracking.
With this feature, each row in the table has a system change number (SCN) that
represents a time greater than or equal to the commit time of the last transaction that
modified the row. You cannot change this setting after table is created.

ROWDEPENDENCIES Specify ROWDEPENDENCIES if you want to enable row-level
dependency tracking. This setting is useful primarily to allow for parallel propagation
in replication environments. It increases the size of each row by 6 bytes.

NOROWDEPENDENCIES Specify NOROWDEPENDENCIES if you do not want table
to use the row-level dependency tracking feature. This is the default.

      在預設情況下,10g下表會以非行依賴性(NOROWDEPENDENCIES)的屬性建立,這意味著我們可觀察的ORA_ROWSCN資訊是以塊級跟蹤的,無法分辨同一塊內的多行間不同的修改時間。為了達到行級粒度的跟蹤我們需要在建表時指定基於行依賴性的ROWDEPENDENCIES字句。舉例如下:


SQL> select * from global_name;

GLOBAL_NAME
--------------------------------------------------------------------------------


SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE    10.2.0.4.0      Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production

SQL> drop table maclean;
Table dropped.

SQL> create table maclean(t1 int,t2 timestamp) ;
Table created.

SQL> insert into maclean values(1,systimestamp);
1 row created.

SQL> commit;
Commit complete.

SQL> insert into maclean values(2,systimestamp);
1 row created.

SQL> commit;
Commit complete.


SQL> alter session set nls_timestamp_format='hh24:mi:ss';
Session altered.

SQL> col t2 for a35
SQL> col orscn for a35

SQL> select scn_to_timestamp(ora_rowscn) orscn,t2 from maclean;

ORSCN                               T2
----------------------------------- -----------------------------------
20:30:11                            20:29:56
20:30:11                            20:30:10

/* 可以看到預設情況下建立的資料表使用塊級依賴性追蹤(Block-level Dependency Tracking)
   故而其返回的ORA_ROWSCN偽列僅能代表某資料塊最近被更新的SCN
*/

create table maclean_rd(t1 int,t2 timestamp) rowdependencies;
Table created.

SQL> select table_name,dependencies from user_tables where dependencies!='DISABLED';
TABLE_NAME                     DEPENDEN
------------------------------ --------
MACLEAN_RD                     ENABLED


/* 包括字典基表在內所有的表都會預設以NOROWDEPENDENCIES建立*/

SQL> insert into maclean_rd values(1,systimestamp);

1 row created.

SQL> commit;

Commit complete.

SQL> insert into maclean_rd values(2,systimestamp);

1 row created.

SQL> commit;

Commit complete.

SQL> select scn_to_timestamp(ora_rowscn) orscn,t2 from maclean_rd;

ORSCN                               T2
----------------------------------- -----------------------------------
20:31:26                            20:31:25
20:31:35                            20:31:37

/* 可以看到在行依賴性跟蹤情況下,ORA_ROWSCN反映的時間戳與插入的時間戳間仍會有誤差;
   顯然這種誤差部分源於scn_to_timestamp函式使用的smon_scn_time SCN記錄表也僅是粗略記錄SCN對應的時間戳。
*/

SQL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from maclean_rd;

DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
------------------------------------ ------------------------------------
                                   1                                94122
                                   1                                94122

/* 以上透過rowid找到了插入的2行所在的資料塊*/



SQL> alter system dump datafile '/s01/10gdb/oradata/CLINICA/datafile/o1_mf_system_6fp8d3f0_.dbf' block 94122;
System altered.

SQL> oradebug setmypid;
Statement processed.
SQL> oradebug tracefile_name;
/s01/10gdb/admin/clinica/udump/clinica_ora_12934.trc

block_row_dump:
tab 0, row 0, @0x1f88
tl: 24 fb: --H-FL-- lb: 0x0  cc: 2
dscn 0x0000.0351b8bd
col  0: [ 2]  c1 02
col  1: [11]  78 6f 01 02 15 20 1a 21 d8 52 68
tab 0, row 1, @0x1f70
tl: 24 fb: --H-FL-- lb: 0x0  cc: 2
dscn 0x0000.0351b8c4
col  0: [ 2]  c1 03
col  1: [11]  78 6f 01 02 15 20 26 02 ab c2 f8

/* 可以從block dump中看到每行都多出了dscn資訊,這就是基於行追蹤的行級ORA_ROWSCN資訊的來源。
   注意這裡的dscn需要佔用6個位元組的空間,換而言之啟用ROWDEPENDENCIES會為每一行多出6個位元組的磁碟開銷。
*/

/* 此外行級追蹤僅能在建立表(create table)的同時指定,而無法使用ALTER TABLE來修改  */

SQL> alter table maclean move tablespace users ROWDEPENDENCIES;
alter table maclean move tablespace users ROWDEPENDENCIES
                                          *
ERROR at line 1:
ORA-14133: ALTER TABLE MOVE cannot be combined with other operations


參考:http://mingyue19850801.blog.163.com/blog/static/1952082020116271153994/  明月       
               http:///archives/%E5%9F%BA%E4%BA%8E%E8%A1%8C%E8%B7%9F%E8%B8%AA%E7%9A%84rowdependencies-ora_rowscn%E4%BF%A1%E6%81%AF.html      

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2139595/,如需轉載,請註明出處,否則將追究法律責任。

相關文章