笔者历史文章: https://github.com/CarlJi/words

关于磁盘的使用,实际生产中以下问题会较为常见:

  • No space left on device - 空间不足
  • Disk utilization 100% - 磁盘I/O过载
  • Too many open files - 文件句柄过多
  • Input/output error - 读写错误

而掌握常见的分析套路会事半功倍。

Disk usage

第一时间明确磁盘容量及使用情况总是没错的,这时候df -h 命令就比较方便:

$ 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

Use% 这个指标就比较清晰展示目标磁盘已经使用多少了。

注意,第三行的tmpfs文件系统比较特殊,其数据实际是存储在内存中而非磁盘。

Inode usage

有时候我们会发现明明磁盘有容量,但是程序仍然报No space left on device,这是因为什么呢?

答案大概率是Inode耗尽了。这时候可以通过df -i 来确认,比如:

$ 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

可以看到/disk3对应的目录其Inode已经使用99%,很快就会耗尽。Inode代表的是文件的metadata信息,若inode使用过多,通常意味着目录里小文件太多了。

PS: 不规范的容器化姿势比较容易出现这个问题,比如Pod一直在产生日志,且使用的是系统盘又不定期回收。

Disk utilization high

磁盘使用率高,一般是已经知道是哪个盘了,但如果不知道,使用iostat -x 1也能较清晰的查看到:

$ 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: iostat -xd <device> 1 可以只查看某个设备。

可以看到sdb这块盘,其%util指标已经100%。

但要注意,%util高并不严格意味着磁盘已经过载了,因为现代硬盘设备都有并行处理多个I/O请求的能力。要关注磁盘利用率,还需要关注await(再具体就是读r_await和写w_await指标),这个指标大致等于单个I/O所需的平均时间,所以如果它也很大,那磁盘一定是很繁忙了。

Which processes are using the specific disk?

实际场景中,面对磁盘负载高,我们通常需要做的是找到"罪魁祸首",判断其行为是否符合预期。

粗略的可以通过 iotop -oP 直接查看当前正在读写的进程。一般机器上有哪些程序,我们应该比较清楚,所以这时候可以大致判断出来:

$ 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 <目录>命令,通过正在打开的文件句柄来识别进程:

$ 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 进一步分析这些进程的读写情况 :

$ 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

kB_rd/skB_wr/s 这两个指标,能基本代表进程读写磁盘的速度。

Too many open files

相信后端同学大多都遇到过Too may open files的错误,因为高并发场景下,服务会建立很多连接,这时候就会很容易遇到这个错误。

可以通过ls -1 /proc/<pid>/fd | wc -l命令来查看当前进程已经打开了多少个文件:

$ ls -1 /proc/1705/fd | wc -l
1258

而若想查看某进程具体的句柄限制,可以通过命令cat /proc/<pid>/limits:

$ 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

而若要调整这个限制,可以通过ulimit命令或修改系统文件/etc/security/limits.conf.

EIO (input/output error)

遇到这个错误,一般是物理磁盘坏了。可能是整个盘坏了不能读写,也有可能是某个block有问题。这时候通过dmesg -T查看内核日志,通常会有相应的error信息。

参考资料

  1. http://linuxperf.com/?p=156
  2. http://linuxperf.com/?p=40
  3. https://man7.org/linux/man-pages/man1/pidstat.1.html
  4. https://engineering.saltside.se/linux-troubleshooting-disk-analysis-2dc40c6c49b4

