https://github.com/CarlJi/words
- 空间不足
- 磁盘I/O过载
- 文件句柄过多
- 读写错误
而掌握常见的分析套路会事半功倍。
Disk usage
$ df -h
Filesystem Size Used Avail Use% Mounted on
udev 48G 4.0K 48G 1% /dev
tmpfs 9.5G 8.55G 9.5G 90% /run
/dev/sda1 275G 234G 28G 90% /
/dev/sdd1 2.7T 1.6T 1.2T 57% /disk3
/dev/sdc1 3.6T 2.6T 1.1T 72% /disk1
/dev/sdb1 3.6T 4.2G 3.6T 1% /disk2
这个指标就比较清晰展示目标磁盘已经使用多少了。
Inode usage
有时候我们会发现明明磁盘有容量,但是程序仍然报,这是因为什么呢?
$ df -i
Filesystem Inodes IUsed IFree IUse% Mounted on
udev 12370103 518 12369585 1% /dev
tmpfs 12372788 611 12372177 1% /run
/dev/sda1 18317312 1941821 16375491 11% /
/dev/sdd1 183148544 181317058 1831468 99% /disk3
/dev/sdc1 244195328 153483 244041845 1% /disk1
/dev/sdb1 244195328 7496 244187832 1% /disk2
可以看到对应的目录其Inode已经使用99%,很快就会耗尽。Inode代表的是文件的metadata信息,若inode使用过多,通常意味着目录里小文件太多了。
Disk utilization high
磁盘使用率高,一般是已经知道是哪个盘了,但如果不知道,使用也能较清晰的查看到:
$ iostat -x 1
Linux 3.19.0-80-generic 2022年05月12日 _x86_64_ (24 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
5.85 0.00 3.60 4.83 0.00 85.72
Device: rrqm/s wrqm/s r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 0.00 237.00 441.00 48.00 56448.00 1388.00 236.55 0.97 1.98 1.02 10.83 1.00 48.80
sdb 0.00 26.00 2.00 186.00 8.00 93876.00 998.77 44.51 348.13 466.00 346.86 5.32 100.00
sdc 0.00 0.00 155.00 7.00 18132.00 16.00 224.05 6.62 47.95 46.71 75.43 4.02 65.20
sdd 0.00 30.00 8.00 8.00 900.00 212.00 139.00 0.10 6.25 3.50 9.00 6.00 9.60
PS: 可以只查看某个设备。
但要注意,高并不严格意味着磁盘已经过载了,因为现代硬盘设备都有并行处理多个I/O请求的能力。要关注磁盘利用率,还需要关注(再具体就是读和写指标),这个指标大致等于单个I/O所需的平均时间,所以如果它也很大,那磁盘一定是很繁忙了。
Which processes are using the specific disk?
粗略的可以通过 直接查看当前正在读写的进程。一般机器上有哪些程序,我们应该比较清楚,所以这时候可以大致判断出来:
$ iotop -oP
Total DISK READ : 173.26 M/s | Total DISK WRITE : 177.38 M/s
Actual DISK READ: 175.77 M/s | Actual DISK WRITE: 85.50 M/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
6929 be/4 root 168.67 M/s 168.57 M/s 0.00 % 76.51 % dd if=/dev/sda bs=4M count=100000 of=mbr.img
379 be/3 root 0.00 B/s 15.61 K/s 0.00 % 2.01 % [jbd2/sda1-8]
当然这种方式也存在一个问题,你是看不出目标进程具体使用哪块磁盘的。那怎么办呢?可以借助命令,通过正在打开的文件句柄来识别进程:
$ lsof +D /disk2
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
prometheu 1705 root mem REG 8,17 72567556 234356807 /disk2/prometheus_dir/data/01G2J2YMJPY9HXMP5KSPW30MM1/chunks/000001
prometheu 1705 root mem REG 8,17 73620431 234356815 /disk2/prometheus_dir/data/01G19H692F7JN796CBQDSFVV1W/chunks/000001
prometheu 1705 root mem REG 8,17 73173252 234356814 /disk2/prometheus_dir/data/01G13QSNA21PYK2R6SC0BFYZYM/chunks/000001
然后通过 进一步分析这些进程的读写情况 :
$ pidstat -d
Linux 3.19.0-80-generic 2022年05月15日 _x86_64_(24 CPU)
16时21分37秒 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
16时21分59秒 0 1705 64.00 67.19 0.00 prometheus
和 这两个指标,能基本代表进程读写磁盘的速度。
Too many open files
可以通过命令来查看当前进程已经打开了多少个文件:
$ ls -1 /proc/1705/fd | wc -l
1258
而若想查看某进程具体的句柄限制,可以通过命令:
$ cat /proc/1705/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 386565 386565 processes
Max open files 20240 20240 files
而若要调整这个限制,可以通过命令或修改系统文件.
EIO (input/output error)
遇到这个错误,一般是物理磁盘坏了。可能是整个盘坏了不能读写,也有可能是某个block有问题。这时候通过查看内核日志,通常会有相应的error信息。