線上過期資料遷移到離線資料庫

pxbibm發表於2014-10-13

線上過期資料遷移到離線資料庫
當我們對海量資料的Oracle 資料庫進行管理和維護時,幾乎無一例外都會使用分割槽
(partition)技術。
在大資料時代,資料量從幾十GB 到幾十TB,幾乎翻了幾百倍,但是分割槽仍然很好地解決了幾乎所有資料管
理方面的問題。
分割槽是Oracle 資料庫中對海量資料儲存管理提供的一個應用很廣泛的技術,它可以
非常方便地載入資料、刪除資料和移動資料,特別是對於一個擁有海量資料的OLAP 以
及資料倉儲系統的資料庫來說,更是如此。

但是最分割槽最大的好處在於處理資料庫資料的過期化處理。

在海量資料的資料庫設計中,可能需要提前考慮資料庫中資料儲存的時間問題,或
者叫做資料的過期化問題,它的意思是,由於資料量太大,在資料庫中只保留特定時長
的資料,比如1 年前的資料就需要做過期化(歸檔化)處理。
這時候分割槽技術就能發揮非常好的作用。

我們透過一個具體的案例,來描述資料從線上資料庫遷移到離線資料庫的過程。

透過表空間傳遞(表空間匯出和匯入)的方式實現分割槽資料由線上資料庫向離線資料庫的搬遷。
SQL> alter system set db_create_file_dest=
'D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\ORCL\DATAFILE\';
System altered.
SQL> create tablespace ts_sales_2009_1 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_2 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_3 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_4 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_5 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_6 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_7 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_8 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_9 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_10 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_11 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2009_12 datafile size 50M autoextend on;
Tablespace created.
SQL> create tablespace ts_sales_2010_1 datafile size 50M autoextend on;
Tablespace created.
SQL>
其中第一條語句是設定一個資料檔案存放路徑,讓Oracle 自動在該路徑下建立檔案,
並使用Oracle 自己的方式為資料檔案命名。
接下來的語句就是為每個表分割槽建立一個獨立的表空間,從表空間名字上就可以看
出來。另外,同時為每個分割槽索引建立一個索引表空間。
然後我們建立表,將表的每個分割槽放到自己對應的表空間上。
下面是建立表的語句,包含13 個分割槽,時間跨度為1 年零1 個月。
SQL> CREATE TABLE sale_data
2 (sale_id NUMBER(5),
3 salesman_name VARCHAR2(30),
4 sales_amount NUMBER(10),
5 sales_date DATE)
6 PARTITION BY RANGE(sales_date)
7 (
8 PARTITION sales_2009_1 VALUES LESS THAN(TO_DATE('01/02/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_1 ,
9 PARTITION sales_2009_2 VALUES LESS THAN(TO_DATE('01/03/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_2 ,
10 PARTITION sales_2009_3 VALUES LESS THAN(TO_DATE('01/04/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_3 ,
11 PARTITION sales_2009_4 VALUES LESS THAN(TO_DATE('01/05/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_4 ,
12 PARTITION sales_2009_5 VALUES LESS THAN(TO_DATE('01/06/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_5 ,
13 PARTITION sales_2009_6 VALUES LESS THAN(TO_DATE('01/07/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_6 ,
14 PARTITION sales_2009_7 VALUES LESS THAN(TO_DATE('01/08/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_7 ,
15 PARTITION sales_2009_8 VALUES LESS THAN(TO_DATE('01/09/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_8 ,
16 PARTITION sales_2009_9 VALUES LESS THAN(TO_DATE('01/10/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_9 ,
17 PARTITION sales_2009_10 VALUES LESS THAN(TO_DATE('01/11/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_10 ,
18 PARTITION sales_2009_11 VALUES LESS THAN(TO_DATE('01/12/2009','DD/MM/YYYY'))
tablespace ts_sales_2009_11 ,
19 PARTITION sales_2009_12 VALUES LESS THAN(TO_DATE('01/01/2010','DD/MM/YYYY'))
tablespace ts_sales_2009_12 ,
20 PARTITION sales_2010_1 VALUES LESS THAN(TO_DATE('01/02/2010','DD/MM/YYYY'))
tablespace ts_sales_2010_1
21 );
Table created.
為分割槽表建立分割槽索引,每個分割槽索引放在各自對應的分割槽表空間上。
SQL> create index indsale_data on sale_data(dales_dat)
local
1 (
2 PARTITION sales_2009_1 tablespace ts_sales_2009_1 ,
3 PARTITION sales_2009_2 tablespace ts_sales_2009_2 ,
4 PARTITION sales_2009_3 tablespace ts_sales_2009_3 ,
5 PARTITION sales_2009_4 tablespace ts_sales_2009_4 ,
6 PARTITION sales_2009_5 tablespace ts_sales_2009_5 ,
7 PARTITION sales_2009_6 tablespace ts_sales_2009_6 ,
8 PARTITION sales_2009_7 tablespace ts_sales_2009_7 ,
9 PARTITION sales_2009_8 tablespace ts_sales_2009_8 ,
10 PARTITION sales_2009_9 tablespace ts_sales_2009_9 ,
11 PARTITION sales_2009_10 tablespace ts_sales_2009_10 ,
12 PARTITION sales_2009_11 tablespace ts_sales_2009_11 ,
13 PARTITION sales_2009_12 tablespace ts_sales_2009_12 ,
14 PARTITION sales_2010_1 tablespace ts_sales_2010_1
15 );
Index created.
SQL>
SQL> select partition_name,tablespace_name from user_segments
where segment_name in ('SALE_DATA','IND_SALE_DATA');
PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME
--------------- ------------- ------------------------------
SALES_2009_1 TABLE PARTITION TS_SALES_2009_1
SALES_2009_10 TABLE PARTITION TS_SALES_2009_10
SALES_2009_11 TABLE PARTITION TS_SALES_2009_11
SALES_2009_12 TABLE PARTITION TS_SALES_2009_12
SALES_2009_2 TABLE PARTITION TS_SALES_2009_2
SALES_2009_3 TABLE PARTITION TS_SALES_2009_3
SALES_2009_4 TABLE PARTITION TS_SALES_2009_4
SALES_2009_5 TABLE PARTITION TS_SALES_2009_5
SALES_2009_6 TABLE PARTITION TS_SALES_2009_6
SALES_2009_7 TABLE PARTITION TS_SALES_2009_7
SALES_2009_8 TABLE PARTITION TS_SALES_2009_8
SALES_2009_9 TABLE PARTITION TS_SALES_2009_9
SALES_2010_1 TABLE PARTITION TS_SALES_2010_1
SALES_2009_1 INDEX PARTITION TS_SALES_2009_1
SALES_2009_10 INDEX PARTITION TS_SALES_2009_10
SALES_2009_11 INDEX PARTITION TS_SALES_2009_11
SALES_2009_12 INDEX PARTITION TS_SALES_2009_12
SALES_2009_2 INDEX PARTITION TS_SALES_2009_2
SALES_2009_3 INDEX PARTITION TS_SALES_2009_3
SALES_2009_4 INDEX PARTITION TS_SALES_2009_4
SALES_2009_5 INDEX PARTITION TS_SALES_2009_5
SALES_2009_6 INDEX PARTITION TS_SALES_2009_6
SALES_2009_7 INDEX PARTITION TS_SALES_2009_7
SALES_2009_8 INDEX PARTITION TS_SALES_2009_8
SALES_2009_9 INDEX PARTITION TS_SALES_2009_9
SALES_2010_1 INDEX PARTITION TS_SALES_2010_1
從上面的結果可以看到,每個分割槽和分割槽索引都建立在各自的表空間上了。
下面我們就要為匯出分割槽表空間做準備了。
比如,現在我們要匯出的分割槽是SALES_2009_1,它對應的表空間為TS_SALES_2009_1。
需要注意的是,當以表空間傳遞的方式匯出表空間時,我們不能直接匯出分割槽所在
的表空間,這在Oracle 裡面是不允許的。
使用表空間傳遞的方式匯出資料,至少需要滿足下面的幾個條件:
● 源和目標資料庫必須使用相同的字符集和國家字符集;
● 目標資料庫不能包含同名的表空間;
● 表空間上的物件必須是自包含的。
前兩個條件比較好理解,我們來看第三個條件,它是什麼意思呢?
自包含的意思是,對於需要進行傳遞的表空間上的物件,它不會引用到表空間之外
的物件。比如:
● 索引在這個表空間上,但是它引用到的表在需要傳遞的表空間以外的其他表空間
上。
● 分割槽表的部分分割槽在需要傳遞的表空間以外的其他表空間上。
● 完整性約束的參考物件在需要傳遞的表空間以外的其他表空間上。
● 表中包含的LOB 物件儲存在需要傳遞的表空間以外的其他表空間上。
對於這個案例來說,每個表空間只儲存一個表分割槽,這樣我們就不能對單個表空
間進行表空間傳遞操作了,因為它上面儲存的物件不是自包含的。
可以透過下面的方式來檢查表空間是否符合以表空間傳遞的方式匯出。
SQL> exec dbms_tts.transport_set_check('TS_SALES_2009_1', TRUE);
PL/SQL procedure successfully completed.
SQL> SELECT * FROM transport_set_violations;
VIOLATIONS
--------------------------------------------------------------------------------
Default Partition (Table) Tablespace USERS for SALE_DATA not contained in transp
ortable set
Partitioned table TEST.SALE_DATA is partially contained in the transportable set
: check table partitions by querying sys.dba_tab_partitions
上面的資訊顯示了我們要傳遞的表空間有兩點不符合傳遞要求:
● 分割槽表的預設表空間沒有包含在傳遞的表空間。
● 表分割槽還有其他的分割槽,沒有在要傳遞的表空間上。
基於以上兩點原因,我們不能直接對分割槽的表空間進行移植,而這種資料儲存的設
計是合理的,所以我們需要考慮使用其他的方式來解決這個問題。
幸運的是,我們找到了一種方法,那就是分割槽交換。它的方法是這樣的:
● 建立一個臨時表;
● 在臨時表上建立索引;
● 將需要匯出的分割槽資料和分割槽索引與臨時表進行分割槽交換;
● 將臨時表和索引所在的表空間匯出。
具體的操作如下:
我們看到,最初的時候,各個分割槽對應在各自的表空間上。
SQL> select partition_name,tablespace_name,segment_type from user_segments
where segment_name='SALE_DATA';
PARTITION_NAME TABLESPACE_NAME SEGMENT_TYPE
----------------- ----------------- ------------------
SALES_2009_1 TS_SALES_2009_1 TABLE PARTITION
SALES_2009_10 TS_SALES_2009_10 TABLE PARTITION
SALES_2009_11 TS_SALES_2009_11 TABLE PARTITION
SALES_2009_12 TS_SALES_2009_12 TABLE PARTITION
SALES_2009_2 TS_SALES_2009_2 TABLE PARTITION
SALES_2009_3 TS_SALES_2009_3 TABLE PARTITION
SALES_2009_4 TS_SALES_2009_4 TABLE PARTITION
SALES_2009_5 TS_SALES_2009_5 TABLE PARTITION
SALES_2009_6 TS_SALES_2009_6 TABLE PARTITION
SALES_2009_7 TS_SALES_2009_7 TABLE PARTITION
SALES_2009_8 TS_SALES_2009_8 TABLE PARTITION
SALES_2009_9 TS_SALES_2009_9 TABLE PARTITION
SALES_2010_1 TS_SALES_2010_1 TABLE PARTITION
13 rows selected.
每個分割槽索引也和分割槽存放在同一個表空間上。
SQL> select partition_name,tablespace_name,segment_type from user_segments
where segment_name='IND_SALE_DATA';
PARTITION_NAME TABLESPACE_NAME SEGMENT_TYPE
----------------- ----------------- ------------------
SALES_2009_1 TS_SALES_2009_1 INDEX PARTITION
SALES_2009_10 TS_SALES_2009_10 INDEX PARTITION
SALES_2009_11 TS_SALES_2009_11 INDEX PARTITION
SALES_2009_12 TS_SALES_2009_12 INDEX PARTITION
SALES_2009_2 TS_SALES_2009_2 INDEX PARTITION
SALES_2009_3 TS_SALES_2009_3 INDEX PARTITION
SALES_2009_4 TS_SALES_2009_4 INDEX PARTITION
SALES_2009_5 TS_SALES_2009_5 INDEX PARTITION
SALES_2009_6 TS_SALES_2009_6 INDEX PARTITION
SALES_2009_7 TS_SALES_2009_7 INDEX PARTITION
SALES_2009_8 TS_SALES_2009_8 INDEX PARTITION
SALES_2009_9 TS_SALES_2009_9 INDEX PARTITION
SALES_2010_1 TS_SALES_2010_1 INDEX PARTITION
13 rows selected.
下面建立一個臨時表,並在表上建立索引。
SQL> create table tmp_sale_data_2009_1 as select * from sale_data where 1=2;
Table created.
SQL> create index IND_TMP_SALE_DATA_2009_1 on TMP_SALE_DATA_2009_1(SALES_DATE);
Index created.
最初的時候,我們看到臨時表和臨時表的索引都預設存放在USERS 表空間上。
SQL> COL SEGMENT_NAME FOR A30;
SQL> select tablespace_name,segment_name,segment_type from user_segments
where segment_name like '%SALE_DATA_2009_1';
TABLESPACE_NAME SEGMENT_NAME SEGMENT_TYPE
---------------------- ----------------------- ------------------
USERS TMP_SALE_DATA_2009_1 TABLE
USERS IND_TMP_SALE_DATA_2009_1 INDEX
首先向要交換的分割槽中插入一些資料。
SQL> begin
2 for i in 1..10000 loop
3 insert into sale_data values(i,'alan',i*10,to_date('2009-01-12','yyyy-mm-dd'));
4 end loop;
5 commit;
6 end;
7 /
PL/SQL procedure successfully completed.
SQL> select count(*) from sale_data;
COUNT(*)
----------
10000
SQL> select count(*) from sale_data partition(SALES_2009_1);
COUNT(*)
----------
10000
可以看到,要交換的分割槽SALES_2009_1 包含了10000 條記錄。
下面開始進行分割槽交換,包括分割槽索引,一併交換到臨時表上。
SQL> alter table sale_data exchange partition sales_2009_1
with table tmp_sale_data_2009_1 including indexes with validation;
Table altered.
完成了分割槽交換,下面我們來看看各個物件所在的表空間情況。
SQL> select partition_name,tablespace_name,segment_type from user_segments
where segment_name = 'SALE_DATA' or segment_name='IND_SALE_DATA' order by 2;
PARTITION_NAME TABLESPACE_NAME SEGMENT_TYPE
----------------- ----------------- ------------------
SALES_2009_10 TS_SALES_2009_10 TABLE PARTITION
SALES_2009_10 TS_SALES_2009_10 INDEX PARTITION
SALES_2009_11 TS_SALES_2009_11 INDEX PARTITION
SALES_2009_11 TS_SALES_2009_11 TABLE PARTITION
SALES_2009_12 TS_SALES_2009_12 INDEX PARTITION
SALES_2009_12 TS_SALES_2009_12 TABLE PARTITION
SALES_2009_2 TS_SALES_2009_2 INDEX PARTITION
SALES_2009_2 TS_SALES_2009_2 TABLE PARTITION
SALES_2009_3 TS_SALES_2009_3 INDEX PARTITION
SALES_2009_3 TS_SALES_2009_3 TABLE PARTITION
SALES_2009_4 TS_SALES_2009_4 INDEX PARTITION
SALES_2009_4 TS_SALES_2009_4 TABLE PARTITION
SALES_2009_5 TS_SALES_2009_5 INDEX PARTITION
SALES_2009_5 TS_SALES_2009_5 TABLE PARTITION
SALES_2009_6 TS_SALES_2009_6 TABLE PARTITION
SALES_2009_6 TS_SALES_2009_6 INDEX PARTITION
SALES_2009_7 TS_SALES_2009_7 TABLE PARTITION
SALES_2009_7 TS_SALES_2009_7 INDEX PARTITION
SALES_2009_8 TS_SALES_2009_8 TABLE PARTITION
SALES_2009_8 TS_SALES_2009_8 INDEX PARTITION
SALES_2009_9 TS_SALES_2009_9 INDEX PARTITION
SALES_2009_9 TS_SALES_2009_9 TABLE PARTITION
SALES_2010_1 TS_SALES_2010_1 INDEX PARTITION
SALES_2010_1 TS_SALES_2010_1 TABLE PARTITION
SALES_2009_1 USERS INDEX PARTITION
SALES_2009_1 USERS TABLE PARTITION
26 rows selected.
SQL> select tablespace_name,segment_name,segment_type from user_segments
where segment_name like '%SALE_DATA_2009_1';
TABLESPACE_NAME SEGMENT_NAME SEGMENT_TYPE
------------------------------ ------------------------------ ------------------
TS_SALES_2009_1 TMP_SALE_DATA_2009_1 TABLE
TS_SALES_2009_1 IND_TMP_SALE_DATA_2009_1 INDEX
SQL>
我們看到,分割槽SALES_2009_1 和相應的分割槽索引,已經交換到了USERS 表空間
上;而臨時表TMP_SALE_DATA_2009_1 和它的索引IND_TMP_SALE_DATA_2009_1
交換到了以前分割槽所在的表空間TS_SALES_2009_1 上。
現在分割槽中的資料已經交換到了臨時表中。
SQL> select count(*) from sale_data partition(SALES_2009_1);
COUNT(*)
----------
0
SQL> select count(*) from sale_data;
COUNT(*)
----------
0
SQL> select count(*) from TMP_SALE_DATA_2009_1 ;
COUNT(*)
----------
10000
SQL>
這樣就完成了表空間的交換,表空間TS_SALES_2009_1 上面的物件就是隻有一個自包
含的表TMP_SALE_DATA_2009_1。
可以透過下面的操作來驗證它。
SQL> conn / as sysdba
Connected.
SQL> exec dbms_tts.transport_set_check('TS_SALES_2009_1', TRUE);
PL/SQL procedure successfully completed.
SQL> SELECT * FROM transport_set_violations;
no rows selected
SQL>
我們看到,transport_set_violations 表中沒有資料,說明空間已經透過了檢查,可以
進行表空間傳遞操作了。
在進行表空間傳遞匯出前,需要將要操作的表空間設定為只讀。
SQL> alter tablespace TS_SALES_2009_1 read only;
Tablespace altered.
下面正式開始匯出表空間TS_SALES_2009_1。
D:\>expdp system/oracle DIRECTORY=exp_trans_ts DUMPFILE=tts.dmp
TRANSPORT_TABLESPACES= TS_SALES_2009_1 TRANSPORT_FULL_CHECK=y LOGFILE=tts.log
Export: Release 10.2.0.3.0 - Production on Saturday, 04 September, 2010 9:59:31
Copyright (c) 2003, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
Starting "SYSTEM"."SYS_EXPORT_TRANSPORTABLE_01": system/******** DIRECTORY=exp_trans_ts
DUMPFILE=tts.dmp TRANSPORT_TABL
ESPACES= TS_SALES_2009_1 TRANSPORT_FULL_CHECK=y LOGFILE=tts.log
Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
Processing object type TRANSPORTABLE_EXPORT/TABLE
Processing object type TRANSPORTABLE_EXPORT/INDEX
Processing object type TRANSPORTABLE_EXPORT/INDEX_STATISTICS
Processing object type TRANSPORTABLE_EXPORT/TABLE_STATISTICS
Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
Master table "SYSTEM"."SYS_EXPORT_TRANSPORTABLE_01" successfully loaded/unloaded
******************************************************************************
Dump file set for SYSTEM.SYS_EXPORT_TRANSPORTABLE_01 is:
D:\TTS.DMP
Job "SYSTEM"."SYS_EXPORT_TRANSPORTABLE_01" successfully completed at 10:01:34
匯出完成後,接下來的工作就是將匯出的檔案複製到離線資料庫伺服器上。
在離線資料庫中,首先要建立好需要匯入的分割槽表,直接建立在預設的表空間上就
可以,因為這些分割槽都是空的。
D:\>impdp system/oracle DIRECTORY=exp_trans_ts DUMPFILE=tts.dmp
TRANSPORT_DATAFILES='D:\ORACLE\PRODUCT\10.2.0\ORADATA\
ORCL\ORCL\DATAFILE\ORCL\DATAFILE\\TS_SALE_2009_1.DBF' LOGFILE=tts.log
Import: Release 10.2.0.3.0 - Production on Saturday, 04 September, 2010 10:18:53
Copyright (c) 2003, 2005, Oracle. All rights reserved.
Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.3.0 - Production
With the Partitioning, OLAP and Data Mining options
Master table "SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01" successfully loaded/unloaded
Starting "SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01": system/******** DIRECTORY=exp_trans_ts
DUMPFILE=tts.dmp TRANSPORT_DATA
FILES='D:\ORACLE\PRODUCT\10.2.0\ORADATA\ORCL\ORCL\DATAFILE\ORCL\DATAFILE\\TS_SALE_2009_1.DBF'
LOGFILE=tts.log
Processing object type TRANSPORTABLE_EXPORT/PLUGTS_BLK
Processing object type TRANSPORTABLE_EXPORT/TABLE
Processing object type TRANSPORTABLE_EXPORT/INDEX
Processing object type TRANSPORTABLE_EXPORT/INDEX_STATISTICS
Processing object type TRANSPORTABLE_EXPORT/TABLE_STATISTICS
Processing object type TRANSPORTABLE_EXPORT/POST_INSTANCE/PLUGTS_BLK
Job "SYSTEM"."SYS_IMPORT_TRANSPORTABLE_01" successfully completed at 10:19:16
這時候我們看到,臨時表和表空間以及表中的資料都匯入到了離線資料庫中。
SQL> col segment_name for a30;
SQL> select tablespace_name,segment_name,segment_type from user_segments
where segment_name like '%SALE_DATA_2009_1';
TABLESPACE_NAME SEGMENT_NAME SEGMENT_TYPE
----------------- ----------------- ------------------
TS_SALES_2009_1 TMP_SALE_DATA_2009_1 TABLE
TS_SALES_2009_1 IND_TMP_SALE_DATA_2009_1 INDEX
此時離線資料庫中分割槽及索引所在的表空間情況如下:
SQL> select partition_name,tablespace_name,segment_type from user_segments
where segment_name = 'SALE_DATA' or segment_name='IND_SALE_DATA' order by 2;
PARTITION_NAME TABLESPACE_NAME SEGMENT_TYPE
------------------------------ ------------------------------ ------------------
SALES_2009_1 USERS INDEX PARTITION
SALES_2009_1 USERS TABLE PARTITION
……
26 rows selected.
表中的資料情況:
SQL> select count(*) from TMP_SALE_DATA_2009_1 ;
COUNT(*)
----------
10000
SQL> select count(*) from sale_data partition(SALES_2009_1);
COUNT(*)
----------
0
我們最後一步的工作就是將匯入的臨時表交換到離線資料庫的分割槽表中。
SQL> alter table sale_data exchange partition sales_2009_1
with table tmp_sale_data_2009_1 including indexes with validation;
Table altered.
SQL> select tablespace_name,segment_name,segment_type from user_segments
where segment_name like '%SALE_DATA_2009_1';
TABLESPACE_NAME SEGMENT_NAME SEGMENT_TYPE
----------------- ----------------- ------------------
USERS TMP_SALE_DATA_2009_1 TABLE
USERS IND_TMP_SALE_DATA_2009_1 INDEX
SQL> select partition_name,tablespace_name,segment_type from user_segments
where segment_name = 'SALE_DATA' or segment_n
ame='IND_SALE_DATA' order by 2;
PARTITION_NAME TABLESPACE_NAME SEGMENT_TYPE
----------------- ----------------- ------------------
SALES_2009_1 TS_SALES_2009_1 INDEX PARTITION
SALES_2009_1 TS_SALES_2009_1 TABLE PARTITION
……
26 rows selected.
我們看到,傳遞過來的表空間TS_SALES_2009_1 上的資料和索引已經交換到了離
線資料庫的分割槽SALES_2009_1 上。
SQL> select count(*) from TMP_SALE_DATA_2009_1;
COUNT(*)
----------
0
SQL> select count(*) from sale_data partition(SALES_2009_1);
COUNT(*)
----------
10000
SQL>
臨時表中已經沒有了資料,而以前空的分割槽現在有了10000 條從線上資料庫中傳遞
過來的資料。
整個過程可以歸納為以下幾步:
● 在線上資料庫中透過臨時表的方式將需要過期處理的分割槽資料和索引交換出來;
● 透過表空間傳遞的方式匯出表空間;
● 將匯出的dmp 檔案和表空間資料檔案複製到離線資料庫中;
● 在離線資料庫中匯入表空間;
● 將匯入表空間上的臨時表資料和索引交換到離線資料庫的分割槽表中。
對於離線資料庫,通常資料是不做修改的,可以將表空間設定為只讀,有利於資料
的安全;同時也可以考慮進行分割槽壓縮,提高資料處理的速度。

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

相關文章