V$ACTIVE_SESSION_HISTORY是定位impdp慢的首选工具,因其高采样率可捕获瞬时等待事件;redo log过小、索引/统计信息自动重建、RAC下未启用CLUSTER参数是三大主因。
impdp慢时,先看V$ACTIVE_SESSION_HISTORY而不是V$SESSION_WAIT
oracle 10g之后的版本中,v$active_session_history(ash)是定位导入瓶颈最直接的手段。你看到的“导入卡在索引创建”或“停在统计信息收集”,往往只是表象;真正拖慢的是后台worker进程在等日志、等锁、等缓存同步。v$session_wait刷新频率低、采样粒度粗,容易漏掉瞬时高占比等待——尤其当impdp启动多个worker(比如partition或parallel=4)时,单个会话的等待可能被平均掉。
正确做法是抓取导入作业运行期间的ASH快照:
- 用
DBA_DATAPUMP_JOBS查出impdp对应的SESSION_ID(注意:不是JOB的OWNER_SESSION,而是实际干活的Worker会话) - 执行:
SELECT event, program, COUNT(*) cnt FROM v$active_session_history WHERE session_id IN (SELECT sid FROM v$session WHERE program LIKE 'DW%') AND sample_time > SYSDATE - 1/24 GROUP BY event, program ORDER BY cnt DESC;
- 重点关注
log file switch (checkpoint incomplete)、gc cr grant 2-way、enq: TX - row lock contention这几类事件
redo log太小会导致impdp速度断崖式下跌
这是11g RAC环境中最常被忽略的硬伤。当impdp以直接路径加载大量数据时,会快速填满当前redo log,触发log file switch;如果redo size只有50MB(默认值),而数据库又运行在NOARCHIVELOG模式下,checkpoint无法及时推进,就会卡在log file switch (checkpoint incomplete)上——此时Worker进程全部挂起,吞吐量从几万条/秒跌到几百条/秒。
验证和修复很简单:
- 查当前redo大小:
SELECT group#, bytes/1024/1024 mb FROM v$log; - 查是否归档模式:
ARCHIVE LOG LIST; - 非归档模式下,至少扩容到
1024M:ALTER DATABASE DROP LOGFILE GROUP 1; ALTER DATABASE ADD LOGFILE GROUP 1 SIZE 1024M; - 注意:RAC所有实例必须统一调整,否则节点间日志切换不同步
索引和统计信息是impdp里最耗时的两个对象类型
导出文件里如果包含函数索引(如UPPER(name))、位图索引或大量列统计信息,11g会在导入阶段自动重建并分析——这个过程不走并行,且ANALYZE TABLE ... COMPUTE STATISTICS在大表上可能跑几十小时。这不是bug,是11g默认行为(12c+已改为DBMS_STATS异步收集)。
跳过它们,导入后再补,效率提升立竿见影:
- 导入时不建索引:
impdp ... EXCLUDE=INDEX - 跳过统计信息:
EXCLUDE=STATISTICS(强烈建议,尤其导出方是10g/11g) - 导入完成后手动建索引:
CREATE INDEX ... NOLOGGING PARALLEL 4; - 再收集统计:
EXEC DBMS_STATS.GATHER_SCHEMA_STATS('SCHEMA_NAME', degree => 8);
别信“导出时加STATISTICS=NONE”——这个参数在11g里对expdp无效,只在12c+生效。
PARALLEL参数在RAC上要配合CLUSTER开关
RAC环境下,impdp PARALLEL=4默认只在本地实例起4个Worker,其他节点空闲。如果不显式启用集群感知,Worker之间无法跨实例协调任务分发,实际并行度还是1,还可能因GC争用加剧等待。
必须加CLUSTER=Y才能让Worker均匀分布到所有节点:
- 正确写法:
impdp ... PARALLEL=8 CLUSTER=Y - 同时确认
init.ora中cluster_database = TRUE且所有实例在线 - 检查Worker分布:
SELECT inst_id, COUNT(*) FROM gv$session WHERE program LIKE 'DW%' GROUP BY inst_id;
没开CLUSTER却设高PARTITION数,只会让单节点CPU和redo压力爆表,其他节点干瞪眼。


















