在工作中有時候碰到一些分區表,業務資料量很大,可能幾百G,上T的規模,而且做資料的導入導出的時候,會感覺到exp/expdp的時候生成的dump檔案太大了,做導入的時候也是很重的負擔。比如500G的dump,你在使用imp做導入的時候,别無選擇,隻能看着日志裡partition裡的資料一個一個被導入。impdp可能稍微好點,還能指定個并行,但是問題又來了,一個500G的dump。impdp是在最後才做commit。對于資料空間和Undo,cpu資源都是挑戰。
分區表有一個地方和普通表不同,對于每個分區可以單獨做dml,不會影響其他的分區,當然了,你得指定分區名。
基于以上的情況,我寫了一個腳本來完成exp/expdp,把一個很大的分區表按照分區生成對應的dump檔案,如果分區有100個分區,那麼就會有100個dump檔案。在資料導入的時候,也可以分區導入,以分區的形式單獨做導入,相當于把一個大的事物分成很多小的部分。可以看做是垂直切分。
比如說表big_table有100個分區,生成了100個dump,導出的時候一般比較快,導入的時候問題就來了。如果開啟100個單獨的程序去導入,系統負載不一定能接受,Undo的大小肯定不能保證這麼多的大事務,很可能會有Undo空間的問題。
這個時候可以考慮開啟幾個并行的程序來做資料導入,比如開啟5個程序來做資料導入,每個程序包含20個分區,這樣會對系統的負載減輕不少,同時也能提高速度。可以看做是水準切分。
parallel_no=$5
target_schema=$4
for i in {1..${parallel_no}}
do
sqlplus -s $1
set linesize 150
set pages 0
set feedback off
set trimspool on
spool $2_partition_parallel_$i.par_temp
select 'tables=' from dual;
spool off;
spool $2_partition_parallel_$i.par_temp append
select table_name||':'||partition_name||',' from (
select rownum,mod(rownum,${parallel_no})+1 parallel_no,table_name,partition_name,num_rows from user_tab_partitions where table_name=upper('$2') order by num_rows desc nulls last
)
where parallel_no=$i;
spool $2_partition_parallel_$i.par_temp2
spool $2_partition_parallel_$i.par_temp2 append
select 'PRDAPPO'||'.'||table_name||':'||partition_name||',' from (
where parallel_no=$i;
EOF
sed -e '/^$/d' -e '$s/.$//' $2_partition_parallel_$i.par_temp>$2_partition_parallel_$i.par_imp
rm $2_partition_parallel_$i.par_temp
sed -e '/^$/d' -e '$s/.$//' $2_partition_parallel_$i.par_temp2>$2_partition_parallel_$i.par_impdp
rm $2_partition_parallel_$i.par_temp2
echo exp $1 file=par${i}_$2.dmp log=par${i}_$2_exp.log statistics=none grants=n constraints=n indexes=n parfile=$2_partition_parallel_$i.par_imp buffer=9102000 "&" >> $2_partition_parallel_export.sh
echo imp $1 file=par${i}_$2.dmp log=par${i}_$2_imp.log statistics=none grants=n constraints=n indexes=n parfile=$2_partition_parallel_$i.par_imp buffer=91020000 ignore=Y commit=y "&" >> $2_partition_parallel_import.sh
echo expdp $1 directory=memo_dir dumpfile=par${i}_$2.dmp logfile=par${i}_$2_expdp.log parfile=$2_partition_parallel_$i.par_imp exclude=statistics,constraint,ref_constraint,index,comment,grant " &" >> $2_partition_parallel_expdp.sh &
echo "nohup " impdp $1 directory=memo_dir dumpfile=par${i}_$2.dmp parallel=2 include=table_data logfile=par${i}_$2_impdp.log parfile=$2_partition_parallel_$i.par_impdp TABLE_EXISTS_ACTION=append REMAP_SCHEMA=prdappo:MIG_TEST DATA_OPTIONS=SKIP_CONSTRAINT_ERRORS " &" >> $2_partition_parallel_impdp.sh &
生成的parfile檔案和parallel導入導出腳本如下:
-rw-r--r-- 1 testuser1 dba 1231 Jun 19 14:16 big_table_partition_parallel_1.par_imp
-rw-r--r-- 1 testuser1 dba 1687 Jun 19 14:16 big_table_partition_parallel_1.par_impdp
-rw-r--r-- 1 testuser1 dba 1253 Jun 19 14:16 big_table_partition_parallel_2.par_imp
-rw-r--r-- 1 testuser1 dba 1717 Jun 19 14:16 big_table_partition_parallel_2.par_impdp
-rw-r--r-- 1 testuser1 dba 1255 Jun 19 14:16 big_table_partition_parallel_3.par_imp
-rw-r--r-- 1 testuser1 dba 1719 Jun 19 14:16 big_table_partition_parallel_3.par_impdp
-rw-r--r-- 1 testuser1 dba 1255 Jun 19 14:16 big_table_partition_parallel_4.par_imp
-rw-r--r-- 1 testuser1 dba 1719 Jun 19 14:16 big_table_partition_parallel_4.par_impdp
-rw-r--r-- 1 testuser1 dba 1273 Jun 19 14:16 big_table_partition_parallel_5.par_imp
-rw-r--r-- 1 testuser1 dba 1737 Jun 19 14:16 big_table_partition_parallel_5.par_impdp
-rw-r--r-- 1 testuser1 dba 2150 Jun 19 14:16 big_table_partition_parallel_expdp.sh
-rw-r--r-- 1 testuser1 dba 905 Jun 19 14:16 big_table_partition_parallel_export.sh
-rw-r--r-- 1 testuser1 dba 1410 Jun 19 14:16 big_table_partition_parallel_impdp.sh
-rw-r--r-- 1 testuser1 dba 1010 Jun 19 15:08 big_table_partition_parallel_import.sh
-rw-r--r-- 1 testuser1 dba 5609 Jun 19 10:52 par1_big_table_expdp.log
-rw-r--r-- 1 testuser1 dba 5120 Jun 19 14:36 par1_big_table_exp.log
-rw-r--r-- 1 testuser1 dba 0 Jun 19 15:10 par1_big_table_imp.log
-rw-r--r-- 1 testuser1 dba 5688 Jun 19 10:52 par2_big_table_expdp.log
-rw-r--r-- 1 testuser1 dba 5200 Jun 19 14:37 par2_big_table_exp.log
-rw-r--r-- 1 testuser1 dba 0 Jun 19 15:10 par2_big_table_imp.log
-rw-r--r-- 1 testuser1 dba 5688 Jun 19 10:53 par3_big_table_expdp.log
-rw-r--r-- 1 testuser1 dba 5200 Jun 19 14:46 par3_big_table_exp.log
-rw-r--r-- 1 testuser1 dba 0 Jun 19 15:10 par3_big_table_imp.log
-rw-r--r-- 1 testuser1 dba 5688 Jun 19 10:53 par4_big_table_expdp.log
-rw-r--r-- 1 testuser1 dba 5200 Jun 19 14:38 par4_big_table_exp.log
-rw-r--r-- 1 testuser1 dba 0 Jun 19 15:10 par4_big_table_imp.log
-rw-r--r-- 1 testuser1 dba 5698 Jun 19 10:52 par5_big_table_expdp.log
-rw-r--r-- 1 testuser1 dba 5200 Jun 19 14:37 par5_big_table_exp.log
-rw-r--r-- 1 testuser1 dba 0 Jun 19 15:10 par5_big_table_imp.log