我是靠谱客的博主 快乐黑裤,最近开发中收集的这篇文章主要介绍Linux 之如何查看文件是被那个进程占用写数据?介绍背景一、步骤二、获取写文件的进程号三、正确做法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

文章目录

  • 介绍背景
  • 一、步骤
        • 1. 1成统计信息文件
        • 1.2 使用at 命令定时执行
        • 1.3 得到如下快照信息
        • 1.4 kill 掉收集信息的命令
  • 二、获取写文件的进程号
        • 2.1 安装sysemtap
        • 2.2 得到文件的inode
        • 2.3 获取文件所在设备的major,minor
        • 2.4 得到写文件的pid
        • 2.5 根据系统内核版本在kernel-devel rpm build for : Scientific Linux 7网站上下载相应的kernal-devel包
        • 2.6 再次执行stap
        • 2.7 安装debuginfo kernal
        • 2.8 再次执行stap
        • 2.9 修改
        • 2.10 再次执行
  • 三、正确做法

介绍背景

centos7 在某一段时间监控报警磁盘使用率达99%,由于监控属于概要形式信息,没有快照信息的监控(能发现某进程的I/O,CPU消耗情况),所以需要在服务器上去定时执行统计命令获取快照信息。
需要通过iostat -dx -k去查看avgqu-sz、await、svctm、%util;
sar -u查看%iowait、%user;
pidstat -d 查看进程I/O读写的快照信息

一、步骤

1. 1成统计信息文件

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时间,不然只有数据,没有时间信息也没有什么用

1.2 使用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 2022

1.3 得到如下快照信息

  1. iostat
15:13:35Linux 3.10.0-862.14.4.el7.x86_64 (ip-xxxxx)
03/13/2022
_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
  1. 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
  1. 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

1.4 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_2022-03-13写数据-_-

  1. 通过lsof 没有定位到打开文件的进程
lsof /tmp/iostat_2022-03-13
[root@ip-10-186-60-117 ~]#
[root@ip-10-186-60-117 ~]#
  1. 通过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查看文件在被那些进程使用。

二、获取写文件的进程号

2.1 安装sysemtap

yum -y install systemtap
SystemTap 是对 Linux 内核监控和跟踪的工具
利用systemtap中的inodewatch.stp工具来查找写文件的进程号

2.2 得到文件的inode

stat -c '%i' /tmp/iostat_2022-03-13
4210339

2.3 获取文件所在设备的major,minor

s -al /dev/vda1
brw-rw---- 1 root disk 253, 1 Jan 30 13:57 /dev/vda1

2.4 得到写文件的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

2.5 根据系统内核版本在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

2.6 再次执行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.

2.7 安装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

2.8 再次执行stap

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]

2.9 修改

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*

2.10 再次执行

stap /usr/share/systemtap/examples/io/inodewatch.stp 253 1 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(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
............
  1. 可见已经得到了写/tmp/iostat_date +%F 文件的进程号,但进程号一直在打印出来,因为后台进程iostat -dx -m 的在while循环中的,每隔sleep 2s 后就会执行一次iostat 产生新的pid。
    那要怎样才能让iostat -dx -m 停止写/tmp/iostat_date +%F 文件了?除了重启大法好 KaTeX parse error: Expected group after '_' at position 1: _̲
  2. 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

最后

以上就是快乐黑裤为你收集整理的Linux 之如何查看文件是被那个进程占用写数据?介绍背景一、步骤二、获取写文件的进程号三、正确做法的全部内容,希望文章能够帮你解决Linux 之如何查看文件是被那个进程占用写数据?介绍背景一、步骤二、获取写文件的进程号三、正确做法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(39)

评论列表共有 0 条评论

立即
投稿
返回
顶部