Oracle用分割槽表分割槽交換做歷史資料遷移
阿新 • • 發佈:2019-01-09
一。說明:
OLTP庫中有些表資料量大,且每月有持續的大量資料增加,由於歷史資料在此庫中不再做訪問,而是在另1個OLAP庫中做分析,所以會對歷史資料遷移至OLAP庫中。對這種歷史資料遷移的操作,較好的辦法是該表採用分割槽表。按時間分割槽後,可以對分割槽進行遷移。通過分割槽交換和表空間傳輸會很容易完成,而且效能上影響很小。關於分割槽表更多內容: http://blog.csdn.net/tanqingru/article/category/1397435
關於表空間傳更多內容: http://blog.csdn.net/tanqingru/article/category/1138527
二。例項:
1.創造需要的環境。
OLTP庫環境準備:
SQL> conn /as sysdba Connected. SQL> select * from V$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production PL/SQL Release 11.2.0.3.0 - Production CORE 11.2.0.3.0 Production TNS for Linux: Version 11.2.0.3.0 - Production NLSRTL Version 11.2.0.3.0 - Production SQL> show parameter db_create_file_dest NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ db_create_file_dest string /data01/qing create tablespace tan_2013_9 datafile size 5m autoextend on; create tablespace tan_2013_10 datafile size 5m autoextend on; create tablespace tan_2013_11 datafile size 5m autoextend on; create tablespace tan_2013_12 datafile size 5m autoextend on; create tablespace tan_2014_1 datafile size 5m autoextend on; create tablespace tan_2014_2 datafile size 5m autoextend on; create tablespace tan_2014_3 datafile size 5m autoextend on; create tablespace tan_2014_4 datafile size 5m autoextend on; create tablespace tan_2014_5 datafile size 5m autoextend on; create tablespace tan_2014_6 datafile size 5m autoextend on; create tablespace tan_2014_7 datafile size 5m autoextend on; create tablespace tan_2014_8 datafile size 5m autoextend on; conn tan/tan SQL> create table tan (t_id number(10), t_name varchar2(100), t_date date ) partition by range(t_date) (partition tan_2013_9 values less than(to_date('2013-10-01','yyyy-mm-dd')) tablespace tan_2013_9, partition tan_2013_10 values less than(to_date('2013-11-01','yyyy-mm-dd')) tablespace tan_2013_10, partition tan_2013_11 values less than(to_date('2013-12-01','yyyy-mm-dd')) tablespace tan_2013_11, partition tan_2013_12 values less than(to_date('2014-01-01','yyyy-mm-dd')) tablespace tan_2013_12, partition tan_2014_1 values less than(to_date('2014-02-01','yyyy-mm-dd')) tablespace tan_2014_1, partition tan_2014_2 values less than(to_date('2014-03-01','yyyy-mm-dd')) tablespace tan_2014_2, partition tan_2014_3 values less than(to_date('2014-04-01','yyyy-mm-dd')) tablespace tan_2014_3, partition tan_2014_4 values less than(to_date('2014-05-01','yyyy-mm-dd')) tablespace tan_2014_4, partition tan_2014_5 values less than(to_date('2014-06-01','yyyy-mm-dd')) tablespace tan_2014_5, partition tan_2014_6 values less than(to_date('2014-07-01','yyyy-mm-dd')) tablespace tan_2014_6, partition tan_2014_7 values less than(to_date('2014-08-01','yyyy-mm-dd')) tablespace tan_2014_7, partition tan_2014_8 values less than(to_date('2014-09-01','yyyy-mm-dd')) tablespace tan_2014_8 ); create index ind_tan on tan(t_date) local ( partition ind_tan_2013_9 tablespace tan_2013_9, partition ind_tan_2013_10 tablespace tan_2013_10, partition ind_tan_2013_11 tablespace tan_2013_11, partition ind_tan_2013_12 tablespace tan_2013_12, partition ind_tan_2014_1 tablespace tan_2014_1, partition ind_tan_2014_2 tablespace tan_2014_2, partition ind_tan_2014_3 tablespace tan_2014_3, partition ind_tan_2014_4 tablespace tan_2014_4, partition ind_tan_2014_5 tablespace tan_2014_5, partition ind_tan_2014_6 tablespace tan_2014_6, partition ind_tan_2014_7 tablespace tan_2014_7, partition ind_tan_2014_8 tablespace tan_2014_8 ); begin for i in 1.. 10000 loop if( mod(i,12)+1 <=8) then insert into tan values(i,'tan'||i,to_date('2014-'||(mod(i,12)+1)||'-01','yyyy-mm-dd')); else insert into tan values(i,'tan'||i,to_date('2013-'||(mod(i,12)+1)||'-01','yyyy-mm-dd')); end if; end loop; commit; end; / SQL> select count(*) from tan partition(tan_2013_12) ; COUNT(*) ---------- 833 SQL> select count(*) from tan partition(tan_2013_9) ; COUNT(*) ---------- 833 SQL> select count(*) from tan partition(tan_2014_8) ; COUNT(*) ---------- 833 SQL> select count(*) from tan partition(tan_2014_1) ; COUNT(*) ---------- 833 SQL> select partition_name,tablespace_name from dba_segments where segment_name in ('TAN','IND_TAN'); PARTITION_NAME TABLESPACE_NAME ------------------------------ ------------------------------ TAN_2014_8 TAN_2014_8 TAN_2014_7 TAN_2014_7 TAN_2014_6 TAN_2014_6 TAN_2014_5 TAN_2014_5 TAN_2014_4 TAN_2014_4 TAN_2014_3 TAN_2014_3 TAN_2014_2 TAN_2014_2 TAN_2014_1 TAN_2014_1 TAN_2013_9 TAN_2013_9 TAN_2013_12 TAN_2013_12 TAN_2013_11 TAN_2013_11 TAN_2013_10 TAN_2013_10 IND_TAN_2014_8 TAN_2014_8 IND_TAN_2014_7 TAN_2014_7 IND_TAN_2014_6 TAN_2014_6 IND_TAN_2014_5 TAN_2014_5 IND_TAN_2014_4 TAN_2014_4 IND_TAN_2014_3 TAN_2014_3 IND_TAN_2014_2 TAN_2014_2 IND_TAN_2014_1 TAN_2014_1 IND_TAN_2013_9 TAN_2013_9 IND_TAN_2013_12 TAN_2013_12 IND_TAN_2013_11 TAN_2013_11 IND_TAN_2013_10 TAN_2013_10 24 rows selected.
OLAP庫環境準備
<span style="font-family: Arial, Helvetica, sans-serif; font-size: 12px;">create tablespace tan_2013_7 datafile size 5m autoextend on;</span>
create tablespace tan_2013_8 datafile size 5m autoextend on; create table tan (t_id number(10), t_name varchar2(100), t_date date ) partition by range(t_date) (partition tan_2013_7 values less than(to_date('2013-08-01','yyyy-mm-dd')) tablespace tan_2013_7, partition tan_2013_8 values less than(to_date('2013-09-01','yyyy-mm-dd')) tablespace tan_2013_8 ); create index ind_tan on tan(t_date) local ( partition ind_tan_2013_7 tablespace tan_2013_7, partition ind_tan_2013_8 tablespace tan_2013_8 ); begin for i in 1.. 10000 loop insert into tan values(i,'tan'||i,to_date('2013-'||(mod(i,2)+7)||'-01','yyyy-mm-dd')); end loop; commit; end; / SQL> select count(*) from tan partition(tan_2013_8); COUNT(*) ---------- 5000 SQL> select count(*) from tan partition(tan_2013_7); COUNT(*) ---------- 5000
2.分割槽交換
現在要做的事是遷移2013年9月份資料。建立個臨時表:
SQL> create table tmp_tan_2013_9 as select * from tan where 1=2;
SQL> create index ind_tmp_tan_2013_9 on tmp_tan_2013_9(t_date);
分割槽交換。
SQL> alter table tan exchange partition tan_2013_9
with table tmp_tan_2013_9 including indexes with validation;
驗證:
SQL> select count(*) from tan partition(tan_2013_9) ;
COUNT(*)
----------
0
SQL> select count(*) from tmp_tan_2013_9;
COUNT(*)
----------
833
SQL> select partition_name,tablespace_name from dba_segments
where segment_name in ('TAN','IND_TAN');
PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------
TAN_2014_8 TAN_2014_8
TAN_2014_7 TAN_2014_7
TAN_2014_6 TAN_2014_6
TAN_2014_5 TAN_2014_5
TAN_2014_4 TAN_2014_4
TAN_2014_3 TAN_2014_3
TAN_2014_2 TAN_2014_2
TAN_2014_1 TAN_2014_1
TAN_2013_12 TAN_2013_12
TAN_2013_11 TAN_2013_11
TAN_2013_10 TAN_2013_10
IND_TAN_2014_8 TAN_2014_8
IND_TAN_2014_7 TAN_2014_7
IND_TAN_2014_6 TAN_2014_6
IND_TAN_2014_5 TAN_2014_5
IND_TAN_2014_4 TAN_2014_4
IND_TAN_2014_3 TAN_2014_3
IND_TAN_2014_2 TAN_2014_2
IND_TAN_2014_1 TAN_2014_1
IND_TAN_2013_12 TAN_2013_12
IND_TAN_2013_11 TAN_2013_11
IND_TAN_2013_10 TAN_2013_10
22 rows selected.
3. 表空間傳輸:
更多關於表空間傳輸的內容:http://blog.csdn.net/bamuta/article/category/1138527驗證表空間的自包含:
SQL> exec dbms_tts.transport_set_check('TAN_2013_9',TRUE);
PL/SQL procedure successfully completed.
SQL> select * from transport_set_violations;
no rows selected
另外表空間傳輸需要兩端庫的字符集一致。
匯出無資料:
SQL> alter tablespace tan_2013_9 read only;
[[email protected] ~]$ exp \'sys/oracle as sysdba\' tablespaces=tan_2013_9 transport_tablespace=y file=exp_tan_2013_9.dmp拷貝檔案
[[email protected] ~]$ scp exp_tan_2013_9.dmp 192.168.114.174:/home/oracle/
[[email protected] ~]$ scp /data01/qing/QING/datafile/o1_mf_tan_2013_9tht2cgh_.dbf 192.168.114.174:/data01/vm603/VM603/datafile/
在目標庫匯入元資料
[[email protected] ~]$ imp \'sys/oracle as sysdba\' transport_tablespace=y file=exp_tan_2013_9.dmp log=imp.log tablespaces=tan_2013_9 datafiles='/data01/vm603/VM603/datafile/o1_mf_tan_2013_9tht2cgh_.dbf'
將兩端庫的該表空間read write
SQL> alter tablespace tan_2013_9 read write;
4.目標庫再做分割槽交換
目標庫對就表增加分割槽:SQL> alter table tan add partition tan_2013_9 values less than (to_date('2013-10-01','yyyy-mm-dd')) tablespace tan_2013_9;
Table altered.
SQL> select count(*) from tan partition(tan_2013_9);
COUNT(*)
----------
0
在目標庫做一次分割槽交換。
SQL> alter table tan exchange partition tan_2013_9 with table tmp_tan_2013_9 including indexes with validation;
Table altered.
檢查
SQL> select count(*) from tan partition(tan_2013_9);
COUNT(*)
----------
833
SQL> select table_name,partition_name,tablespace_name from user_tab_partitions;
TABLE_NAME PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
TAN TAN_2013_8 TAN_2013_8
TAN TAN_2013_7 TAN_2013_7
TAN TAN_2013_9 TAN_2013_9
SQL> select index_name,partition_name,tablespace_name from user_ind_partitions;
INDEX_NAME PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
IND_TAN IND_TAN_2013_8 TAN_2013_8
IND_TAN IND_TAN_2013_7 TAN_2013_7
IND_TAN TAN_2013_9 TAN_2013_9
5.源庫刪掉已經遷移走的分割槽:
SQL> select table_name,partition_name,tablespace_name from user_tab_partitions;
TABLE_NAME PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
TAN TAN_2014_3 TAN_2014_3
TAN TAN_2014_2 TAN_2014_2
TAN TAN_2014_4 TAN_2014_4
TAN TAN_2014_5 TAN_2014_5
TAN TAN_2014_6 TAN_2014_6
TAN TAN_2014_7 TAN_2014_7
TAN TAN_2014_8 TAN_2014_8
TAN TAN_2013_10 TAN_2013_10
TAN TAN_2013_11 TAN_2013_11
TAN TAN_2013_12 TAN_2013_12
TAN TAN_2014_1 TAN_2014_1
TAN TAN_2013_9 USERS
12 rows selected.
SQL> <strong>alter table tan drop partition tan_2013_9;</strong>
Table altered.
SQL> select table_name,partition_name,tablespace_name from user_tab_partitions;
TABLE_NAME PARTITION_NAME TABLESPACE_NAME
------------------------------ ------------------------------ ------------------------------
TAN TAN_2014_3 TAN_2014_3
TAN TAN_2014_2 TAN_2014_2
TAN TAN_2014_4 TAN_2014_4
TAN TAN_2014_5 TAN_2014_5
TAN TAN_2014_6 TAN_2014_6
TAN TAN_2014_7 TAN_2014_7
TAN TAN_2014_8 TAN_2014_8
TAN TAN_2013_10 TAN_2013_10
TAN TAN_2013_11 TAN_2013_11
TAN TAN_2013_12 TAN_2013_12
TAN TAN_2014_1 TAN_2014_1