海量数据迁移之分区并行切分

在海量的数据迁移中,如果某个表特别大,可以考虑对表中的分区进行切分,比如某个表有100g,还有100个分区,那么可以考虑针对这100个分区,那么可以考虑把这100个分区看成100个表进行并行抽取,如果某个分区数据比较多,可能生成5个dump,那么着100个分区,就可能生成105个分区以上。
那么如果有100多个表,那么可能分区都算进来就可能有上千个。如何对这上千个dump进行最快的加载呢。
可以考虑基于分区的并行切分,里面可能还涉及一些算法的知识。

目前生成了如下的数据报告,我们需要基于这个报告来对如下的表/分区进行切分。
REEMENT这个表不是分区表,所以在分区信息的地方填写了默认值'x',在数据加载的时候会进行过滤。
MEMO这个表比较大,对于分区partition(P0_A1000_E3),生成的dunp序号为21,22,23,总共有3个dump。在数据加载的时候就可以先加载21号dump,然后22号dump,23号dump

MEMO partition(P0_A1000_E3) 3 21..23
MEMO partition(P0_A1000_E2) 3 18..20
MEMO partition(P0_A1000_E1) 3 15..17
USR_GRP_MEMBERS x 2 1..3
REEMENT x 2 1..3
MEMO partition(PMAXVALUE_AMAXVALUE_EMAXVALUE) 1 699..700
MEMO partition(P9_A3000_E5) 2 697..698
MEMO partition(P9_A3000_E4) 2 695..696
MEMO partition(P9_A3000_E3) 2 693..694
MEMO partition(P9_A3000_E2) 2 691..692
MEMO partition(P9_A3000_E1) 2 689..690
MEMO partition(P9_A3000_E0) 2 687..688
MEMO partition(P9_A2000_E5) 2 685..686
MEMO partition(P9_A2000_E4) 2 683..684
MEMO partition(P9_A2000_E3) 2 681..682
MEMO partition(P9_A2000_E2) 2 679..680
MEMO partition(P9_A2000_E1) 2 677..678
MEMO partition(P9_A1000_E0) 2 657..658

我们现在就需要基于第三列的信息,对表、分区表进行切分。使得启用的多个并行进程能够最大程度的达到平衡。
我们可以使用如下的脚本来进行表、分区的并行切分。
比如我们考虑启用6个并行的进程,生成的日志类似下面的形式。可以看到切分还是很均匀的。

move INVOICE partition(A11_B6)  to par6_
move INVOICE partition(A11_B4)  to par1_
move INVOICE partition(A11_B2)  to par2_
move INVOICE partition(A11_B10)  to par3_
move INVOICE partition(A10_B8)  to par4_
move INVOICE partition(A10_B6)  to par5_
move INVOICE partition(A10_B4)  to par6_
move INVOICE partition(A10_B2)  to par1_
move INVOICE partition(A10_B10)  to par2_
move RESOURCE partition(A9)  to par3_
move RESOURCE partition(A8)  to par4_
move RESOURCE partition(A7)  to par5_
move RESOURCE partition(A6)  to par6_
move RESOURCE partition(A5)  to par1_
move RESOURCE partition(A4)  to par2_
move RESOURCE partition(A3)  to par3_
move RESOURCE partition(A2)  to par4_
move RESOURCE partition(A1)  to par5_
move RESOURCE partition(A0)  to par6_
213
213
213
213
214
214

脚本如下:

par_file_name=$1
sort -rn -k3 $par_file_name > ${par_file_name}_tmp
mv  ${par_file_name}_tmp  ${par_file_name}

par_no=$2
obj_length=`cat ${par_file_name}|wc -l `
echo $obj_length

for i in {1..$par_no}
do
sed -n ''$i'p' ${par_file_name}> par${i}_${par_file_name}
export par${i}_sum=`cat par${i}_${par_file_name}|awk '{print $3}' | awk '{sum+=$1}END{print sum}'`
#echo `eval echo \\${par${i}_sum}`
done

function getMin
{
param_no=$#

for i in {1..$param_no}
do
export par${i}_=`eval echo \\${${i}}`
done

min_sum=$par1_
min_par=par1_

for i in {2..$param_no};
do
j=`expr $i - 1`
tmp_cur_par=par${i}_
tmp_cur_sum=`eval echo   \\${${tmp_cur_par}}`
if [ $min_sum -le $tmp_cur_sum  ]
then
 min_sum=$min_sum
 min_par=$min_par
else
 min_sum=$tmp_cur_sum
 min_par=$tmp_cur_par
fi
done

echo  $min_par
}

function getSumList
{
for k in {1..$par_no}
do
#export par${k}_sum=`cat par${k}_${par_file_name}|awk '{print $3}' | awk '{sum+=$1}END{print sum}'`
#echo `eval echo \\${par${k}_sum}`

#par_list="$par_list  `eval echo \\${par${k}_sum}`"
#echo $par_list

tmp_sum=`cat par${k}_${par_file_name}|awk '{print $3}' | awk '{sum+=$1}END{print sum}'`
echo $tmp_sum
#tmp_par_list=${tmp_par_list} "" $tmp_sum
done
#echo $tmp_par_list
}

j=`expr $par_no + 1`
for i in {$j..${obj_length}}
do
tmp_obj=`sed -n ''$i'p' ${par_file_name}`

par_list=`getSumList`
tmp_par=`getMin  $par_list`
echo 'move '`sed -n ''$i'p' ${par_file_name}|awk '{print $1 " " $2}'` ' to '$tmp_par
echo $tmp_obj >> ${tmp_par}${par_file_name}
tmp_par=0
done

for i in {1..$par_no}
do
cat par${i}_${par_file_name}|awk '{print $3}' | awk '{sum+=$1}END{print sum}'
done

