Linux 檢視檔案被那個程序寫資料
檔案被那個程序使用,寫資料不是用lsof可以找出來嗎,但現實情況是lsof沒找出來T_T
背景
centos7 在某一段時間監控報警磁盤使用率達99%,由于監控屬于概要形式資訊,沒有快照資訊的監控(能發現某程序的I/O,CPU消耗情況),是以需要在伺服器上去定時執行統計指令擷取快照資訊。
需要通過iostat -dx -k去檢視avgqu-sz、await、svctm、%util;
sar -u檢視%iowait、%user;
pidstat -d 檢視程序I/O讀寫的快照資訊
步驟
- 生成統計資訊檔案
cat>/tmp/at_task.sh<<EOF
pidstat -d 2 >/tmp/pidstat_\`date +%F_%T\`.log 2>& 1 &
sar -u 2 >/tmp/sar_\`date +%F_%T\`.log 2>& 1 &
while [ 1 ];do echo -n \`date +%T\` >>/tmp/iostat_\`date +%F\` 2>& 1 && iostat -dx -k 1 1 >>/tmp/iostat_\`date +%F\` 2>& 1; sleep 2; done &
EOF
在while循環中使用iostat的原因是要輸出 date +%T
時間,不然隻有資料,沒有時間資訊也沒有什麼用
- 使用at 指令定時執行
at 15:14 today -f /tmp/at_task.sh
出現錯誤
Can't open /var/run/atd.pid to signal atd. No atd running?
重新開機atd服務
service atd restart
重新開啟at定時任務
at 15:14 today -f /tmp/at_task.sh
job 2 at Wed Mar 13 15:14:00 2019
得到如下快照資訊
iostat
15:13:35Linux 3.10.0-862.14.4.el7.x86_64 (ip-xxxxx) 03/13/2019 _x86_64_ (4 CPU)
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
vda 0.12 0.07 17.31 19.41 580.79 90.52 36.57 0.09 2.39 4.42 0.57 0.72 2.63
scd0 0.00 0.00 0.00 0.00 0.00 0.00 6.00 0.00 0.28 0.28 0.00 0.25 0.00
sar
03:14:00 PM CPU %user %nice %system %iowait %steal %idle
03:14:02 PM all 0.25 0.00 0.38 0.00 0.00 99.37
03:14:04 PM all 1.25 0.13 0.63 0.00 0.00 97.99
03:14:06 PM all 0.25 0.13 0.50 0.00 0.00 99.12
03:14:08 PM all 0.50 0.00 0.50 0.63 0.00 98.37
pidstat
03:14:00 PM UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
03:14:02 PM 5700 9089 0.00 6.00 0.00 uxxx
03:14:02 PM 5700 9140 0.00 6.00 0.00 uxxx
03:14:02 PM 5700 9292 0.00 10.00 0.00 uxxx
03:14:02 PM 0 18084 0.00 2.00 0.00 bash
kill 掉收集資訊的指令
ps -ef | egrep 'iostat|sar|pidstat|while' | grep -v grep | awk '{print $2}' | xargs -l kill
*但ps -ef | egrep 指令沒有擷取到while循環的pid,不kill掉該while循環,就會一直對/tmp/iostat_2019-03-13寫資料-_-*
通過lsof 沒有定位到打開檔案的程序
lsof /tmp/iostat_2019-03-13
[root@ip-10-186-60-117 ~]#
[root@ip-10-186-60-117 ~]#
通過lsof 可以定位到打開mysql-error.log的程序
lsof /opt/mysql/data/5690/mysql-error.log
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mysqld 12858 actiontech-universe 1w REG 253,1 6345 20083533 /opt/mysql/data/5690/mysql-error.log
mysqld 12858 actiontech-universe 2w REG 253,1 6345 20083533 /opt/mysql/data/5690/mysql-error.log
可見,某程序隻有一隻持有某檔案的inode,才可以通過lsof檢視檔案在被那些程序使用
擷取寫檔案的程序号
安裝sysemtap
yum -y install systemtap
SystemTap 是對 Linux 核心監控和跟蹤的工具
利用systemtap中的inodewatch.stp工具來查找寫檔案的程序号
得到檔案的inode
stat -c '%i' /tmp/iostat_2019-03-13
4210339
擷取檔案所在裝置的major,minor
ls -al /dev/vda1
brw-rw---- 1 root disk 253, 1 Jan 30 13:57 /dev/vda1
得到寫檔案的pid
stap /usr/share/systemtap/examples/io/inodewatch.stp 253 1 4210339
Checking "/lib/modules/3.10.0-862.14.4.el7.x86_64/build/.config" failed with error: No such file or directory
Incorrect version or missing kernel-devel package, use: yum install kernel-devel-3.10.0-862.14.4.el7.x86_64
根據系統核心版本在
kernel-devel rpm build for : Scientific Linux 7網站上下載下傳相應的kernal-devel包
wget ftp://ftp.pbone.net/mirror/ftp.scientificlinux.org/linux/scientific/7.2/x86_64/updates/security/kernel-devel-3.10.0-862.14.4.el7.x86_64.rpm
rpm -ivh kernel-devel-3.10.0-862.14.4.el7.x86_64.rpm
再次執行stap
stap /usr/share/systemtap/examples/io/inodewatch.stp 253 1 4210339
......
Missing separate debuginfos, use: debuginfo-install kernel-3.10.0-862.14.4.el7.x86_64
Pass 2: analysis failed. [man error::pass2]
Number of similar error messages suppressed: 2.
安裝debuginfo kernal
debuginfo-install kernel-3.10.0-862.14.4.el7.x86_64
Verifying : kernel-debuginfo-common-x86_64-3.10.0-862.14.4.el7.x86_64 1/3
Verifying : yum-plugin-auto-update-debug-info-1.1.31-50.el7.noarch 2/3
Verifying : kernel-debuginfo-3.10.0-862.14.4.el7.x86_64 3/3
Installed:
kernel-debuginfo.x86_64 0:3.10.0-862.14.4.el7
yum-plugin-auto-update-debug-info.noarch 0:1.1.31-50.el7
Dependency Installed:
kernel-debuginfo-common-x86_64.x86_64 0:3.10.0-862.14.4.el7
stap /usr/share/systemtap/examples/io/inodewatch.stp 253 1 4210339
ERROR: module version mismatch (#1 SMP Tue Sep 25 14:32:52 CDT 2018 vs #1 SMP Wed Sep 26 15:12:11 UTC 2018), release 3.10.0-862.14.4.el7.x86_64
WARNING: /usr/bin/staprun exited with status: 1
添加 -v檢視詳細報錯
stap -v /usr/share/systemtap/examples/io/inodewatch.stp 253 1 4210339
Pass 1: parsed user script and 471 library scripts using 240276virt/41896res/3368shr/38600data kb, in 300usr/20sys/320real ms.
Pass 2: analyzed script: 2 probes, 12 functions, 8 embeds, 0 globals using 399436virt/196284res/4744shr/197760data kb, in 1540usr/560sys/2106real ms.
Pass 3: using cached /root/.systemtap/cache/f5/stap_f5c0cd780e8a2cac973c9e3ee69fba0c_7030.c
Pass 4: using cached /root/.systemtap/cache/f5/stap_f5c0cd780e8a2cac973c9e3ee69fba0c_7030.ko
Pass 5: starting run.
ERROR: module version mismatch (#1 SMP Tue Sep 25 14:32:52 CDT 2018 vs #1 SMP Wed Sep 26 15:12:11 UTC 2018), release 3.10.0-862.14.4.el7.x86_64
WARNING: /usr/bin/staprun exited with status: 1
Pass 5: run completed in 0usr/10sys/38real ms.
Pass 5: run failed. [man error::pass5]
修改
vim /usr/src/kernels/3.10.0-862.14.4.el7.x86_64/include/generated/compile.h
#define UTS_VERSION "#1 SMP Tue Sep 25 14:32:52 CDT 2018"
改為
#define UTS_VERSION "#1 SMP Wed Sep 26 15:12:11 UTC 2018"
rm -rf /root/.systemtap/cache/f5/stap_f5c0cd780e8a2cac973c9e3ee69fba0c_7030*
參考
SystemTap - 安裝再次執行
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4671) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4677) vfs_write 0xfd00001/4210339
iostat(4683) vfs_write 0xfd00001/4210339
............
可見已經得到了寫/tmp/iostat_
date +%F
檔案的程序号,但程序号一直在列印出來,因為背景程序iostat -dx -m 的在while循環中的,每隔sleep 2s 後就會執行一次iostat 産生新的pid。
***那要怎樣才能讓iostat -dx -m 停止寫/tmp/iostat_
date +%F
檔案了?除了重新開機大法好 $_$***
rm -rf 也不能終止背景的while iostat程序寫檔案,删除了檔案後,while循環又會生成新的檔案
rm -rf /tmp/iostat_2019-03-1*
stat /tmp/iostat_2019-03-1*
File: ‘/tmp/iostat_2019-03-13’
Size: 146700 Blocks: 512 IO Block: 4096 regular file
Device: fd01h/64769d Inode: 4210339 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2019-03-14 16:07:26.211888899 +0800
Modify: 2019-03-14 16:18:17.854019793 +0800
Change: 2019-03-14 16:18:17.854019793 +0800
正确做法
cat>/tmp/iostat.sh<<EOF
while [ 1 ];do echo -n \`date +%T\` >>/tmp/iostat_\`date +%F\` 2>& 1 && iostat -dx -m 1 1 >>/tmp/iostat_\`date +%F\` 2>& 1; sleep 2; done &
EOF
at now + 1 minute today
bash /tmp/iostat.sh
#這樣就能友善的擷取到程序号pid了
ps -ef | grep iostat
root 8593 1 0 16:16 pts/2 00:00:00 bash /tmp/iostat.sh
I Need the Kernel Source Linux下如何知道檔案被那個程序寫 Linux下的IO監控與分析 使用systemtap調查異常io的來源 原文位址
https://www.cnblogs.com/YangJiaXin/p/10531197.html