海量数据迁移之外部表切分(r2笔记52天)
在前几篇中讨论过海量数据的并行加载,基本思路就是针对每一个物理表都会有一个对应的外部表,在做数据迁移的时候,如果表有上百G的时候,一个物理表对应一个外部表性能上会没有任何提升。如果需要做数据插入的时候,对undo是极大的挑战,从某种程度上而言,性能应该要比datapump要差。这个时候可以考虑一个物理表对应多个外部表,比如一个表有100G。可以考虑生成100个external dump 文件,然后加载生成100个外部表,每个dump文件对应一个外部表,这样做数据的插入的时候就相对容易控制了。每一个外部表的数据加载到目标库之后,commit一次,就能及时的释放Undo资源,提高性能。
比如表T生成了两个dump文件(t_1.dmp,t_2.dmp),就可以考虑如下的方式来加载,黄色部分是对应的dump文件。
CREATE TABLE T_EXT_1
( id number,object_id number,object_name varchar2(30),object_type varchar2(30),clob_test clob )
ORGANIZATION EXTERNAL
( TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY "EXPDP_LOCATION"
LOCATION
( 't_1.dmp'
)
);
CREATE TABLE T_EXT_2
( id number,object_id number,object_name varchar2(30),object_type varchar2(30),clob_test clob )
ORGANIZATION EXTERNAL
( TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY "EXPDP_LOCATION"
LOCATION
( 't_2.dmp'
)
);
对应的脚本如下:
其中在DUMP目录下存放着生成的dump文件,根据动态匹配得到最终生成了几个dump文件,来决定创建几个对应的外部表。
target_owner=`echo "$2" |awk -F@ '{print $1}'|awk -F/ '{print $1}'|tr '[a-z]' '[A-Z]'`
source_owner=`echo "$1" |awk -F@ '{print $1}'|awk -F/ '{print $1}'|tr '[a-z]' '[A-Z]'`
tab_name=`echo "$3"|tr '[a-z]' '[A-Z]'`
owner_account=$5
tmp_parallel=`ls -l ../DUMP/${tab_name}_[0-9]*.dmp|wc -l`
echo parallel :$tmp_parallel
for i in {1..$tmp_parallel};
do
echo '${tab_name}_$i.dmp' >> tmp_${tab_name}_par_dmp.lst
done
sed -e '/^$/d' tmp_${tab_name}_par_dmp.lst > ../DUMP_LIST/${tab_name}_par_dmp.lst
rm tmp_${tab_name}_par_dmp.lst
dump_list=`cat ../DUMP_LIST/${tab_name}_par_dmp.lst`
print "
conn $1
set feedback off
set linesize 100
col data_type format a30
set pages 0
set termout off
SELECT
t1.COLUMN_NAME,
t1.DATA_TYPE
|| DECODE (
t1.DATA_TYPE,
'NUMBER', DECODE (
'('
|| NVL (TO_CHAR (t1.DATA_PRECISION), '*')
|| ','
|| NVL (TO_CHAR (t1.DATA_SCALE), '*')
|| ')',
'(*,*)', NULL,
'(*,0)', '(38)',
'('
|| NVL (TO_CHAR (t1.DATA_PRECISION), '*')
|| ','
|| NVL (TO_CHAR (t1.DATA_SCALE), '*')
|| ')'),
'FLOAT', '(' || t1.DATA_PRECISION || ')',
'DATE', NULL,
'TIMESTAMP(6)', NULL,
'(' || t1.DATA_LENGTH || ')') ||','
AS DATA_TYPE
from all_tab_columns t1 where owner=upper('$owner_account') AND table_name=upper('$3' )
order by t1.column_id;
"|sqlplus -s /nolog > ${tab_name}.temp
sed -e '/^$/d' -e '$s/.$//' -e 's/CLOB(4000)/CLOB/g' -e 's/BLOB(4000)/BLOB/g' ${tab_name}.temp > ../DESC_LIST/${tab_name}.desc
rm ${tab_name}.temp
for i in {1..$tmp_parallel}
do
echo loading table ${tab_name} as ${tab_name}_EXT_$i
sqlplus -s $2 <<EOF
set timing on
set echo on
CREATE TABLE ${tab_name}_EXT_$i
(
`cat ../DESC_LIST/${tab_name}.desc `
)
ORGANIZATION EXTERNAL
( TYPE ORACLE_DATAPUMP
DEFAULT DIRECTORY $4
LOCATION(
`sed -n "${i}p" ../DUMP_LIST/${tab_name}_par_dmp.lst`
));
EOF
done
exit
生成的日志类似下面的格式:
loading table T as T_EXT_1
Elapsed: 00:00:01.33
loading table T as T_EXT_2
Elapsed: 00:00:01.30
- eclipse搭建ssh后台
- 解决mysql漏洞 Oracle MySQL Server远程安全漏洞(CVE-2015-0411)
- im4java包处理图片
- centOS7 mini配置linux服务器(五) 安装和配置tomcat和mysql
- RedisPool操作Redis,工具类实例
- centOS7 mini配置linux服务器(四) 配置jdk
- 老司机教你“飙”EventBus3
- Android listView异步下载和convertView复用产生的错位问题
- 实用Android 屏幕适配方案分享
- java-FFmpeg(一) 实现视频的转码和截图功能
- websocket(二) websocket的简单实现,识别用户属性的群聊
- websocket教程(一) 非常有趣的理解websocket
- 前端插件——头像截图上传插件的使用(带后台)
- 如何减轻ajax定时触发对服务器造成的压力和带宽的压力?ajax-长轮训
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 在unittest中使用 logging 模块记录测试数据的方法
- 分享8个Laravel模型时间戳使用技巧小结
- 基于python实现名片管理系统
- 记一个OLED编程中文显示函数的坑(留意变量数据类型的范围)
- tp5框架基于Ajax实现列表无刷新排序功能示例
- 浅谈pycharm下找不到sqlalchemy的问题
- PHP实现常用排序算法的方法
- 利用Python实现原创工具的Logo与Help
- PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
- 浅谈python下tiff图像的读取和保存方法
- Jmeter(二十五) - 从入门到精通 - JMeter函数 - 下篇(详解教程)
- 解决vscode python print 输出窗口中文乱码的问题
- 对python3新增的byte类型详解
- Python实现的特征提取操作示例
- Linux进程间通信方式之socket使用实例