一、 环境信息:
Oracle 11.1.0.7.0 - 64bit,单机,AIX 6.1
二、 EXPDP性能诊断
1、 expdp脚本如下:
cat exp_SCOTT_20180511.par
userid="/ as sysdba" directory=temp_dump dumpfile=exp_SCOTT_20180511_%u.dmp logfile=exp_SCOTT_20180511.log cluster=n parallel=8 compression=all schemas=SCOTT exclude=statistics
2、导出整个schema的时间大约为13个小时,数据量133GB:
sed -n -e '2p' -e '/method:/p' -e '$p' exp_SCOTT_2018051.log Export: Release 11.1.0.7.0 - 64bit Production on Friday, 11 May, 2018 15:16:44 Total estimation using BLOCKS method: 133.3 GB Job "SYS"."SYS_EXPORT_SCHEMA_01" successfully completed at 04:13:05
3、 expdp 导出过程10046 Trace追踪诊断:
因该库需要使用expdp按schema导出导入方式进行整库迁移,按照一个schema导出需要13个小时的速度是接受不了的,虽然该机器配置不是非常的好。接下来导出另外一个schema,并启用10046 trace追踪:
--查询正在执行的expdp相关会话信息: set lines 150 pages 100 numwidth 7 col program for a38 col username for a10 col spid for a7 select to_char(sysdate,'YYYY-MM-DD HH24:MI:SS') "DATE", s.program, s.sid, s.status, s.username, d.job_name, p.spid, s.serial#, p.pid from v$session s, v$process p, dba_datapump_sessions d where p.addr=s.paddr and s.saddr=d.saddr; DATE PROGRAM SID STATUS USERNAME JOB_NAME SPID SERIAL# PID ------------------- -------------------------- ------- -------- ---------- --------------------- ------- ------- ------- 2018-05-14 14:46:10 ) 2814 ACTIVE SYS SYS_EXPORT_SCHEMA_01 488648 6557 467 2018-05-14 14:46:10 ) 3243 ACTIVE SYS SYS_EXPORT_SCHEMA_01 124224 19566 466 2018-05-14 14:46:10 V1-V3) 2801 ACTIVE SYS SYS_EXPORT_SCHEMA_01 340810 61833 464
--查询对应会话是否有其它会话阻塞: select sid,serial#,event,blocking_session,seconds_in_wait,state,last_call_et from v$session where serial# in (6557,19566,61833); SID SERIAL# EVENT BLOCKING_SESSION SECONDS_IN_WAIT STATE LAST_CALL_ET ------- ------- -------------------------------------- ---------------- --------------- ------------------- ------------ 2801 61833 wait for unread message on broadcast channel 1 WAITING 46636 2814 6557 db file sequential read 0 WAITED SHORT TIME 46636 3243 19566 wait for unread message on broadcast channel 0 WAITING 46638
--对相关进程进行10046 trace追踪: oradebug setospid 124224 oradebug unlimit oradebug event 10046 trace name context forever, level 12; oradebug tracefile_name --oradebug event 10046 trace name context off; oradebug setospid 488648 oradebug unlimit oradebug event 10046 trace name context forever, level 12; oradebug tracefile_name --oradebug event 10046 trace name context off; --已上trace时间长一点,会抓取较大的信息
同时查看相关trace文件的的信息:
grep "nam=' WAIT #13: nam='db file sequential read'" TEST_dw01_488648.trc|awk '{print $12}'|sort -u obj#=-1 obj#=0 obj#=14 ... obj#=579 obj#=596 obj#=9
发现这些在等待的这些对象基本都是SYS用户下:
select obj#,owner#,name,namespace from obj$ where obj# in (-1,0,14,3,36,559,563,566,567,575,578,579,596,9); OBJ# OWNER# NAME NAMESPACE ---------- ---------- ------------------------------ ---------- 3 0 I_OBJ# 4 9 0 I_FILE#_BLOCK# 4 14 0 SEG$ 1 36 0 I_OBJ1 4 559 0 PARTOBJ$ 1 563 0 TABPART$ 1 566 0 I_TABPART_BOPART$ 4 567 0 I_TABPART_OBJ$ 4 575 0 TABSUBPART$ 1 578 0 I_TABSUBPART_POBJSUBPART$ 4 579 0 I_TABSUBPART$_OBJ$ 4 596 0 LOBFRAG$ 1
同时查看expdp导出日志,是在估算大小:
Total estimation using BLOCKS method:xxx.xx GB
初步诊断为,expdp在导出时,要估算导出大小,需要查询sys用户下的基表,很有可能是这些查询的SQL出现了性能问题。
--抽查SEG$表的统计信息: OWNER PARTNAME NROWS BLOCKS AVGSPC CCNT ROWLEN SSIZE ANADATE ---------- ---------- -------- ---------- ------ ---- ------ -------- ------------------- SYS 4531 132 0 0 66 4531 2013-07-19 01:10:49
发现该表统计信息很久没有更新,接连查询其它表的统计信息,发现都是很久没有更新统计信息。于是做了如下操作,先将相关表的统计信息更新到最新:
--收集整个sys用户的统计信息: exec dbms_stats.gather_schema_stats(ownname => 'SYS',degree=>8); --收集数据字典的统计信息: exec dbms_stats.gather_dictionary_stats(options =>'gather auto',degree=>16); --收集fixed表统计信息: exec dbms_stats.gather_fixed_objects_stats;
然后中断已经在导出的进程,等统计信息收集完成后,再执行导出,测试导出速度是否有提升。发现导出速度并没有明显提升,看来真正的问题并没有找到,再次进行trace追踪。
tkprof TEST_dm00_124224.trc tkprof_TEST_dm00_124224.out waits=y sort=exeela tkprof TEST_dw01_488648.trc tkprof_TEST_dw01_488648.out waits=y sort=exeela
然后发现如下SQL异常:
SQL ID: aujcr6t1u8u62 Plan Hash: 3731411368 SELECT LVL FROM SYS.KU$_REF_PAR_LEVEL_VIEW WHERE OBJ# = :B1 call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 0 0.00 0.00 0 0 0 0 Execute 160363 1.87 32.76 0 0 0 0 Fetch 160362 13047.39 13496.19 0 1008676980 0 0 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 320725 13049.26 13528.96 0 1008676980 0 0 Misses in library cache during parse: 0 Elapsed times include waiting on following events: Event waited on Times Max. Wait Total Waited ---------------------------------------- Waited ---------- ------------ db file sequential read 169141 0.60 453.81 db file scattered read 3 0.01 0.02 OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS call count cpu elapsed disk query current rows ------- ------ -------- ---------- ---------- ---------- ---------- ---------- Parse 167759 4.95 5.86 0 0 0 0 Execute 648851 123.59 151.44 0 0 0 0 Fetch 648850 13057.99 13507.29 0 1010718198 0 488487 ------- ------ -------- ---------- ---------- ---------- ---------- ---------- total 1465460 13186.53 13664.61 0 1010718198 0 488487
查询该SQL历史执行的情况:
set lines 180 pages 9999 col execs for 999,999,999 col avg_etime for 999,999.999 col avg_lio for 999,999,999.9 col begin_interval_time for a30 col node for 99999 break on plan_hash_value on startup_time skip 1 select ss.snap_id, ss.instance_number node, begin_interval_time, sql_id, plan_hash_value, nvl(executions_delta, 0) execs, (elapsed_time_delta / decode(nvl(executions_delta, 0), 0, 1, executions_delta)) / 1000000 avg_etime, (buffer_gets_delta / decode(nvl(buffer_gets_delta, 0), 0, 1, executions_delta)) avg_lio, (disk_reads_delta / decode(nvl(buffer_gets_delta, 0), 0, 1, executions_delta)) avg_pio from DBA_HIST_SQLSTAT S, DBA_HIST_SNAPSHOT SS where sql_id = to_char('aujcr6t1u8u62') and ss.snap_id = S.snap_id and ss.instance_number = S.instance_number and executions_delta > 0 order by 1, 2, 3; --可以看到,该SQL单次执行时间为0.081秒,30分钟内只能执行20万次左右 SNAP_ID NODE BEGIN_INTERVAL_TIME SQL_ID PLAN_HASH_VALUE EXECS AVG_ETIME AVG_LIO AVG_PIO -------- ----- --------------------- ------------- --------------- ------------ ------------ -------------- ---------- 54453 1 11-MAY-18 03.00.27.869 PM aujcr6t1u8u62 3731411368 7,607 .081 6,289.2 .816221901 54454 1 11-MAY-18 03.30.30.087 PM aujcr6t1u8u62 20,606 .081 6,290.0 0 54455 1 11-MAY-18 04.00.32.259 PM aujcr6t1u8u62 20,736 .081 6,290.0 0
因为是expdp导出执行的sql,对于这样的sql有一个好处,就是可以对比相同版本的其它库的历史执行计划。
造成相同执行计划在不同库性能差异的这种情况的原因有很多,比如优化器的相关参数设置不同、机器配置不同,库本身的性能较好或库本身很空闲等。这里不对这些原因进行分析,先分析一下该SQL,看看该SQL的执行计划是否合理:
--获取该sql的绑定变量: SQL> set linesize 200 pagesize 200 SQL> col name for a30 SQL> col datatype_string for a20 SQL> col value_string for a20 SQL> select sql_id, name, datatype_string, last_captured, value_string from v$sql_bind_capture2 where sql_id = 'aujcr6t1u8u62' order by last_captured, position; SQL_ID NAME DATATYPE_STRING LAST_CAPTURED VALUE_STRING ------------- ------------------------------ -------------------- ------------------- -------------------- aujcr6t1u8u62 :B1 NUMBER 2018-05-15 16:49:30 801250 aujcr6t1u8u62 :B1 NUMBER 2018-05-16 10:39:08 885287 --获取真实的执行计划: set pages 9999 line 333 var B1 number; exec :B1 := 885287; SELECT LVL FROM SYS.KU$_REF_PAR_LEVEL_VIEW WHERE OBJ# = :B1; select * from table(dbms_xplan.display_cursor(null,0));
然后与该trace追踪到的执行计划进行对比:
发现该SQL使用的优化器模式是Rule Based Optimizer(简称RBO),是基于数据字典的优化,它根据数据字典查询有无可用的索引,如果有则使用,否则不使用,不同的访问方法有预定好的优先级,选择优先级高的执行方法。但在这里不知道它为什么没有选择走CDEF$的I_CDEF3索引,而是走了全表扫描。这也可以解释为什么收集完sys用户统计信息之后,执行计划不变的原因了。那问题来了,是使用CBO做索引扫描的执行效率高,还是现在RBO模式的效率高呢?经测试,使用Cost Based Optimizer(简称CBO)的效率高,也就是通过变量信息产生的真正执行计划。
SQL> SELECT /*+ rule */ LVL FROM SYS.KU$_REF_PAR_LEVEL_VIEW WHERE OBJ# = :B1; no rows selected Elapsed: 00:00:00.10 SQL> SELECT LVL FROM SYS.KU$_REF_PAR_LEVEL_VIEW WHERE OBJ# = :B1; no rows selected Elapsed: 00:00:00.00
既然问题已经找到,接下来就好办了,使用coe_xfr_sql_profile.sql直接绑定较优的执行计划。
绑定后的执行计划效果如下:
绑定之后的提升效果还是很明显的,单次平均执行时间已经下降到0.002秒,平均逻辑读也成倍的下降。这里为什么说很明显呢?可能看起来0.081秒的执行效率已经很高了,但是这个sql的是需要很次执行的,在expdp导出schema的过程中,需要查询整个schema的所有对象。
优化后的导出效果,1个多小时就完成了导出:
sed -n -e '2p' -e '$p' exp_SCOTT_20180515.log Export: Release 11.1.0.7.0 - 64bit Production on Tuesday, 15 May, 2018 16:51:22 Job "SYS"."SYS_EXPORT_SCHEMA_01" successfully completed at 18:16:51
三、 总结
1、 对于expdp/impdp的性能影响因素很多,比如库整体性能,机器配置情况,存储I/O资源等。
2、 有关expdp/impdp性能诊断请参考:
SRDC - 数据泵导入(IMPDP)性能问题的诊断收集 (Document 2365615.1)
SRDC - 数据泵导出性能问题的诊断收集 (Document 2365568.1)
针对数据泵导出 (expdp) 和导入 (impdp)工具性能降低问题的检查表 (Document 1549185.1)