大分区表的手工并行优化

这段时间饱受大分区表的性能之苦,碰到最大的一个分区表有1个t左右,操作起来每个细节都需要格外小心,我这次和大家分享的案例应用的分区表不是很大,有80G左右。但是这个分区主要分区比较多,有将近2000个左右的分区。 举一个案例来说明一下。 现在要做以下下几件事,要保证要宕机时间尽可能短。 为了方便起见,我暂定现在有4个DB instance,叫par01,par02,par03,par04. 1.需要对par01的数据运行Update语句,根据条件更新(update操作可能会移动分区), 2.然后把par01的数据导出来 3.重新对par01,par02,par03,par04进行分区 4.选择性的把数据导入到par01,par02,par03,par04 所以看以上步骤最终目的就是把par01的数据更新以后重新分布到par01,par02,par03,par04上去。 除了以上的4个步骤,我还设想了以下的实现方式,但是实际操作的时候,发现不好控制,而且可能在网络带宽和磁盘空间上都有一定的要求。 1)采用db link,在par01上建立par02,03,04的db link,然后对Par01,02,03,04分区后,数据的复制直接使用db link来做。-->这个部分对网络带宽有很高的要求,而且比较纠结的一点事不好控制进度。如果有任何异常,只能重新开始。 2)采用临时表,建立4个临时表,设置为Nologging,然后使用insert/*+append */的方式根据需要插入数据。然后导出,然后重新导入到02,03,04上。->-会占有大量的磁盘空间,相当于复制了一份数据的镜像。比如库有200G,就得额外需要200G的数据空间。需要耗费更长的时间。 首先是第一个部分。 1.需要把par01的数据运行Update若干语句(update操作可能会移动分区), 这种update操作对于oracle来说是敏感的。需要enable row movement才可以。 因为备份已经充足,所以特意对表设置了nologging. 然后按照开发提供的脚本运行update,(有奖金8个sql语句)结果update整整跑了快6个小时。幸亏是测试环境预演,能够提前发现很多的问题。 可以接受的时间范围是30分钟左右。所以只能想办法最大限度的压缩时间。 首先能想到的是parallel,但是通过测试 parallel dml也有诸多限制,而且效果也不明显。 最后采用的方法是:par01有上千个partition,可以把每个partition看成独立的一张表,然后对每个Partition来执行相应的Update,然后在此基础上根据High_value进行划分,来决定采用多少个个窗口并行的去跑Update。 sql语句大体如下 update test partition(parxxxxx) set xxxx where xxxxx; 最后根据数据情况和High value我开了5个窗口并行的跑update,效果很明显。最后跑了将近半个小时,中间根据一定的频率来commit,性能确实提高了不少。 2.然后把par01的数据导出来, 大家对于数据导入导出,首先都是expdp/impdp,但是在这个场景里,不太妥当,而且有一定的风险,最后决定使用exp/imp 原因如下: 1.我们所用的库是从10.2.0.5.0手工升级到11.2.0.2.0的。对于expdp/impdp有一些已知11g的bug提到会导致数据泵hang住。 2.par01,par02,par03,par04的网络环境很好,如果使用expdp/impdp需要配置相应的directory和用户权限,而且需要把dump文件拷贝到各个服务端目录下,需要耗费大量的时间,而且拷贝80多G的dump文件也需要准备足够的空间。如果直接在par01上进行导入,不需要配置,就方便度多了。 3.导出需要生成几个独立的dump文件。采用的方法如下。

exp xxxx file=par01_xxxxxx.dmp log=par01_xxxxx.log statistics=none grants=n constraints=n indexes=n tables=xxxx query=\"where code in \(xxx,xxx,xxx\)\" buffer=9102000

expdp在这种情况下没有明显的优势,首先query选项启用,direct就没作用了,开了并行,等了好一会,貌似Hang住了, 最后采用的方法是:采用导出分区的方式,根据数据量和业务情况,把导出工作分成5个单独的进程来跑,每个进程会导出指定的分区 比如 thread1:分区par_001~par_005 thread2:分区par_100~par_105 查看系统的负载,导出时cpu都是满载的,效果应该和expdp的并行效果差不多,但是控制要灵活。 最后统计结果,本来需要100分钟以上的任务,最后用了将近30分钟就全部导完了。

