问题现象
使用 orato8a 工具进行抽取时发现,当使用 parallel 参数全表并行导出时,orato8a 工
具输出的导出时间要比实际运行时间小很多。
具体来看,orato8a 运行后前几分钟是没有数据写入的,通过 pstack 查看发现一直在
执行 do_prepare_data_info 这个函数。
# time ./orato8a --user='hx_user/cx123@150.12.201.28/gdltcxff' --
table_name='FP_YJJCYQK_MX' --owner='HX_FP'
--file=/opt/export/idf/data/all/FFK/HXZG/GDDS/FP_YJJCYQK_MX_TEST13.txt
--field='_#c#_' --format=3 --line_separator='_#r#_' --parallel=8
export columns: 23
export rows: 29126180
export time: 6 min 6 sec
process ok!
real 12m16.100s
user 6m50.656s
sys 0m25.602s
通过每隔一分钟的 pstack 信息可以看到,前几分钟 orato8a 进程一直在进行
do_prepare_data_info,而后才开始 run_do_save 抽取数据并计时,所以 orato8a 抽取
结束后显示的 export time 要比实际时间小。
原因分析
orato8a 运行后前几分钟执行 do_prepare_data_info 的时候,是在连接 oracle 获取系
统表数据。由于 oracle 返回慢,导致程序卡住了 6 分钟无响应。
现场将查询 oracle 系统表的 sql 在客户 oracle 库上执行,耗时 6 分钟以上。咨询了
oracle 运维人员,了解到库中数据量超过 10T,我们所查询的系统表数据量很大,
这个查询速度是正常的。
查询系统表 sql 如下:
select dbms_rowid.rowid_create(1,
o.DATA_OBJECT_ID,
relative_fno,
e.BLOCK_ID,
0),
dbms_rowid.rowid_create(1,
o.data_object_id,
e.relative_fno,
e.BLOCK_ID + e.BLOCKS - 1,
10000)
from dba_extents e, dba_objects o
where e.owner = upper('ora001')
and e.owner = o.OWNER
and e.segment_name = upper('tt1')
and o.object_name = upper('tt1');
select dbms_rowid.rowid_create(1,
o.DATA_OBJECT_ID,
relative_fno,
e.BLOCK_ID,
0),
dbms_rowid.rowid_create(1,
o.data_object_id,
e.relative_fno,
e.BLOCK_ID + e.BLOCKS - 1,
10000)
from dba_extents e, dba_objects o
where e.owner = upper('ora001')
and e.owner = o.OWNER
and e.segment_name = upper('tt1')
and e.partition_name = upper('')
and o.object_name = upper('tt1')
and o.SUBOBJECT_NAME = upper('');