实验环境
搭建平台:VMware Workstation
OS:RHEL 7.6
Grid&DB:Oracle 12.2.0.1 问题描述在使用数据泵导出和导入(expdp和impdp)突然遇到严重的性能问题,导致导数时间极其漫长,查看日志发现数据泵两个进程DMnn(数据泵主进程)和DWnn(数据泵工作进程)经常等待出现"StreamsAQ: enqueue blocked on low memory"。以下是使用expdp命令导出数据时命令的示例症状(能显示导出时间是因为添加Oracle 12.1及以上版本的参数logtime = all) 正常时间导出空分区表通常需要不到一秒的时间,但是现在突然要2-3秒才能导出每个分区,而且是空分区表。。。
12-Dec-21 10:09:15.573: Processing object type TABLE_EXPORT/TABLE/STATISTICS/MARKER 12-Dec-21 10:09:17.589: . . exported "<SCHEMA_NAME>"."<TABLE_NAME>":"<PART_NAME1>" 0 KB 0 rows 12-Dec-21 10:09:20.661: . . exported "<SCHEMA_NAME>"."<TABLE_NAME>":"<PART_NAME2>" 0 KB 0 rows 12-Dec-21 10:09:22.672: . . exported "<SCHEMA_NAME>"."<TABLE_NAME>":"<PART_NAME3>" 0 KB 0 rows 12-Dec-21 10:09:25.698: . . exported "<SCHEMA_NAME>"."<TABLE_NAME>":"<PART_NAME4>" 0 KB 0 rows 12-Dec-21 10:09:27.721: . . exported "<SCHEMA_NAME>"."<TABLE_NAME>":"<PART_NAME5>" 0 KB 0 rows 12-Dec-21 10:09:30.733: . . exported "<SCHEMA_NAME>"."<TABLE_NAME>":"<PART_NAME6>" 0 KB 0 rows 12-Dec-21 10:09:32.758: . . exported "<SCHEMA_NAME>"."<TABLE_NAME>":"<PART_NAME7>" 0 KB 0 rows
解决办法这是由于当数据库内存使用了ASMM或者AMM的管理方式时,如果此时的buffer cache负载较高并且streams pool中的内存正被转移到buffer cache时,可能会发生此问题。可以使用以下SQL来检查以下查询是否一直返回“1”:
SQL> select shrink_phase_knlasg from X$KNLASG; SHRINK_PHASE_KNLASG ------------------- 1
注:该字段表示 streams pool 处于收缩阶段。当 streams pool 完成收缩时,该值应返回“0”,但如果它一直返回“1”,这个问题就可能发生。 所以,我们知道现象背后的原理就有思路了:如果SHRINK_PHASE_KNLASG列在几分钟之内的值仍然是“1”的时候,则从sqlplus运行以下命令强制streams pool缩小完成:
connect / as sysdba alter system set events 'immediate trace name mman_create_def_request level 6';
但是! 即使 streams pool 已经结束收缩,该标志也可能没有被修改!所以"StreamsAQ: enqueue blocked on low memory"这个问题会一直存在。这是一个官方bug,需要通过补丁27634991修复(Oracle 19c已经默认修复了该bug)。
