Oracle 12cR1-In-Database Archiving

在oracle 12cR1版本中推出了一个新功能“In-Database Archiving”。这个选项允许将记录标记为不活动(称作归档记录)。当你把记录设置为归档记录后,你在Oracle的会话中就无法查看了。我曾经设计过这样的表。那个时候是通过字段标识来控制的,在一张数据表最后面增加一个字段isdelete,所有的删除都是更新操作,当我要对一条数据记录进行删除的时候,就默认发起update语句,把这条记录对应的isdelete更新为Y。然后查询只会查找isdelete=N的数据。这么做的好处就是我把历史删除的数据做了永久保留。对用户来说是透明的。要使用这个选项,必须在建表的时候指定row archival。或者建完表之后通过alter table来修改。

CREATE TABLE M1 (id NUMBER) ROW ARCHIVAL;

创建完表后,将自动会创建一个隐藏列ORA_ARCHIVE_STATE,专门用于记录活动的和不活动的数据。

SQL> SELECT column_id, table_name, column_name, hidden_column FROM dba_tab_cols WHERE table_name='M1' order by column_id;

 COLUMN_ID TABLE_NAME                          COLUMN_NAME                         HID
---------- ----------------------------------- ----------------------------------- ---
         1 M1                                  ID                                  NO
           M1                                  ORA_ARCHIVE_STATE                   YES

一旦新数据插入到表中,所有的记录默认都是active的,在会话中始终可见。 active的记录,ORA_ARCHIVE_STATE的值默认都为0,不是active的记录,ORA_ARCHIVE_STATE的值将为1。

SQL> INSERT INTO m1 SELECT LEVEL FROM dual CONNECT BY LEVEL <= 5;
5 rows created.

SQL> commit;
Commit complete.

SQL> SELECT * FROM m1;
        ID
----------
         1
         2
         3
         4
         5

SQL> SELECT m1.*,ORA_ARCHIVE_STATE FROM m1;
        ID ORA_ARCHIVE_STATE
---------- --------------------
         1 0
         2 0
         3 0
         4 0
         5 0

如果我们要把123设置成不活动的记录,直接使用update进行更新,中间使用包DBMS_ILM.ARCHIVESTATENAME。

SQL> update m1 set ora_archive_state=DBMS_ILM.ARCHIVESTATENAME(1) where ID IN (1,2,3);   
3 rows updated.

SQL> commit; 
Commit complete.

此时我们在执行查询m1,可以看到只会显示4和5。

SQL> SELECT ORA_ARCHIVE_STATE, ID FROM M1;

ORA_ARCHIVE_STATE            ID
-------------------- ----------
0                             4
0                             5

当然我们也可以看到全部的记录,需要在session级别设置ROW ARCHIVAL VISIBILITY。

SQL> alter session set row archival visibility =all;
Session altered.

SQL> SELECT ORA_ARCHIVE_STATE, ID FROM M1;

ORA_ARCHIVE_STATE            ID
-------------------- ----------
1                             1
1                             2
1                             3
0                             4
0                             5

SQL> alter session set row archival visibility =active;
Session altered.

SQL> SELECT ORA_ARCHIVE_STATE, ID FROM M1;

ORA_ARCHIVE_STATE            ID
-------------------- ----------
0                             4
0                             5

查看执行计划,你会发现,该语句默认的在谓词上加上filter(“M1”.”ORA_ARCHIVE_STATE”=’0′)的条件进行过滤操作。

SQL> select * from table(dbms_xplan.display());

PLAN_TABLE_OUTPUT
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3061007841

--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     5 | 10075 |     3   (0)| 00:00:01 |
|*  1 |  TABLE ACCESS FULL| M1   |     5 | 10075 |     3   (0)| 00:00:01 |
--------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("M1"."ORA_ARCHIVE_STATE"='0')
17 rows selected.

当然要取消这个功能,只需要对alter table即可。

SQL> ALTER TABLE m1 NO ROW ARCHIVAL ; 
Table altered.

SQL> select * from m1;

        ID
----------
         1
         2
         3
         4
         5

如果用ctas来创建一个备份表,默认会根据原表的情况来保持一致,不会只复制active的数据,我们来演示一下这个情况。

SQL> alter table m1 row archival;
Table altered.

SQL> update m1 set ora_archive_state=DBMS_ILM.ARCHIVESTATENAME(1) where ID IN (1,2,3); 
3 rows updated.

SQL> commit;
Commit complete

SQL> select * from m1;
        ID
----------
         4
         5

SQL> create table m2 as select * from m1;
Table created.

SQL> select * from m2;

        ID
----------
         1
         2
         3
         4
         5 

正如我们所看到的,即使我们在源表M1上启用了行归档功能,但在我们使用CREATE TABLE AS SELECT语句创建表时,它并没有传播到结果表。

关注dbDao.com的新浪微博

扫码加入微信Oracle小密圈,了解Oracle最新技术下载分享资源

TEL/電話+86 13764045638
Email service@parnassusdata.com
QQ 47079569