当前位置:首页 > 问答 > 正文

ORA-31629报错内存分配不够,远程帮忙修复问题的经验分享

(来源:Oracle官方支持文档)ORA-31629这个错误,说白了就是Oracle数据库在用数据泵(Data Pump)工具做导入导出时,服务器觉得“内存不够用了”,它就像你往一个已经塞满的行李箱里硬塞衣服,箱子会“嘭”地一声弹开一样,数据库也会报这个错告诉你“撑不住了”,我处理过不少这类问题,尤其是在给客户做远程支持的时候,发现大家遇到的场景虽然五花八门,但核心思路都差不多,下面我就把我远程帮人解决这个问题的经验,像聊天一样分享出来。

(来源:多次远程支持案例总结)最重要的一步不是马上动手改参数,而是先“问诊”,隔着屏幕,我第一句话通常是:“朋友,你这次是导数据还是导数据?大概有多大?服务器内存总共多少?”这几个问题非常关键,因为如果是导一个几十G的大库,而服务器内存只有8G,那几乎肯定会碰到这个问题,知道了问题的规模,我们才能量体裁衣。

ORA-31629报错内存分配不够,远程帮忙修复问题的经验分享

(来源:Oracle Data Pump原理说明)我得简单解释一下为什么会出现这个错误,不然客户会觉得很懵,数据泵干活的时候,并不是把整个数据文件一次性全读进内存,那样谁也受不了,它会创建一些并行的 worker 进程来分工合作,每个进程都需要一块自己的“工作区”来缓存要处理的数据块,这个“工作区”的大小,主要受一个叫 STREAMS_POOL_SIZE 的参数控制,你可以把它想象成一个共享的“工作台”,如果同时干活的人(并行进程)太多,或者每个人要搬的“砖”(数据块)太大,这个“工作台”就显得太小了,大家挤来挤去,工具都没地方放,活自然就干不下去了,于是ORA-31629就冒出来了。

(来源:常见解决方案手册)远程修复的第一步,也是最直接的一步,就是去调整这个“工作台”的大小,也就是 STREAMS_POOL_SIZE 参数,我会通过远程桌面连接上客户的服务器,用管理员账号登录数据库,然后执行类似这样的命令:

ORA-31629报错内存分配不够,远程帮忙修复问题的经验分享

ALTER SYSTEM SET STREAMS_POOL_SIZE=1G SCOPE=MEMORY;

这里我把内存池设置成了1G,这个值设多少合适呢?这又回到最开始“问诊”的结果了,如果数据量不大,可能512M就够了;如果是个巨无霸,可能得设到2G甚至更高,但前提是不能超过服务器空闲物理内存的极限,不然操作系统自己都会卡死,我一般会建议客户先设一个保守的值试试水。

(来源:实战经验积累)光调大“工作台”有时候还不够,第二个常见的招数是减少同时“干活的人”,也就是降低并行度,数据泵导出导入时可以用 PARALLEL 参数指定用几个进程并行操作,有时候客户为了追求速度,把这个值设得很高,比如16甚至32,这会给内存带来巨大压力,我会让他们在命令里加上 PARALLEL=4 或者更低的数字试试,这就好比把16个人同时挤进一个小厨房改成4个人有条不紊地工作,虽然可能慢点,但至少不会把厨房弄炸了,速度和安全,总要有个平衡。

ORA-31629报错内存分配不够,远程帮忙修复问题的经验分享

(来源:针对大表处理的技巧)第三点,如果客户要处理的数据里有一两张特别巨大的表,我会建议他们换个思路:别硬来,可以采用“分而治之”的办法,在导出时使用 INCLUDE 参数把这张大表排除在本次任务之外,然后为这张大表单独创建一个导出任务,这样,主任务的内存压力会小很多,成功率高,虽然操作上多了一步,但总比反复失败强。

(来源:系统层面优化建议)第四,有时候问题不出在数据库参数上,而是出在操作系统层面,我会远程检查一下服务器实时的内存使用情况,用 free -g 这样的命令看看是不是整个系统的内存都所剩无几了,如果真是这样,那可能就需要和客户沟通,是不是能临时关掉一些非核心的应用,给数据库腾出点地方,或者最根本的,考虑给服务器加内存了,这叫“巧妇难为无米之炊”。

(来源:预防性措施分享)问题解决后,我一般会多唠叨几句,分享一些预防的经验,在做任何大型操作之前,最好先在一个测试环境上模拟一遍,预估一下内存消耗,还有,定期检查数据库的内存相关参数设置是否合理,不要一个配置用到底,养成监控系统资源使用率的习惯,别等到内存爆了才手忙脚乱。

解决ORA-31629就像给人看病,要先号准脉(分析规模和原因),再对症下药(调整参数或策略),最后还得嘱咐几句“以后要注意养生”(预防措施),通过远程的方式,虽然不能亲手操作,但通过清晰的沟通和一步步的指导,绝大多数问题都是可以顺利解决的。