Aix平台查看进程打开的文件

最近刚好处理了一个Oracle数据库因为file descriptor耗尽,不能继续工作的案例。Oracle的MNL进程,打开了太多的文件,导致了这个错误。

背景:

  • Unix中一切皆文件,socket,file…
  • /proc 虚拟文件系统可以方便查看进程信息,包括打开的文件(fd,file descriptor)
  • 大多数linux系统可以使用lsof来查看、使用/proc中包含的信息

Aix环境查看进程打开的文件

进入/proc/<mnl_process_pid>目录,查看fd子目录,可以查看所有打开的fd(file descriptor)

# cd /proc/184422/fd
# ls -l

这个文件夹下都是一些数字(fd),接下来使用相关工具,找到打开的都是什么文件

procfiles 命令

procfiles <process_pid> —— 命令使用方式

# procfiles 184422

Current rlimit: 2147483647 file descriptors
   4: S_IFREG mode:0444 dev:10,5 ino:13407 uid:0 gid:0 rdev:0,0
      O_RDONLY size:4811 

会显示如上所示的信息,4 是 fd,文件在设备10,5上,文件系统的inode是13407
下面我们来查看dev:10,5 对应哪块磁盘

# cd /dev
# ls -l | grep "10, *5"
brw-rw----   1 root     system       10,  5 Oct 10 2005  hd2
crw-rw----   1 root     system       10,  5 Oct 10 2005  rhd2

所以,可知文件存储在/dev/hd2上(hd2是块设备,rhd2是字符设备)/dev/hd2对应什么文件系统呢?

# lsfs | grep hd2
/dev/hd2        --         /usr           jfs2 3801088 yes no

由此可知,该设备对应/usr 文件系统,现在知道文件系统是/usr,inode是13407;先查看这个文件的信息:

# istat 13407 /usr
Inode 13407 on device 10/5
File Protection: rw-r--r--
Owner: 2(bin)           Group: 2(bin)
Link count:   1         Length 4811 bytes
Last updated:   Tue Aug 24 16:14:48 CDT 2004
Last modified:  Mon Jul 12 11:33:31 CDT 2004
Last accessed:  Wed Aug  9 09:16:28 CDT 2006
Block pointers (hexadecimal): 1892c

文件名是什么?

# cd /usr
# find . -inum 13407 -exec ls -l {} \;
-rw-r--r--   1 bin      bin            4811 Jul 12 2004
./lib/nls/msg/en_US/hostmibd.cat

所以呢,通过上述操作,一步步,从/proc中的fd,最终定位到对应的文件位置(linux中没这么多步骤需要)

pstat命令

可使用pstat命令,查看进程的file descriptor table
首先获取要查看的进程PID:

# ps -ef | grep cron
    root 323762      1   0   Oct 06      -  0:07 /usr/sbin/cron

上述输出,显示PID是323762,转化为16进制:0x4F0B2

# pstat -a | grep -i 4F0B2
SLT ST    PID   PPID   PGRP   UID  EUID  TCNT  NAME
 79 a   4f0b2      1  4f0b2     0     0     1  cron

上述命令,显示该进程对应的Slot(SLT)为79(后述命令要使用Slot)

# pstat -u 79 | grep FILE
FILE SYSTEM STATE
FILE DESCRIPTOR TABLE

# pstat -u 79 | grep -p "FILE DESCRIPTOR TABLE"
FILE DESCRIPTOR TABLE
*ufd: 0xf00000002ff49e20
fd 0: fp = 0xf1000714500080e0 flags = 0x0080 count = 0x0000
fd 1: fp = 0xf100071450007fa0 flags = 0x0080 count = 0x0000
fd 2: fp = 0xf100071450007fa0 flags = 0x0080 count = 0x0000
fd 3: fp = 0xf100071450007780 flags = 0x0080 count = 0x0000
fd 4: fp = 0xf100071450007af0 flags = 0x0080 count = 0x0000
fd 5: fp = 0xf1000714500079b0 flags = 0x0080 count = 0x0000
fd 6: fp = 0xf1000714500066a0 flags = 0x0080 count = 0x0000
fd 7: fp = 0xf100071450008270 flags = 0x0080 count = 0x0000
fd 8: fp = 0xf1000714500081d0 flags = 0x0080 count = 0x0000
fd 9: fp = 0xf100071450008220 flags = 0x0080 count = 0x0000
fd 10: fp = 0xf100071450008180 flags = 0x0080 count = 0x0000
fd 11: fp = 0xf1000714500082c0 flags = 0x0080 count = 0x0001
fd 12: fp = 0xf100071450008130 flags = 0x0081 count = 0x0000

lsof命令

默认状态下Aix可能没有lsof命令,如果有可以直接使用lsof查看进程打开的文件

# lsof -p pid

Leave Comment