今天在客户处进行培训时,客户抱怨到,sqlldr的速度太慢,说是从昨天晚上加载数据到今天上午,都没有结束。加载的文本文件大小为10M,大概包含10万条记录。按照我的理解,sqlldr几乎不可能花这么长的时间的。
于是,让客户查询v$session_wait,发现执行sqlldr加载的session(session id为33)正在等待library cache lock的等待事件。很明显,sqlldr一直在等待,而不是在进行实际的加载工作。
既然是等待library cache lock,说明有其他的进程锁定了要加载的表,导致sqlldr
无法获得该表上的lock。这属于shared pool里的一种争用。
然后,我让客户发出下面的SQL:
select /*+ ordered */
w1.sid waiting_session,
h1.sid holding_session,
w.kgllktype lock_or_pin,
w.kgllkhdl address,
decode(h.kgllkmod,0,'None',1,'Null',2,'Share',3,'Exclusive','Unknown') mode_held,
decode(w.kgllkreq,0,'None',1,'Null',2,'Share',3,'Exclusive','Unknown') mode_requested
from dba_kgllock w, dba_kgllock h, v$session w1, v$session h1
where (((h.kgllkmod != 0) and (h.kgllkmod != 1)
and ((h.kgllkreq = 0) or (h.kgllkreq = 1)))
and (((w.kgllkmod = 0) or (w.kgllkmod = 1))
and ((w.kgllkreq != 0) and (w.kgllkreq != 1))))
and w.kgllktype = h.kgllktype
and w.kgllkhdl = h.kgllkhdl
and w.kgllkuse = w1.saddr
and h.kgllkuse = h1.saddr;
该sql可以很清楚的显示出,谁阻碍了谁。查询结果显示23号session锁定了33号session。于是发出下面的sql:
select sql_text from v$sql
where hash_value=(select sql_hash_value from v$session where sid=23);
可以看到23号session在干什么。结果发现它在执行重新rebuild索引的命令:
alter index XXX rebuild online;
而该索引正是要加载的表上的索引,于是可以肯定,该语句阻塞了sqlldr的操作。
于是在确定了23号session无关紧要以后,将该session直接切断即可。切断该session以后,sqlldr很快就完成了加载数据的工作。
结论:
当发现oracle里某个动作特别慢的时候,先查看一下它在等待什么。
可能并不一定是这个动作本身慢,而是其他的原因导致它无法进行下去。
于是,让客户查询v$session_wait,发现执行sqlldr加载的session(session id为33)正在等待library cache lock的等待事件。很明显,sqlldr一直在等待,而不是在进行实际的加载工作。
既然是等待library cache lock,说明有其他的进程锁定了要加载的表,导致sqlldr
无法获得该表上的lock。这属于shared pool里的一种争用。
然后,我让客户发出下面的SQL:
select /*+ ordered */
w1.sid waiting_session,
h1.sid holding_session,
w.kgllktype lock_or_pin,
w.kgllkhdl address,
decode(h.kgllkmod,0,'None',1,'Null',2,'Share',3,'Exclusive','Unknown') mode_held,
decode(w.kgllkreq,0,'None',1,'Null',2,'Share',3,'Exclusive','Unknown') mode_requested
from dba_kgllock w, dba_kgllock h, v$session w1, v$session h1
where (((h.kgllkmod != 0) and (h.kgllkmod != 1)
and ((h.kgllkreq = 0) or (h.kgllkreq = 1)))
and (((w.kgllkmod = 0) or (w.kgllkmod = 1))
and ((w.kgllkreq != 0) and (w.kgllkreq != 1))))
and w.kgllktype = h.kgllktype
and w.kgllkhdl = h.kgllkhdl
and w.kgllkuse = w1.saddr
and h.kgllkuse = h1.saddr;
该sql可以很清楚的显示出,谁阻碍了谁。查询结果显示23号session锁定了33号session。于是发出下面的sql:
select sql_text from v$sql
where hash_value=(select sql_hash_value from v$session where sid=23);
可以看到23号session在干什么。结果发现它在执行重新rebuild索引的命令:
alter index XXX rebuild online;
而该索引正是要加载的表上的索引,于是可以肯定,该语句阻塞了sqlldr的操作。
于是在确定了23号session无关紧要以后,将该session直接切断即可。切断该session以后,sqlldr很快就完成了加载数据的工作。
结论:
当发现oracle里某个动作特别慢的时候,先查看一下它在等待什么。
可能并不一定是这个动作本身慢,而是其他的原因导致它无法进行下去。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/9842/viewspace-331084/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/9842/viewspace-331084/