3.重新对par01,par02,par03,par04进行分区 需要对Par01,02,03,04的分区进行重新的组织。比如原来表只有100个可能根据需要得分成200个分区了,而且分区名称也有要求。 这个地方可能有两种实现, 一种是把分区都drop掉,只留一个max pattition,然后split partition 另一种方法是把分区不断的进行merge,最后合并成一个max parition. 我最终选用的是第一种方法,因为比较直观简单,重新分区的时候步骤很有规律,我生成了动态sql来删除分区,只保留默认的max partition. 这个部分多说一句,有的朋友可能建议不删数据了,直接根据需要split partition,生成指定的分区,我尝试了这种方法,速度太慢。可能有大量的数据会从各个partition间不断的move> 4.选择性的把数据导入到par01,par02,par03,par04 这个部分基于步骤2,独立的导入,时间也好控制。 比如说par02这个分区比较大,我导出的时候就生成了两个dump文件,然后导入的时候,就可以在par02上分两个独立的导入进程操作。 以上是自己的一些总结。也对比了一些其他优化的案例。有些不足,还希望大家多多指教。

原文发布于微信公众号 - 杨建荣的学习笔记(jianrong-notes)

原文发表时间:2014-03-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏数据和云

深入解析:由expdp遇到ORA-7445问题的深入展开

李真旭(Roger) ACOUG 核心专家,Oracle ACE,云和恩墨技术专家 编辑手记:由一个问题入手,深入其根本原因,层层递进,细致分析,由点及面,这...

2766
来自专栏儿童编程

Scratch中“面向对象”思想的体现——儿童积木编程与代码编程的联系

Scratch是MIT面向少年儿童设计的一款搭积木式的编程软件。对零基础的少年儿童(尤其针对8-16岁)及零基础的成年人普及编程、编程入门具有重大意义。对于教育...

603
来自专栏杂烩

程序eclipse下run和debug不一致问题

    公司核心代码,这里不上了,主要将如何发现问题、如何排查问题和如何解决问题。

462

Cloudify中的部署组合

[这篇文章是由DeWayne Filppi撰写的。]

23310
来自专栏非著名程序员

Android将应用程序的崩溃信息如何保存到本地文件,并上传至服务器

导语:最近实在是太忙了,没有怎么更新公众号,也没有怎么认真去写一些内容,在这里先给关注我的朋友说一声抱歉,可能在接下来的一段时间,还是很忙,但是我会争取抽空多分...

1819
来自专栏程序员互动联盟

【专业技术】Linux设备驱动第八篇:高级字符驱动操作之设备存取控制

上一篇中介绍了阻塞IO等的一些用法,本来这一篇准备介绍一下poll/select等的一些高级IO操作,后来想想,在实际工作中开发驱动的时候很少会使用到poll/...

33713
来自专栏Java学习网

Java中文乱码问题分析与标本兼治的方法

你是否遇到过这种情景,代码都写OK了,测试也没问题,但一运行发现显示的是乱码,这下坏了,明天还要给客户做演示汇报,现在已经到晚上22点了,别无选择,只能连夜查找...

2098
来自专栏情情说

《深入实践Spring Boot》阅读笔记之一:基础应用开发

上上篇「1718总结与计划」中提到,18年要对部分项目拆分,进行服务化,并对代码进行重构。公司技术委员会也推荐使用spring boot,之前在各个技术网站中也...

3389
来自专栏腾讯移动品质中心TMQ的专栏

Android内存泄露测试不再蓝瘦,香菇

在进行Android内存泄露分析时,面对成千上万个对象,你是否蓝瘦,香菇?作为测试人员你在进行内存泄露测试之后,是否有勇气告诉开发同事程序已经没有内存泄露,可以...

2217
来自专栏Crossin的编程教室

【Python 第33课】 处理文件中的数据

我们已经知道了如何读取和写入文件。有了这两个操作文件的方法,再加上对文件内容的处理,就能写一些小程序,解决不少日常的数据处理工作。 比如我现在拿到一份文档,里面...

3168

扫描关注云+社区