In-Database Archiving

数据库内归档可以将表中的行标记为非活动状态来进行归档,这些非活动的行可以使用压缩来进行优化,但是应用程序看不到这些数据。如果想要看到这些数据的话可以通过在会话级别设置参数。

通过数据库内归档的技术,可以在一个数据库当中保存更多的数据,并维持更长的数据保存周期,并且不会降低应用程序的性能。这些归档数据也可以通过压缩来提高性能,应用升级的过程中,也可以延迟对这些归档数据的修改以此来提高升级效率。

开启数据库内归档

ROW ARCHIVAL子句用来开启数据库内归档,可以通过在CREATE TABLE的时候指定,也可以在创建完毕以后ALTER TABLE进行修改。

drop table t1 purge;

create table t1 (id number,name varchar2(10))
row archival;

# 开启或关闭归档
alter table t1 no row archival;
alter table t1 row archival;

# 查看字段
col column_name for a20
col data_type for a20
SELECT column_id,
 column_name,
 data_type,
 data_length,
 hidden_column
 FROM user_tab_cols
 WHERE table_name = 'T1'
 ORDER BY column_id;

 COLUMN_ID COLUMN_NAME          DATA_TYPE            DATA_LENGTH HID
---------- -------------------- -------------------- ----------- ---
         1 ID                   NUMBER                        22 NO
         2 NAME                 VARCHAR2                      10 NO
           ORA_ARCHIVE_STATE    VARCHAR2                    4000 YES        <<<<====如果开启数据库内归档,则会自动生成这个隐藏字段

# 关闭归档
alter table t1 no row archival;
SELECT column_id,
 column_name,
 data_type,
 data_length,
 hidden_column
 FROM user_tab_cols
 WHERE table_name = 'T1'
 ORDER BY column_id;

 COLUMN_ID COLUMN_NAME          DATA_TYPE            DATA_LENGTH HID
---------- -------------------- -------------------- ----------- ---
         1 ID                   NUMBER                        22 NO
         2 NAME                 VARCHAR2                      10 NO         <<<<==== ORA_ARCHIVE_STATE字段消失

生成一些数据

alter table t1 row archival;

insert into t1 
select level,'xb'||level from dual connect by level <=10;
commit;

col ora_archive_state for a10
select ora_archive_state,id,name from t1;

ORA_ARCHIV         ID NAME
---------- ---------- ----------
0                   1 xb1
0                   2 xb2
0                   3 xb3
0                   4 xb4
0                   5 xb5
0                   6 xb6
0                   7 xb7
0                   8 xb8
0                   9 xb9
0                  10 xb10

归档行数据

归档只是隐藏了行数据,并未实际的删除,这个隐藏参数主要是由ora_archive_state值来进行控制,只要是非’0’值,这行数据就会被隐藏,也就是归档的意思

update t1 
set ora_archive_state='10'
where id <6;
commit;

select ora_archive_state,id,name from t1;

ORA_ARCHIV         ID NAME
---------- ---------- ----------
0                   6 xb6
0                   7 xb7
0                   8 xb8
0                   9 xb9
0                  10 xb10

这时可以发现ID<6的数据都隐藏了,应用程序无法看到,正如前面所说,如果要看到全部数据,可以在会话级别设置参数

alter session set row archival visibility=all;
select ora_archive_state,id,name from t1;

ORA_ARCHIV         ID NAME
---------- ---------- ----------
10                  1 xb1
10                  2 xb2
10                  3 xb3
10                  4 xb4
10                  5 xb5
0                   6 xb6
0                   7 xb7
0                   8 xb8
0                   9 xb9
0                  10 xb10

# 再设置成只看活动的行
alter session set row archival visibility=active;
select ora_archive_state,id,name from t1;

ORA_ARCHIV         ID NAME
---------- ---------- ----------
0                   6 xb6
0                   7 xb7
0                   8 xb8
0                   9 xb9
0                  10 xb10

表之间归档属性传播

当通过CTAS等方式创建表时,行的归档属性是不会从原表传播到目标表的

drop table t2 purge;
create table t2 as select * from t1;

# 查询目标表,由于目标表没有开启归档,所有不包含隐藏列
xb@PDB12C> select id,name,ora_archive_state from t2;
select id,name,ora_archive_state from t2
               *
ERROR at line 1:
ORA-00904: "ORA_ARCHIVE_STATE": invalid identifier


xb@PDB12C> select id,name  from t2;

        ID NAME
---------- --------------------
         1 xb1
         2 xb2
         3 xb3
         4 xb4
         5 xb5
         6 xb6
         7 xb7
         8 xb8
         9 xb9
        10 xb10

开启目标表的归档,查询会发现ora_archive_state值都是0,也就是说表的行都是活动状态

alter session set row archival visibility = all;

alter table t2 row archival;

xb@PDB12C> select id,name,ora_archive_state  from t2;

        ID NAME                 ORA_ARCHIV
---------- -------------------- ----------
         1 xb1                  0
         2 xb2                  0
         3 xb3                  0
         4 xb4                  0
         5 xb5                  0
         6 xb6                  0
         7 xb7                  0
         8 xb8                  0
         9 xb9                  0
        10 xb10                 0

通过dbms_ilm.archivestatename过程来更新ora_archive_state列

update t2
set ora_archive_state=dbms_ilm.archivestatename(1)
where id <= 5;

commit;

xb@PDB12C> select id,name,ora_archive_state  from t2;

        ID NAME                 ORA_ARCHIV
---------- -------------------- ----------
         1 xb1                  1
         2 xb2                  1
         3 xb3                  1
         4 xb4                  1
         5 xb5                  1
         6 xb6                  0
         7 xb7                  0
         8 xb8                  0
         9 xb9                  0
        10 xb10                 0

重新查询原表的数据

xb@PDB12C> select id,name,ora_archive_state  from t1;

        ID NAME                 ORA_ARCHIV
---------- -------------------- ----------
         1 xb1                  10
         2 xb2                  10
         3 xb3                  10
         4 xb4                  10
         5 xb5                  10
         6 xb6                  0
         7 xb7                  0
         8 xb8                  0
         9 xb9                  0
        10 xb10                 0

这个时候,将原表的数据再次插入到目标表当中,看ora_archive_state的状态值是否也会插入过去

insert into t2
select id,name||'_new' from t1;
commit;

xb@PDB12C> select id,name,ora_archive_state  from t2;

        ID NAME                 ORA_ARCHIV
---------- -------------------- ----------
         1 xb1                  1
         2 xb2                  1
         3 xb3                  1
         4 xb4                  1
         5 xb5                  1
         6 xb6                  0
         7 xb7                  0
         8 xb8                  0
         9 xb9                  0
        10 xb10                 0
         1 xb1_new              0
         2 xb2_new              0
         3 xb3_new              0
         4 xb4_new              0
         5 xb5_new              0
         6 xb6_new              0
         7 xb7_new              0
         8 xb8_new              0
         9 xb9_new              0
        10 xb10_new             0

通过上面的结果可以看到ora_archive_state属性值并没有传播到新表当中去,新表中的行默认都仍然是活动状态,原来非活动的5条记录状态保持不变。