In-Database Archiving

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

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

开启数据库内归档

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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字段消失

生成一些数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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值,这行数据就会被隐藏,也就是归档的意思

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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的数据都隐藏了,应用程序无法看到,正如前面所说,如果要看到全部数据,可以在会话级别设置参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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等方式创建表时,行的归档属性是不会从原表传播到目标表的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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,也就是说表的行都是活动状态

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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

重新查询原表的数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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的状态值是否也会插入过去

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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条记录状态保持不变。


In-Database Archiving
https://www.xbdba.com/2019/07/23/in-database-archiving/
作者
xbdba
发布于
2019年7月23日
许可协议