Linux Troubleshooting 超实用系列 - Disk Analysis的更多相关文章

  1. linux磁盘管理系列-软RAID的实现

    1 什么是RAID RAID全称是独立磁盘冗余阵列(Redundant Array of Independent Disks),基本思想是把多个磁盘组合起来,组合一个磁盘阵列组,使得性能大幅提高. R ...

  2. linux磁盘管理系列-LVM的使用

    LVM是什么 LVM是Linux操作系统的逻辑卷管理器. 现在有两个Linux版本的LVM,分别是 LVM1,LVM2.LVM1是一种已经被认为稳定了几年的成熟产品,LVM2 是最新最好的LVM版本. ...

  3. linux磁盘管理系列三:LVM的使用

    磁盘管理系列 linux磁盘管理系列一:磁盘配额管理   http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_linux_040_quota.html l ...

  4. linux磁盘管理系列二:软RAID的实现

    磁盘管理系列 linux磁盘管理系列一:磁盘配额管理   http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_linux_040_quota.html l ...

  5. linux磁盘管理系列一:磁盘配额管理

    磁盘管理系列 linux磁盘管理系列一:磁盘配额管理   http://www.cnblogs.com/zhaojiedi1992/p/zhaojiedi_linux_040_quota.html l ...

  6. Linux 系统化学习系列文章总目录(持续更新中)

    本页内容都是本人系统化学习Linux 时整理出来的.这些文章中,绝大多数命令类内容都是翻译.整理man或info文档总结出来的,所以相对都比较完整. 本人的写作方式.风格也可能会让朋友一看就恶心到直接 ...

  7. Linux qemu-nbd mount qemu disk image

    Linux qemu-nbd mount qemu disk image deepin@deepin:~$ deepin@deepin:~$ qemu-nbd --help Usage: qemu-n ...

  8. Linux服务器部署系列之八—Sendmail篇

    Sendmail是目前Linux系统下面用得最广的邮件系统之一,虽然它存在一些不足,不过,目前还是有不少公司在使用它.对它的学习,也能让我们更深的了解邮件系统的运作.下面我们就来看看sendmail邮 ...

  9. Linux服务器部署系列之七—OpenLDAP篇

    LDAP(轻量级目录访问服务),通过配置这个服务,我们也可以在linux下面使用目录的形式管理用户,就像windows下面的AD一样,方便我们管理.下面我们就一起来配置openldap服务.本文运行环 ...

随机推荐

  1. ACM - 动态规划 - P1282 多米诺骨牌

    多米诺骨牌由上下 \(2\) 个方块组成,每个方块中有 \(1 \sim 6\) 个点.现有排成行的上方块中点数之和记为 \(S_1\),下方块中点数之和记为 \(S_2\),它们的差为 \(\lef ...

  2. Python - 数据存储与数据库简介

  3. Arduino 烧写bootloader

    什么是bootloader 一般情况下微处理器写入程序时都通过专门的编程器进行烧写,但是也可以通过在MCU中预先写入一些程序来实现某些基本功能,这些预先写入的程序代码就是bootloader.这样每次 ...

  4. Linux下的cman中文帮助手册配置

    Linux下的帮助命令man功能很强大,很好用,但显示的结果是英文,有时候看着还是吃力,就想着要是有man的中文显示结果该多好.网上搜寻一番后,终于找到解决方案,很简单,亲测有效.具体步骤如下: su ...

  5. turnjs fabricjs canvas 翻书

    最近做了一个翻书效果的项目, 来总结一下实现过程和遇到的一些问题, 供自己以后快速解决问题, 希望也能帮到同样遇到此类问题的同学, 如果有更好的方法,希望你能分享给我git地址 插件: Turn.js ...

  6. 《深入理解ES6》笔记——扩展对象的功能性(4)

    变量功能被加强了.函数功能被加强了,那么作为JavaScript中最普遍的对象,不加强对得起观众吗? 对象类别 在ES6中,对象分为下面几种叫法.(不需要知道概念) 1.普通对象 2.特异对象 3.标 ...

  7. 微信小程序版博客——开发汇总总结(附源码)

    花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...

  8. PHP基于Thinkphp5的砍价活动相关设计

    近期我们公司项目里陆陆续续有很多为了招引新用户的活动推出,砍价的活动由我来负责,我们的项目是在微信浏览器里供用户浏览访问. 大概描述:进入砍价活动列表页选择有意向的商品,用户点击商品图片可以看到WEB ...

  9. 用Python爬取斗鱼网站的一个小案例

    思路解析: 1.我们需要明确爬取数据的目的:为了按热度查看主播的在线观看人数 2.浏览网页源代码,查看我们需要的数据的定位标签 3.在代码中发送一个http请求,获取到网页返回的html(需要注意的是 ...

  10. java语言和jdk、jre基础

    Java语言平台 * J2SE(Java 2 Platform Standard Edition)标准版  * 是为开发普通桌面和商务应用程序提供的解决方案,该技术体系是其他两者的基础,可以完成一些桌 ...