作者:李燁楠 中國建設銀行
來自微信公眾號:平臺人生
環境: AIX 6.1 AIX7.1
前言:
用戶有時需要統計一個進程打開的文件數目,比如,在當前打開文件句柄使用量是否超過用戶資源限制(/etc/security/limits)中 nofiles的取值時。那么,AIX系統中該如何實現這一需求呢?如何判斷我們設置的nofiles值對當前應用是否夠用呢?下面我們提供三種方法進行統計。
使用 procfiles 命令
procfiles 命令可以顯示進程打開的所有文件描述符(FD,file descriptor,即代表打開的文件)信息,加上 -n 參數還可以顯示相關文件名稱。
sfmon@localhost>procfiles 51184046
51184046 : -ksh
Current rlimit: 8192 file descriptors
0: S_IFCHR mode:00 dev:10,4 ino:13150 uid:901 gid:900 rdev:30,0
O_RDWR | O_NOCTTY
1: S_IFCHR mode:00 dev:10,4 ino:13150 uid:901 gid:900 rdev:30,0
O_RDWR | O_NOCTTY
2: S_IFCHR mode:00 dev:10,4 ino:13150 uid:901 gid:900 rdev:30,0
O_RDWR | O_NOCTTY
10: S_IFREG mode:0444 dev:10,5 ino:40370 uid:901 gid:900 rdev:0,0
O_RDONLY size:0
63: S_IFREG mode:0600 dev:110,1 ino:5 uid:901 gid:900 rdev:0,0
O_RDWR | O_APPEND size:0
sfmon@localhost>procfiles -n 51184046
51184046 : -ksh
Current rlimit: 8192 file descriptors
0: S_IFCHR mode:00 dev:10,4 ino:13150 uid:901 gid:900 rdev:30,0
O_RDWR | O_NOCTTY name://dev/pts/0
1: S_IFCHR mode:00 dev:10,4 ino:13150 uid:901 gid:900 rdev:30,0
O_RDWR | O_NOCTTY name://dev/pts/0
2: S_IFCHR mode:00 dev:10,4 ino:13150 uid:901 gid:900 rdev:30,0
O_RDWR | O_NOCTTY name://dev/pts/0
10: S_IFREG mode:0444 dev:10,5 ino:40370 uid:901 gid:900 rdev:0,0
O_RDONLY size:0name:/usr/lib/nls/msg/en_US/ksh.cat
63: S_IFREG mode:0600 dev:110,1 ino:5 uid:901 gid:900 rdev:0,0
O_RDWR | O_APPEND size:0name:/home/ap/sfmon/.sh_history
注意,stdin/stdout/stderr都各占一個文件描述符,而且socket也是要占用文件描述符的。
相關知識介紹:proctools系列命令
/proc 文件系統提供了一種控制進程的機制。它還提供了對有關當前進程和線程狀態信息的訪問,不過該信息是二進制格式。/proc 文件系統中每個條目的名稱都是與進程 ID 對應的十進制數字。這些條目是子目錄,每個條目的所有者由進程的用戶 ID 確定。對進程狀態的訪問是由每個子目錄中包含的附加文件提供的。
proctools系列命令(/proc 命令)基于某些可用信息提供 ASCII 報告。其中大多數命令接受進程 ID 列表或 /proc/ProcessID 字符串作為輸入。因此可以使用 Shell 擴展 /proc/* 指定系統中的所有進程。
proctools系列命令從 /proc 中收集指定進程的信息并向用戶顯示該信息。這些命令從 /proc 中收集的信息是當前進程狀態的快照,因此除了已終止的進程外,此信息在任何時刻都會有所不同。
proctools 命令包括:
procfiles 報告有關由進程打開的所有文件描述符的信息。
proctree 打印包含特定進程 ID 或用戶的進程樹。
procsig 列出進程定義的信號操作。
procstack 打印進程中所有線程的十六進制地址和符號名稱。
procrun 啟動在發生 PR_REQUESTED 事件時停止的進程。
procmap 打印進程的地址空間映射。
procflags 打印指定進程中每個線程的 /proc 跟蹤標志、掛起和保持信號以及其他 /proc 狀態信息。
proccred 打印進程的憑據(有效、實際、已保存的用戶 ID 和組 ID)。
procldd 列出進程加載的對象,包括使用 dlopen() 來顯式附加的共享對象。
procwait 等待所有指定的進程終止。
procwdx 打印進程的當前工作目錄。
procstop 在發生 PR_REQUESTED 事件時終止進程。
在生產環境中檢查進程時應該特別小心,特別不建議編入腳本循環執行進行系統監控,因為這些工具在進行檢查時可能會掛起進程。
2.使用pstat命令統計:# pstat -a | grep,
獲得進程的slot ID。 # pstat -u | grep "fd " | wc -l
每個 fd 代表一個打開的文件描述符。
使用方法:
進入kdb,轉換進程號pid至16進制,然后退出kdb。
root>kdb
(0)>dcal 1442240
Value decimal: 1442240 Value hexa: 001601C0
(0)>q
查看同名進程,根據進程號16進制,找到對應的slotID:
root>pstat -a | grepksh
1046a 1601c0 2b01a8 1601c0 0 0 1 ksh
1054 a 1e0142 1d00d4 1e0142 0 0 1 ksh
1056 a 200152 1b0312 1b0312 8 8 1 ksh
3099 a 1b0312 1d00d4 1b0312 0 0 1 ksh
查看打開的文件描述符:
root>pstat -u 1046 | grep "fd "
fd 0: fp = 0xf1000f1e9009c900 flags = 0x0480 count = 0x0000
fd 1: fp = 0xf1000f1e9009c900 flags = 0x0480 count = 0x0000
fd 2: fp = 0xf1000f1e9009c900 flags = 0x0480 count = 0x0000
fd 10: fp = 0xf1000f1e90062900 flags = 0x0481 count = 0x0000
fd 63: fp = 0xf1000f1e90084600 flags = 0x0481 count = 0x0000
統計使用文件描述符數目:
root@xxhjibm0502:/>pstat -u 1046 | grep "fd " | wc -l
5
3.使用lsof命令
如果系統部署安裝了lsof工具,統計一個進程打開的文件數目的工作則更加簡單直接。
root@xxhjibm0502:/>lsof -p 1442240
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
ksh 1442240 root cwd VDIR 10,4 4096 2 / (/dev/hd4)
ksh 1442240 root 0u VCHR 37,0 0t574139 25377 /dev/pts/0
ksh 1442240 root 1u VCHR 37,0 0t574139 25377 /dev/pts/0
ksh 1442240 root 2u VCHR 37,0 0t574139 25377 /dev/pts/0
ksh 1442240 root 10r VREG 10,5 5875 62228 /usr (/dev/hd2)
ksh 1442240 root 63u VREG 10,4 20768 31 / (/dev/hd4)