时间: 2024-10-23 20:16:32

海量数据迁移之分区并行切分的相关文章

海量数据迁移之使用分区并行切分导入

在之前的章节中讨论过怎么把一个很大的分区表切分为若干的dump文件,在数据加载的时候能够同时做基于每个分区的数据导入,如果有些分区比较大,有几十个dump文件,那么这个分区做数据导入的时候是不能再进行并行切分了. 现在在准生产环境中先查找了如下的表,charge,memo,charge_rel数量级都过亿,而且memo表中还含有lob字段.其他两个分区尽管字段没有特殊之处,但是分区数很多.都在几百个左右. charge  133036878memo 186700029    CHARGE_REL

海量数据迁移之通过rowid切分大表

在之前的章节中,讨论过了通过 分区+并行等方式来进行超大的表的切分,通过这种方式能够极大的提高数据的平均分布,但是不是最完美的. 比如在数据量再提高几个层次,我们假设这个表目前有1T的大小.有10个分区,最大的分区有400G,那么如果我们想尽可能的平均的导出数据,使用并行就不一定能够那么奏效了. 比方说我们要求每个dump文件控制在200M总有,那样的话400G的分区就需要800个并行才能完成,在实际的数据库维护中,我们知道默认的并行数只有64个,提高几倍,也不可能超过800 所以在数据量极大的

海量数据迁移之外部表切分

在前几篇中讨论过海量数据的并行加载,基本思路就是针对每一个物理表都会有一个对应的外部表,在做数据迁移的时候,如果表有上百G的时候,一个物理表对应一个外部表性能上会没有任何提升.如果需要做数据插入的时候,对undo是极大的挑战,从某种程度上而言,性能应该要比datapump要差.这个时候可以考虑一个物理表对应多个外部表,比如一个表有100G.可以考虑生成100个external dump 文件,然后加载生成100个外部表,每个dump文件对应一个外部表,这样做数据的插入的时候就相对容易控制了.每一

oracle 12c R1 在线迁移数据文件、在线迁移表分区或者子分区例子

在线重定义数据文件: 在oracle 12c R1之前的版本中,如果在线移动数据文件需要将表空间或者数据文件离线,然后操作系统mv,recover后online数据文件或者表空间,在oracle 12c R1后可以直接在线重定义数据文件,这个过程用户可以进行查询.DML以及DDL的任务,另外数据文件也可以直接在存储设备间迁移,比如ASM到文件系统的相互迁移. SQL> select name from v$datafile; NAME ------------------------------

迁移LVM分区到新的逻辑卷/驱动器(第六部分)

迁移LVM分区到新的逻辑卷/驱动器(第六部分) 这是我们正在进行的LVM系列的第六部分.在本文中,我们将为大家展示怎样在线将现存的逻辑卷迁移到其它新的驱动器.在开始之前,我想要先来介绍一下LVM迁移及其特性. LVM存储迁移 什么是LVM迁移? LVM迁移是LVM众多优秀特性之一,通过它,我们可以迁移逻辑卷到一个新的磁盘而不会丢失数据,也不用关机操作.该特性的功能是将数据从旧磁盘移动到新磁盘.通常,我们只是在一些磁盘发生错误时,才将数据从一个磁盘迁移到另外一个磁盘存储. 迁移特性 将逻辑卷从一个

海量数据迁移之一个误操作的问题总结

在生产环境中的数据迁移还是很惊心动魄的,毕竟生产的数据不容许有任何潜在的问题,很小的问题也可能导致业务的终端,这个时候dba的角色是很重要的,如果dba犯了一个很细小的问题,在海量数据迁移中可能会导致灾难性的结果,所以今天和大家讨论一下关于由vi误操作导致的问题及总结. 结合今天早上的例子来说明. 目前生产环境已经有大量的用户数据了,需要从老系统迁移一批用户数据过来,一切都在安装好计划进行准备和操作.我是采用了外部表的方式,把一个很大的表分为了几十上百个外部表,采用insert方式加载的. 数据

海量数据迁移之外部表并行抽取

在10g开始的新特性中,外部表是一个不容忽视的好工具.对于大型项目中海量数据使用sqlloader是一种全新的方式,不过很明显,sqlloader的可扩展性更强,但是基于oracle平台的数据迁移来说,外部表的性能也不错.对于数据迁移来说也是一个很好的方案. 使用外部表来做数据迁移,可以"动态"加载数据,能够很方便的从数据库中加载数据,对于数据校验来说就显得很有优势了,而对于sqlloader来说,可能得等到数据加载的时候才知道是不是有问题,如果对于数据的准确性要求极高,可以使用外部表

海量数据迁移之使用shell启用多个动态并行

在数据迁移中,可能有成百上千个表,有些表很大,有些表又很小. 如果启用了多个并行的进程,可能会有资源分配上的问题. 比如下面有10个表,100代表预计的时间为100分钟. table1  100 table2  90 table3  90 table4  80 table5  80 table6  70 table7  60 table8  60 table9  50 table10 40 如果分为4个进程来并行执行,可能一种比较理想的方案就是 parallel1: table1,table8

海量数据迁移之分区表批量insert性能改进

在平时的工作中接触到的分区表一般都比较大,而且分区也少则几十,多则几百,上千. 在数据迁移的时候,分区表的迁移更是块大骨头,因为数据量太大,而且有些分区表中还有一些lob字段,想直接通过sqlldr来迁移还是需要做一些额外的工作. 如果通过datapump分区导出数据,批量导入,也是一种思路,不过需要考虑好并发的进程. 通过oracle_datapump来做数据的导入,可能更为灵活,但是不是绝对的.最近就做了一些相关的数据导入测试,感触不少. 比如,目前我们需要导入的两个大表,一个是memo,一