Linux 磁盘IO 磁盘结构与数据存储方式, 数据是如何存储的,又通过怎样的方式被访问?
机械硬盘主要由磁盘盘片、磁头、主轴与传动轴等组成;数据就存放在磁盘盘片中
现代硬盘寻道都是采用CHS( Cylinder Head Sector )的方式,硬盘读取数据时,读写磁头沿径向移动,移到要读取的扇区所在磁道的上方 , 这段时间称为 寻道时间(seek time)。因读写磁头的起始位置与目标位置之间的距离不同,寻道时间也不同。磁头到达指定磁道后 , 然后通过盘片的旋转,使得要读取的扇区转到读写磁头的下方,这段时间称为 旋转延迟时间(rotational latencytime)。然后再读写数据,读写数据也需要时间,这段时间称为 传输时间(transfer time)。
固态硬盘主要由主控芯片、闪存颗粒与缓存组成;数据就存放在闪存芯片中
通过主控芯片进行寻址 , 因为是电信号方式, 没有任何物理结构,所以寻址速度非常快且与数据存储位置无关
如何查看系统IO状态
查看磁盘空间
调用 open ,fwrite 时到底发生了什么?
在一个IO过程中,以下5个API/系统调用是必不可少的
Create 函数用来打开一个文件,如果该文件不存在 , 那么需要在磁盘上创建该文件
Open 函数用于打开一个指定的文件 。如果在 Open 函数中指定 O_CREATE 标记,那么 Open 函数同样可以实现 Create 函数的功能
【linuxio命令 linux 命令】Clos e函数用于释放文件句柄
Write 和 Read 函数用于实现文件的读写过程
O_SYNC (先写缓存, 但是需要实际落盘之后才返回,如果接下来有读请求, 可以从内存读 ), write-through
O_DSYNC (D=data, 类似O_SYNC, 但是只同步数据, 不同步元数据)
O_DIRECT (直接写盘, 不经过缓存)
O_ASYNC (异步IO, 使用信号机制实现, 不推荐, 直接用aio_xxx)
O_NOATIME(读取的时候不更新文件 atime(access time))
sync()全局缓存写回磁盘
fsync()特定fd的sync()
fdatasync()只刷数据, 不同步元数据
mountnoatime(全局不记录atime), re方式(只读), sync(同步方式)
一个IO的传奇一生这里有一篇非常好的资料,讲述了整个IO过程;
下面简单记录下自己的理解的一次常见的Linux IO过程,想了解更详细及相关源码,非常推荐阅读上面的原文
Linux IO体系结构
[站外图片上传中...(image-38a7b-1644137945193)]
Superblock超级描述了整个文件系统的信息 。为了保证可靠性,可以在每个块组中对superblock进行备份 。为了避免superblock冗余过多,可以采用稀疏存储的方式,即在若干个块组中对superblock进行保存,而不需要在所有的块组中都进行备份
GDT 组描述符表组描述符表对整个组内的数据布局进行了描述 。例如,数据块位图的起始地址是多少?inode位图的起始地址是多少?inode表的起始地址是多少?块组中还有多少空闲块资源等 。组描述符表在superblock的后面
数据块位图数据块位图描述了块组内数据块的使用情况 。如果该数据块已经被某个文件使用,那么位图中的对应位会被置1,否则该位为0
Inode位图Inode位图描述了块组内inode资源使用情况 。如果一个inode资源已经使用,那么对应位会被置1
Inode表 (即inode资源)和数据块 。这两块占据了块组内的绝大部分空间,特别是数据块资源
一个文件是由inode进行描述的 。一个文件占用的数据块block是通过inode管理起来的。在inode结构中保存了直接块指针、一级间接块指针、二级间接块指针和三级间接块指针 。对于一个小文件,直接可以采用直接块指针实现对文件块的访问;对于一个大文件,需要采用间接块指针实现对文件块的访问
最简单的调度器 。它本质上就是一个链表实现的 fifo 队列,并对请求进行简单的 合并 处理 。
调度器本身并没有提供任何可以配置的参数
读写请求被分成了两个队列 , 一个用访问地址作为索引,一个用进入时间作为索引 , 并且采用两种方式将这些request管理起来;
在请求处理的过程中 , deadline算法会优先处理那些访问地址临近的请求 , 这样可以最大程度的减少磁盘抖动的可能性 。
只有在有些request即将被饿死的时候 , 或者没有办法进行磁盘顺序化操作的时候,deadline才会放弃地址优先策略,转而处理那些即将被饿死的request
deadline算法可调整参数
read_expire : 读请求的超时时间设置(ms) 。当一个读请求入队deadline的时候,其过期时间将被设置为当前时间+read_expire,并放倒fifo_list中进行排序
write_expire :写请求的超时时间设置(ms)
fifo_batch :在顺序(sort_list)请求进行处理的时候 , deadline将以batch为单位进行处理 。每一个batch处理的请求个数为这个参数所限制的个数 。在一个batch处理的过程中 , 不会产生是否超时的检查,也就不会产生额外的磁盘寻道时间 。这个参数可以用来平衡顺序处理和饥饿时间的矛盾,当饥饿时间需要尽可能的符合预期的时候,我们可以调小这个值,以便尽可能多的检查是否有饥饿产生并及时处理 。增大这个值当然也会增大吞吐量,但是会导致处理饥饿请求的延时变长
writes_starved :这个值是在上述deadline出队处理第一步时做检查用的 。用来判断当读队列不为空时,写队列的饥饿程度是否足够高,以时deadline放弃读请求的处理而处理写请求 。当检查存在有写请求的时候,deadline并不会立即对写请求进行处理,而是给相关数据结构中的starved进行累计,如果这是第一次检查到有写请求进行处理,那么这个计数就为1 。如果此时writes_starved值为2 , 则我们认为此时饥饿程度还不足够高,所以继续处理读请求 。只有当starved = writes_starved的时候 , deadline才回去处理写请求 。可以认为这个值是用来平衡deadline对读写请求处理优先级状态的,这个值越大 , 则写请求越被滞后处理,越?。辞肭缶驮娇梢曰竦们鹘诙燎肭蟮挠畔燃?
front_merges :当一个新请求进入队列的时候,如果其请求的扇区距离当前扇区很近,那么它就是可以被合并处理的 。而这个合并可能有两种情况,一个是向当前位置后合并,另一种是向前合并 。在某些场景下,向前合并是不必要的,那么我们就可以通过这个参数关闭向前合并 。默认deadline支持向前合并,设置为0关闭
在调度一个request时,首先需要选择一个一个合适的cfq_group 。Cfq调度器会为每个cfq_group分配一个时间片,当这个时间片耗尽之后,会选择下一个cfq_group 。每个cfq_group都会分配一个vdisktime,并且通过该值采用红黑树对cfq_group进行排序 。在调度的过程中,每次都会选择一个vdisktime最小的cfq_group进行处理 。
一个cfq_group管理了7棵service tree,每棵service tree管理了需要调度处理的对象cfq_queue 。因此,一旦cfq_group被选定之后,需要选择一棵service tree进行处理 。这7棵service tree被分成了三大类,分别为RT、BE和IDLE 。这三大类service tree的调度是按照优先级展开的
通过优先级可以很容易的选定一类Service tree 。当一类service tree被选定之后 , 采用service time的方式选定一个合适的cfq_queue 。每个Service tree是一棵红黑树,这些红黑树是按照service time进行检索的,每个cfq_queue都会维护自己的service time 。分析到这里,我们知道,cfq算法通过每个cfq_group的vdisktime值来选定一个cfq_group进行服务,在处理cfq_group的过程通过优先级选择一个最需要服务的service tree 。通过该Service tree得到最需要服务的cfq_queue 。该过程在 cfq_select_queue 函数中实现
一个cfq_queue被选定之后,后面的过程和deadline算法有点类似 。在选择request的时候需要考虑每个request的延迟等待时间,选择那种等待时间最长的request进行处理 。但是,考虑到磁盘抖动的问题 , cfq在处理的时候也会进行顺序批量处理,即将那些在磁盘上连续的request批量处理掉
cfq调度算法的参数
back_seek_max :磁头可以向后寻址的最大范围,默认值为16M
back_seek_penalty :向后寻址的惩罚系数 。这个值是跟向前寻址进行比较的
fifo_expire_async :设置异步请求的超时时间 。同步请求和异步请求是区分不同队列处理的,cfq在调度的时候一般情况都会优先处理同步请求,之后再处理异步请求,除非异步请求符合上述合并处理的条件限制范围内 。当本进程的队列被调度时,cfq会优先检查是否有异步请求超时,就是超过fifo_expire_async参数的限制 。如果有,则优先发送一个超时的请求 , 其余请求仍然按照优先级以及扇区编号大小来处理
fifo_expire_sync :这个参数跟上面的类似,区别是用来设置同步请求的超时时间
slice_idle :参数设置了一个等待时间 。这让cfq在切换cfq_queue或service tree的时候等待一段时间,目的是提高机械硬盘的吞吐量 。一般情况下,来自同一个cfq_queue或者service tree的IO请求的寻址局部性更好,所以这样可以减少磁盘的寻址次数 。这个值在机械硬盘上默认为非零 。当然在固态硬盘或者硬RAID设备上设置这个值为非零会降低存储的效率,因为固态硬盘没有磁头寻址这个概念 , 所以在这样的设备上应该设置为0,关闭此功能
group_idle :这个参数也跟上一个参数类似,区别是当cfq要切换cfq_group的时候会等待一段时间 。在cgroup的场景下 , 如果我们沿用slice_idle的方式,那么空转等待可能会在cgroup组内每个进程的cfq_queue切换时发生 。这样会如果这个进程一直有请求要处理的话,那么直到这个cgroup的配额被耗尽 , 同组中的其它进程也可能无法被调度到 。这样会导致同组中的其它进程饿死而产生IO性能瓶颈 。在这种情况下,我们可以将slice_idle = 0而group_idle = 8 。这样空转等待就是以cgroup为单位进行的,而不是以cfq_queue的进程为单位进行,以防止上述问题产生
low_latency :这个是用来开启或关闭cfq的低延时(low latency)模式的开关 。当这个开关打开时,cfq将会根据target_latency的参数设置来对每一个进程的分片时间(slice time)进行重新计算 。这将有利于对吞吐量的公平(默认是对时间片分配的公平) 。关闭这个参数(设置为0)将忽略target_latency的值 。这将使系统中的进程完全按照时间片方式进行IO资源分配 。这个开关默认是打开的
target_latency :当low_latency的值为开启状态时 , cfq将根据这个值重新计算每个进程分配的IO时间片长度
quantum :这个参数用来设置每次从cfq_queue中处理多少个IO请求 。在一个队列处理事件周期中,超过这个数字的IO请求将不会被处理 。这个参数只对同步的请求有效
slice_sync :当一个cfq_queue队列被调度处理时,它可以被分配的处理总时间是通过这个值来作为一个计算参数指定的 。公式为: time_slice = slice_sync(slice_sync/5 * (4 - prio)) 这个参数对同步请求有效
slice_async :这个值跟上一个类似 , 区别是对异步请求有效
slice_async_rq :这个参数用来限制在一个slice的时间范围内,一个队列最多可以处理的异步请求个数 。请求被处理的最大个数还跟相关进程被设置的io优先级有关
通常在Linux上使用的IO接口是同步方式的,进程调用 write / read 之后会阻塞陷入到内核态,直到本次IO过程完成之后,才能继续执行,下面介绍的异步IO则没有这种限制,但是当前Linux异步IO尚未成熟
目前Linux aio还处于较不成熟的阶段 , 只能在 O_DIRECT 方式下才能使用(glibc_aio),也就是无法使用默认的Page Cache机制
正常情况下 , 使用aio族接口的简要方式如下:
io_uring 是 2019 年 5 月发布的 Linux 5.1 加入的一个重大特性 —— Linux 下的全新的异步 I/O 支持,希望能彻底解决长期以来 Linux AIO 的各种不足
io_uring 实现异步 I/O 的方式其实是一个生产者-消费者模型:
逻辑卷管理
RAID0
RAID1
RAID5(纠错)
条带化
Linux系统性能调整:IO过程
Linux的IO调度
一个IO的传奇一生
理解inode
Linux 文件系统是怎么工作的?
Linux中Buffer cache性能问题一探究竟
Asynchronous I/O and event notification on linux
AIO 的新归宿:io_uring
Linux 文件 I/O 进化史(四):io_uring —— 全新的异步 I/O
linux查看磁盘io的几种方法linux查看磁盘io的几种方法
怎样才能快速的定位到并发高是由于磁盘io开销大呢?可以通过三种方式:
第一种:用 top 命令 中的cpu 信息观察
Top可以看到的cpu信息有:
Tasks: 29 total, 1 running, 28 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.3% us, 1.0% sy, 0.0% ni, 98.7% id, 0.0% wa, 0.0% hi, 0.0% si
具体的解释如下:
Tasks: 29 total 进程总数
1 running 正在运行的进程数
28 sleeping 睡眠的进程数
0 stopped 停止的进程数
0 zombie 僵尸进程数
Cpu(s):
0.3% us 用户空间占用CPU百分比
1.0% sy 内核空间占用CPU百分比
0.0% ni 用户进程空间内改变过优先级的进程占用CPU百分比
98.7% id 空闲CPU百分比
0.0% wa 等待输入输出的CPU时间百分比
0.0% hi
0.0% si
0.0% wa 的百分比可以大致的体现出当前的磁盘io请求是否频繁 。如果 wa的数量比较大,说明等待输入输出的的io比较多 。
第二种:用vmstat
vmstat 命令报告关于线程、虚拟内存、磁盘、陷阱和 CPU 活动的统计信息 。由 vmstat 命令生成的报告可以用于平衡系统负载活动 。系统范围内的这些统计信息(所有的处理器中)都计算出以百分比表示的平均值 , 或者计算其总和 。
输入命令:
vmstat 2 5
如果发现等待的进程和处在非中断睡眠状态的进程数非常多,并且发送到块设备的块数和从块设备接收到的块数非常大,那就说明磁盘io比较多 。
vmstat参数解释:
Procs
r: 等待运行的进程数 b: 处在非中断睡眠状态的进程数 w: 被交换出去的可运行的进程数 。此数由 linux 计算得出,但 linux 并不耗尽交换空间
Memory
swpd: 虚拟内存使用情况,单位:KB
free: 空闲的内存 , 单位KB
buff: 被用来做为缓存的内存数,单位:KB
Swap
si: 从磁盘交换到内存的交换页数量,单位:KB/秒
so: 从内存交换到磁盘的交换页数量,单位:KB/秒
IO
bi: 发送到块设备的块数,单位:块/秒
bo: 从块设备接收到的块数 , 单位:块/秒
System
in: 每秒的中断数,包括时钟中断
cs: 每秒的环境(上下文)切换次数
CPU
按 CPU 的总使用百分比来显示
us: CPU 使用时间
sy: CPU 系统使用时间
id: 闲置时间
准测
更多vmstat使用信息
第二种:用iostat
安装:
Iostat 是 sysstat 工具集的一个工具 , 需要安装 。
Centos的安装方式是:
yum install sysstat
Ubuntu的安装方式是:
aptitude install sysstat
使用:
iostat -dx 显示磁盘扩展信息
root@fileapp:~# iostat -dx
r/s 和 w/s 分别是每秒的读操作和写操作,而rKB/s 和wKB/s 列以每秒千字节为单位显示了读和写的数据量
如果这两对数据值都很高的话说明磁盘io操作是很频繁 。
linux wa%过高,iostat查看io状况
1, 安装iostat
yum install sysstat
之后就可以使用 iostat 命令了,
2 , 入门使用
iostat -d -k 2
参数 -d 表示,显示设备(磁盘)使用状态;-k某些使用block为单位的列强制使用Kilobytes为单位;2表示,数据显示每隔2秒刷新一次 。
tps:该设备每秒的传输次数(Indicate the number of transfers per second that were issued to the device.) 。"一次传输"意思是"一次I/O请求" 。多个逻辑请求可能会被合并为"一次I/O请求" 。"一次传输"请求的大小是未知的 。kB_read/s:每秒从设备(drive expressed)读取的数据量;
kB_wrtn/s:每秒向设备(drive expressed)写入的数据量;
kB_read:读取的总数据量;kB_wrtn:写入的总数量数据量;这些单位都为Kilobytes 。
指定监控的设备名称为sda,该命令的输出结果和上面命令完全相同 。
iostat -d sda 2
默认监控所有的硬盘设备,现在指定只监控sda 。
3, -x 参数
iostat还有一个比较常用的选项 -x ,该选项将用于显示和io相关的扩展数据 。
iostat -d -x -k 1 10
输出信息的含义
。
4, 常见用法
iostat -d -k 1 10#查看TPS和吞吐量信息(磁盘读写速度单位为KB)
iostat -d -m 2#查看TPS和吞吐量信息(磁盘读写速度单位为MB)
iostat -d -x -k 1 10#查看设备使用率(\util)、响应时间(await) iostat -c 1 10 #查看cpu状态
5, 实例分析
iostat -d -k 1 | grep vda
Device:tpskB_read/skB_wrtn/skB_readkB_wrtn
sda1060.7218.9571.53395637647 1493241908
sda10299.024266.67129.414352132
sda10483.844589.904117.1745444076
sda10218.003360.00100.003360100
sda10546.008784.00124.008784124
sda10827.0013232.00136.0013232136
上面看到 , 磁盘每秒传输次数平均约400;每秒磁盘读取约5MB,写入约1MB 。
iostat -d -x -k 1
Device:rrqm/s wrqm/sr/sw/srsec/swsec/srkB/swkB/s avgrq-sz avgqu-szawaitsvctm\util
sda1.5628.317.84 31.5043.653.1621.821.581.190.030.802.6110.29
sda1.9824.75 419.806.93 13465.35253.476732.67126.7332.152.004.702.0085.25
sda3.0641.84 444.90 54.08 14204.08 2048.987102.041024.4932.572.104.211.8592.24
可以看到磁盘的平均响应时间5ms,磁盘使用率80 。磁盘响应正常,但是已经很繁忙了 。
可以看到磁盘的平均响应时间5ms,磁盘使用率90 。磁盘响应正常,但是已经很繁忙了 。
await:每一个IO请求的处理的平均时间(单位是微秒毫秒) 。这里可以理解为IO的响应时间 , 一般地系统IO响应时间应该低于5ms , 如果大于10ms就比较大了
svctm表示平均每次设备I/O操作的服务时间(以毫秒为单位) 。如果svctm的值与await很接近,表示几乎没有I/O等待,磁盘性能很好,
如果await的值远高于svctm的值,则表示I/O队列等待太长,系统上运行的应用程序将变慢 。
\util: 在统计时间内所有处理IO时间,除以总共统计时间
所以该参数暗示了设备的繁忙程度
。一般地,如果该参数是100%表示设备已经接近满负荷运行了(当然如果是多磁盘,即使\util是100%,因为磁盘的并发能力,所以磁盘使用未必就到了瓶颈) 。
也可以使用下面的命令,同时显示cpu和磁盘的使用情况
等待时间超过5ms, 磁盘io有问题
linux系统如何查看网络IO?首先 、用top命令查看
top - 16:15:05 up 6 days,6:25,2 users,load average: 1.45, 1.77, 2.14
Tasks: 147 total,1 running, 146 sleeping,0 stopped,0 zombie
Cpu(s):0.2% us,0.2% sy,0.0% ni, 86.9% id, 12.6% wa,0.0% hi,0.0% si
Mem:4037872k total,4003648k used,34224k free,5512k buffers
Swap:7164948k total,629192k used,6535756k free,3511184k cached
查看12.6% wa
IO等待所占用的CPU时间的百分比,高过30%时IO压力高
其次、 用iostat -x 1 10
avg-cpu:\user%nice%sys %iowait%idle
0.000.000.2533.4666.29
Device:rrqm/swrqm/sr/sw/srsec/swsec/srkB/swkB/s avgrq-sz avgqu-szawaitsvctm\util
sda0.000.000.000.000.000.000.000.000.000.000.000.000.00
sdb0.00112217.009.00192.00 9216.0096.004608.00123.79137.23 1033.4313.17 100.10
sdc0.000.000.000.000.000.000.000.000.000.000.000.000.00
查看\util 100.10 %idle 66.29
如果 \util 接近 100%,说明产生的I/O请求太多 , I/O系统已经满负荷,该磁盘可能存在瓶颈 。
idle小于70% IO压力就较大linuxio命令了,一般读取速度有较多的wait.
同时可以结合vmstat 查看查看b参数(等待资源的进程数)
vmstat -1
如果你想对硬盘做一个IO负荷的压力测试可以用如下命令
time dd if=/dev/zero bs=1M count=2048 of=direct_2G
此命令为在当前目录下新建一个2G的文件
linuxio命令我们在新建文件夹的同时来测试IO的负荷情况 。
如何找出Linux系统高IO的思路总结前言
I/O Wait是一个需要使用高级的工具来debug问题原因 , 当然也有许多基本工具的高级用法 。I/O wait的问题难以定位的原因是linuxio命令:因为linuxio命令我们有很多工具可以告诉你I/O 受限linuxio命令了,但是并没有告诉你具体是哪个进程引起的 。
1. 如何确认,是否是I/O问题导致系统缓慢
确认是否是I/O导致的系统缓慢我们可以使用多个命令,但是,最简单的是unix的命令 top
# top
top - 14:31:20 up 35 min, 4 users, load average: 2.25, 1.74, 1.68
Tasks: 71 total, 1 running, 70 sleeping, 0 stopped, 0 zombie
Cpu(s): 2.3\us, 1.7%sy, 0.0%ni, 0.0%id, 96.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 245440k total, 241004k used, 4436k free, 496k buffers
Swap: 409596k total, 5436k used, 404160k free, 182812k cached
从CPU这行,可以发现CPU的io waitlinuxio命令;这里是96.0% 。越高就代表CPU用于io wait的资源越多 。
2. 找出哪个磁盘正在被写入
上边的top命令从一个整体上说明了I/O wait , 但是并没有说明是哪块磁盘影响的,想知道是哪块磁盘引发的问题,可以使用另外一个命令 iostat 命令
$ iostat -x 2 5
avg-cpu: \user %nice %system %iowait %steal %idle
3.66 0.00 47.64 48.69 0.00 0.00
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 44.50 39.27 117.28 29.32 11220.94 13126.70 332.17 65.77 462.79 9.80 2274.71 7.60 111.41
dm-0 0.00 0.00 83.25 9.95 10515.18 4295.29 317.84 57.01 648.54 16.73 5935.79 11.48 107.02
dm-1 0.00 0.00 57.07 40.84 228.27 163.35 8.00 93.84 979.61 13.94 2329.08 10.93 107.02
iostat 会每2秒更新一次,一共打印5次信息,-x 的选项是打印出扩展信息
第一个iostat 报告会打印出系统最后一次启动后的统计信息,这也就是说,在多数情况下 , 第一个打印出来的信息应该被忽略,剩下的报告,都是基于上一次间隔的时间 。举例子来说,这个命令会打印5次 , 第二次的报告是从第一次报告出来一个后的统计信息,第三次是基于第二次 ,依次类推
所以,一定记?。旱谝桓龊雎裕?
在上面的例子中,sda的\utilized 是111.41%,这个很好的说明了有进程正在写入到sda磁盘中 。
除了\utilized 外,我们可以从iostat得到更加丰富的资源信息 , 例如每毫秒读写请求(rrqm/swrqm/s)),每秒读写的((r/sw/s) 。在上边的例子中 , 我们的项目看起来正在读写非常多的信息 。这个对我们查找相应的进程非常有用 。
3. 找出导致高IO的进程
# iotop
Total DISK READ: 8.00 M/s | Total DISK WRITE: 20.36 M/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO COMMAND
15758 be/4 root 7.99 M/s 8.01 M/s 0.00 % 61.97 % bonnie-n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
最简单的方法就是用iotop找出哪个进程用了最多的存储资源,从上面可以看到是bonnie。
iotop很好用,但是不是默认安装的 。
如果没有iotop,下面的方式也可以让你有种方法缩小范围,尽快找到是哪个进程 。
ps 命令对内存和CPU有一个统计 , 但是他没有对磁盘I/O的统计,虽然他没有显示磁盘I/O,但是它显示进行的状态,我们可以用来知道一个进程是否正在等待I/O
主要的进程状态有:
PROCESS STATE CODES
D uninterruptible sleep (usually IO)
R running or runnable (on run queue)
S interruptible sleep (waiting for an event to complete)
T stopped, either by a job control signal or because it is being traced.
W paging (not valid since the 2.6.xx kernel)
X dead (should never be seen)
Z defunct ("zombie") process, terminated but not reaped by its parent.
等待I/O的进程的状态一般是“uninterruptible sleep” , 或者“D”,我们可以很容易的查找到正在等待I/O的进程
# for x in `seq 1 1 10`; do ps -eo state,pid,cmd | grep "^D"; echo "----"; sleep 5; done
D 248 [jbd2/dm-0-8]
D 16528 bonnie-n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
----
D 22 [kswapd0]
D 16528 bonnie-n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
----
D 22 [kswapd0]
D 16528 bonnie-n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
----
D 22 [kswapd0]
D 16528 bonnie-n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
----
D 16528 bonnie-n 0 -u 0 -r 239 -s 478 -f -b -d /tmp
上边的例子会循环的输出状态是D的进程,每5秒一次,一共10次
从输出我们可以知道 bonnie的pid是16528 ,在waiting,bonnie看起来就是我们想找到的进程,但是,只是从它的状态,我们没有办法证明就是bonnie引起的I/O等待 。
为了证明,我们可以可以查看/proc,每个进程目录下都有一个叫io的文件,里边保存这和iotop类似的信息 。
# cat /proc/16528/io
rchar: 48752567
wchar: 549961789
syscr: 5967
syscw: 67138
read_bytes: 49020928
write_bytes: 549961728
cancelled_write_bytes: 0
read_bytes和write_bytes是这个进程从磁盘读写的字节,在这个例子中,bonnie进程读取了46M的数据并且写入了524MB的数据到磁盘上 。
4. 找出哪个文件正在被大量写入
lsof 命令可以展示一个进程打开的所有文件 。从这个列表中 , 我们可以找到哪个文件被写入 。
# lsof -p 16528
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
bonnie16528 root cwd DIR 252,0 4096 130597 /tmp
truncated
bonnie16528 root 8u REG 252,0 501219328 131869 /tmp/Bonnie.16528
bonnie16528 root 9u REG 252,0 501219328 131869 /tmp/Bonnie.16528
bonnie16528 root 10u REG 252,0 501219328 131869 /tmp/Bonnie.16528
bonnie16528 root 11u REG 252,0 501219328 131869 /tmp/Bonnie.16528
bonnie16528 root 12u REG 252,0 501219328 131869 strong/tmp/Bonnie.16528/strong
# df /tmp
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/mapper/workstation-root 7667140 2628608 4653920 37% /
# pvdisplay
--- Physical volume ---
PV Name /dev/sda5
VG Name workstation
PV Size 7.76 GiB / not usable 2.00 MiB
Allocatable yes
PE Size 4.00 MiB
Total PE 1986
Free PE 8
Allocated PE 1978
PV UUID CLbABb-GcLB-l5z3-TCj3-IOK3-SQ2p-RDPW5S
使用pvdisplay可以看到,pv设备就是/dev/sda5,正是我们前面找到的sda 。
参考文档:
关于linuxio命令和linux 命令的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息 , 记得收藏关注本站 。
推荐阅读
- 直播软件不用认证,直播不用认证的软件
- 关于html5怎么设置句间隔的信息
- thewordis有什么区别,the world 和world区别
- 电脑已分好的硬盘怎么添加,给电脑增加一个已经分区的硬盘
- vb.net互换字节 vbnet byte转成string
- 旅行社如何推广餐厅酒店,旅行社如何推广餐厅酒店管理
- java打印红心代码,java打印星星
- 日本网红摔倒视频直播,日本网红摔倒视频直播
- go语言做嵌入式 go嵌入式开发