大分区表的手工并行优化

这段时间饱受大分区表的性能之苦,碰到最大的一个分区表有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 条评论
登录 后参与评论

相关文章

来自专栏肖力涛的专栏

Spark踩坑记:初试

Apache Spark是一个围绕速度、易用性和复杂分析构建的大数据处理框架。本系列文将通过初试、Hbase+Mysql 、Spark Streaming+ka...

1.1K2
来自专栏皮振伟的专栏

[linux][memory]进程的最大内存使用量的讨论

前言: 一个进程最大能使用多少虚拟内存,能控制的地方还是比想象的多一点。 尤其是IaaS上,一个qemu进程能使用多少虚拟内存,就是对应着虚拟机的物理内存的最大...

66211
来自专栏腾讯大数据的专栏

Hadoop Raid-实战经验总结

分布式文件系统用于解决海量数据存储的问题,腾讯大数据采用HDFS(Hadoop分布式文件系统)作为数据存储的基础设施,并在其上构建如Hive、HBase、Spa...

18610
来自专栏腾讯数据库技术

一个ext4的Bug分析过程

3992
来自专栏hbbliyong

由一道面试题来了解进程间的通信

周末面试碰到一个面试题,题目是: 在MMO游戏中,服务器采用Linux操作系统,网络通信与游戏逻辑处理进程一般是分离的。 例如:GameSvr进程处理游戏逻辑,...

6347
来自专栏JMCui

Linux 常用性能工具简介.

一、wget 文件下载 使用wget下载单个文件:wget URL 下载并以不同的文件名保存:wget -O wordpress.zip URL wget限速下...

5035
来自专栏北京马哥教育

MySQL 数据库上线后根据 status 状态优化

马哥linux运维 | 最专业的linux培训机构 ---- 网上有很多的文章教怎么配置mysql服务器,但考虑到服务器硬件配置的不同,具体应用的差别,那些文...

2766
来自专栏Java技术分享

浅谈spring的事务管理作用

事务就是对一系列的数据库操作进行统一的提交或回滚操作,比如说做一个转账功能,要更改帐户两边的数据,这时候就必须要用事务才能算是严谨的做法。要么成功,要么失败,保...

1996
来自专栏开源项目

Git 项目推荐 | 基于go+protobuff 实现的分布式

eQ ? 基于go+protobuff实现的多种持久化方案的mq框架 Client For KiteQ Go: https://github.com/b...

42114
来自专栏大数据和云计算技术

常见Linux调优命令和工具

引言: 应同学的要求,分享些基础的知识。 没有比Linux更基础了,关键问题来了,你真的认真看了和转发了吗? O(∩_∩)O哈哈~ 要实现对Linux的调优,就...

4848

扫码关注云+社区