我们某一个系统的夜维出现了性能的问题,删除N张表,数据量从几万到几百万不等,现在需要3.5-4个小时,看了一下SQL AWR,有些采用了TABLE ACCESS FULL,而且是数据量百万级的表,并且一次删除5000条,批量要删除几百次,相当于执行几百次TABLE ACCESS FULL,效率可想而知。
大家讨论后,决定除了索引、SQL语句,从夜维程序逻辑上也要优化,提出了一些方案,目前正处于测试中。不过今儿先不说这事儿,这有个问题,就是测试库数据是模拟出来的,无论从字段含义,还是数据量,均不能和生产相比,因此为了验证,夜维程序优化的作用,需要将生产数据导入测试环境。
这个过程中,碰见了一些琐碎的问题,有些可能是常见的问题,记录于此,
1. 首先需要了解生产库数据。
生产库用户下数据存放于数据表空间TABLE_DAT中,目前使用量为25G左右,索引数据存放于索引表空间TABLE_IDX,目前使用量为10G左右。
2. 导出生产库数据。
使用expdp system/oracle schema=xxx directory=xxx dumpfile=xxx logfile=xxx,导出生产库xxx这个schema所有对象信息,dump文件17G(因为expdp数据泵会有压缩,因此不是25+10=35G),用时十几分钟。
3. 准备测试数据库。
为了满足生产库数据的需求,测试环境就至少需要35G的空间存放数据。找遍了手头上的资源,才找到一台异地机房的服务器,可用空间为50G左右,安装了Oracle 11.2.0.4,剩余42G左右。接着为了便于数据导入,创建了和生产环境一致的用户、数据表空间名称(26G),以及索引表空间名称(11G)。
问题来了,需要倒入的文件dump有17G,本地空间只有42-26-11=5G左右,不足以存放dump文件。
4. 寻找中间服务器。
最直接的方法,就是找一台中间服务器,作为中转,满足空间容量,执行导出导入。但找的服务器,发现和这台开发服务器,网络策略不通,因为我们生产库和测试库,属于两地机房,之间互访需要开通策略,现申请网络策略,需要一些时间,所以这一条路行不通。
5. 山穷水尽疑无路。
目前的问题,测试库服务器,磁盘空间只有5G,但一个文件dump就需要17G,而且这台服务器,由于一些原因,不能加新的磁盘容量。那么如何增加存储空间?
6. 柳暗花明又一村。
前两天为了学习RAC,特意看了下NFS,因为我这台服务器,属于同网段的还有几台,虽然容量相近(不能满足数据库+数据文件+dump的空间需求),但足以存放17G文件,我来搭一个NFS,dump文件放其中,让这台数据库服务器,可以访问这个dump,是不是就可以了?
编辑用于提供存储的服务器exports,
[root@RAC1 DATA]# vi /etc/exports
/shared_disk 10.x.x.x(sync,rw)
启动NFS服务,
[root@RAC1 DATA]# service nfs start
Starting NFS services: [ OK ]
Starting NFS quotas: [ OK ]
Starting NFS mountd: [ OK ]
Starting NFS daemon: [ OK ]
Starting RPC idmapd: [ OK ]
查看信息,
[root@RAC1 DATA]# showmount -e 10.221.x.x
Export list for 10.221.x.x
/shared_disk 10.x.x.x
这台测试数据库服务器,执行挂载,
[root@RAC2 /]# mount -t nfs 10.x.x.x:/shared_disk /u01
此时执行df -h就可以看出,有一个10.x.x.x:/shared_disk /u0挂载点了。
7. 执行导入操作。
首先测试服务器,创建用于导入的目录结构,
create directory dump_dir as '/home/oracle';
grant read,write on directory
执行impdp,
impdp xxx/xxx directory=dump_dir dumpfile=xxx logfile=xxx
8. 异常操作。
由于临时忘了是不是用户名正确,我执行了ctrl+c强行终止了impdp进程,当我再次执行impdp的时候则提示我表已经存在,需要使用TABLE_EXISTS_ACTION参数,检索数据库确实有了数据,且数据量正确。
奇怪,我刚才是终止了这一次impdp操作,怎么会有数据了?
9. 那人却在灯火阑珊处。
Oracle 11g下的impdp/expdp数据泵的执行,操作系统层面是执行了impdp/expdp,启了一进程,但实际后台是启动了一个job,因此只kill这个操作系统的进程,并未从数据库层kill这个job,所以job继续执行。
正在运行的job,可以从这张视图了解,
正在执行的impdp进程窗口,ctrl+c就可以进入impdp的交互界面,如下是一些参数,例如kill_job就可以删除此任务,
如果已经关闭了执行窗口,可以从上面是图中检索job名称,执行impdp命令加上attach=job_name,就可以进入这个job的命令行,继续操作了。
总结:
1. 为了解决空间不足的问题,采用NFS临时借用其他节点存储,算是一种方案。
2. 11g下的数据泵impdp/expdp,后台采用job执行,只是kill进程无法停止job,可以使用impdp/expdp命令行操作和管理job任务。
如果您觉得此篇文章对您有帮助,欢迎关注微信公众号:bisal的个人杂货铺,您的支持是对我最大的鼓励!共同学习,共同进步:)