这次的情况是这样的 创建一个external table 从远端gunzip文件过来。结果hang住了。
创建一个pipe文件
$ mknod /tmp/tmp_pipe p
CREATE DIRECTORY dir AS '/tmp';
创建个external table
CREATE TABLE ext (
value number
)
ORGANIZATION EXTERNAL (
TYPE oracle_loader
DEFAULT DIRECTORY dir
ACCESS PARAMETERS (
FIELDS TERMINATED BY ';'
MISSING FIELD VALUES ARE NULL
(value)
)
LOCATION ('tmp_pipe')
)
;
查询:select * FROM ext
然后就会一直hang在哪里。
此时查询v$session_wait ;
external table misc IO
得到这样的等待信息
提示已近等待了数百秒,难道他一直在工作吗?
这是我们truss 该PID
得到
[oracle@db root]$ strace -p 23861
Process 23861 attached - interrupt to quit
open("/tmp/tmp_pipe", O_RDONLY
一直在open这个文件,这样的话 我就可能需要检查是不是 我的network 或者gunzip处理问题。
这里如果给的是number的话 那么可能需要lsof来判断正在开启哪个文件
附上用法:
Linux 上显示某进程打开的文件
lsof -p 12 看进程号为12的进程打开了哪些文件
solaris上
pfile
au(x) 输出格式 :
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
USER: 行程拥有者
PID: pid
%CPU: 占用的 CPU 使用率
%MEM: 占用的记忆体使用率
VSZ: 占用的虚拟记忆体大小
RSS: 占用的记忆体大小
TTY: 终端的次要装置号码 (minor device number of tty)
STAT: 该行程的状态:
D: 不可中断的静止
R: 正在执行中
S: 静止状态
T: 暂停执行
Z: 不存在但暂时无法消除
W: 没有足够的记忆体分页可分配
<:>高优先序的行程
N: 低优先序的行程
L: 有记忆体分页分配并锁在记忆体内
START: 行程开始时间
TIME: 执行的时间
COMMAND:所执行的指令
------------------------------------------------------------------------------------------
D 不可中断 uninterruptible sleep (usually IO)
R 运行 runnable (on run queue)
S 中断 sleeping
T 停止 traced or stopped
Z 僵死 a defunct (”zombie”) process
接下来就一个这样好玩的问题了
SQL> select state, seq#, event, seconds_in_wait from v$session_wait where sid = 197;
STATE SEQ# EVENT SECONDS_IN_WAIT
——————- ———- —————————– —————
WAITED KNOWN TIME 63 SQL*Net message from client 1505
SID STATE EVENT SEQ# SECONDS_IN_WAIT P1 P2 P3
———- ——- ——————– ——- ————— ———— ———- ———-
197 WORKING On CPU / runqueue 63 1514 1413697536 1 0
这里显示 session持有CPU 而且并未产生任何等待,因为状态是 waited not waiting.可是他已经工作了1505秒了
于是我们从OS 层面上检测一下
Ora sid2pid 197
9597
Prstat –p 9597
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
9597 oracle 1145M 1070M sleep 59 0 0:00.00 0.0% oracle/1
可以看到他整处于sleep 状态 并且 CPU 0.0%
也就是什么都没干
[llinux ] Ps –aux |grep 9597 可以看到S列是 Ss
接下来你该如何是好?
Pstack 9597
9597: oracleXXXXXX01 (LOCAL=NO)
ffffffff7c9a7854 sigsuspend (ffffffff7fff6d90)
ffffffff7c956d2c _libc_sleep (0, 5, 0, 0, 0, ffffffff7fff6f21) + f8
0000000100cc0188 qm_init_uga_helper (380028000, 380028, 3ba048b68, 380000, 380028000, 380028000) + 6c8
00000001002d4808 rpiswu2 (0, 104556000, ffffffff7fff70d8, 2, 104556418, ffffffff7fff7a80) + 1a8
0000000100cc5af0 qm_run_as_ksys (ffffffff7fff761c, 100cbfac0, ffffffff7fff7541, 1042dbd80, 1042db000, 1042db) + b0
…..
00000001002a7b34 main (2, ffffffff7ffff358, ffffffff7ffff370, 0, 0, 100000000) + 94
00000001002a7a7c _start (0, 0, 0, 0, 0, 0) + 17c
这个是内存的堆栈信息,从底下往上看start,main etc…
看到头部分是以ffffff开头的这个好奇怪 于是继续使用pmap
$ pmap 9597 | grep -i ^ffffffff7c9
FFFFFFFF7C900000 728K read/exec /usr/lib/sparcv9/libc.so.1
【linux下没有code 内存大小 只有开头的address 部分 不过大家也能看懂了】
他是call的libc.so.1
那么问题是否发生在这里呢?
$ nm /usr/lib/sparcv9/libc.so.1 | egrep "Size|_libc_sleep"
[Index] Value Size Type Bind Other Shndx Name
[228] | 355380| 396|FUNC |LOCL |0 |9 |_libc_sleep
就是这个东西。
可是一条简单的命令为何会调用这个东西呢?
检查了一下 ORACLE 的启动环境 发现LD_LIBRARY_PATH.的变量中$ORACLE_HOME/lib32 在$ORACLE_HOME/lib前面
这可能会导致他load 32bit的包 来替代64位的。
重新修改变量 问题解决。
这次的问题,我没有思考是否是因为SQL的I/O问题或者是产生了什么CPU等待,因为等待提示中什么都看不出来。
所以直接回归到最原始的部分,OS PROCESS ,在这里你总会看到真相所在。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/21818314/viewspace-693211/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/21818314/viewspace-693211/