磁盘I/O使用率高的问题 问题描述 磁盘I/O使用率高或100%。 可能原因 SQL执行慢或无响应; 数据库运行异常。 解决步骤 1. 可以通过iostat命令查看磁盘IO情况,重点关注until和svctm这两个值 svctm:The average service time (in milliseconds) for I/O requests that were issued to the device. Warning! Do not trust this field any more. This field will be removed in a future sysstat version. %util:Percentage of elapsed time during which I/O requests were issued to the device (bandwidth utilization for the device). Device saturation occurs when this value is close to 100%. > 执行命令: > iostat x k d 1 > 返回结果示例: > 其中每列说明如下: rrqm/s: 每秒进行 merge 的读操作数目。即 rmerge/s wrqm/s: 每秒进行 merge 的写操作数目。即 wmerge/s r/s: 每秒完成的读 I/O 设备次数。即 rio/s w/s: 每秒完成的写 I/O 设备次数。即 wio/s rkB/s: 每秒读K字节数。是 rsect/s 的一半,因为每扇区大小为512字节。 wkB/s: 每秒写K字节数。是 wsect/s 的一半。 avgrqsz: 平均每次设备I/O操作的数据大小 (扇区)。 avgqusz: 平均I/O队列长度。 rsec/s: 每秒读扇区数。即 rsect/s wsec/s: 每秒写扇区数。即 wsect/s rawait:每个读操作平均所需的时间,不仅包括硬盘设备读操作的时间,还包括了在kernel队列中等待的时间。 wawait:每个写操作平均所需的时间,不仅包括硬盘设备写操作的时间,还包括了在kernel队列中等待的时间。 await: 平均每次设备I/O操作的等待时间 (毫秒)。 svctm: 平均每次设备I/O操作的服务时间 (毫秒)。 %util: 一秒中有百分之多少的时间用于 I/O 操作,即被io消耗的cpu百分比 > 返回结果分析: > > > 如果 svctm 比较接近 await,说明 I/O 几乎没有等待时间;如果 await 远大于 svctm,说明I/O 队列太长,io响应太慢,则需要进行必要优化。如果avgqusz比较大,也表示有大量io在等待。 注意 iostat 中的 %util 基本已经没有任何作用了,svctm也没什么参考意义,%util表示该设备有I/O(即非空闲)的时间比率,不考虑I/O有多少,只考虑有没有。 由于现代硬盘设备都有并行处理多个I/O请求的能力,所以%util即使达到100%也不意味着设备饱和了。 举个简化的例子:某硬盘处理单个I/O需要0.1秒,有能力同时处理10个I/O请求,那么当10个I/O请求依次顺序提交的时候,需要1秒才能全部完成,在1秒的采样周期里%util达到100%;而如果10个I/O请求一次性提交的话,0.1秒就全部完成,在1秒的采样周期里%util只有10%。可见,即使%util高达100%,硬盘也仍然有可能还有余力处理更多的I/O请求,即没有达到饱和状态。 2. 可以通过nmon工具分析,具体参见 > nmon返回结果中,关注Disk I/O中 Busy列判断磁盘是否达到饱和状态; > > 3. 或者通过dstat、sar来查看磁盘I/O情况 4. TeleDB数据库常见磁盘I/O使用率高的问题及解决办法: 1)大批量写入/更新操作,占用大量磁盘I/O; 解决办法: a、分析写入/更新逻辑,排查WAL日志写入占比,通过优化写入/更新逻辑,降低WAL日志写入量; b、操作系统CPU充足的情况下,可设置WAL日志压缩策略; 2)高并发SQL语句执行效率低,产生大量I/O,导致磁盘I/O、CPU升高; 解决办法:优化SQL语句,尤其是并发量大、高频的SQL语句,通常通过创建索引减少大表全表扫描,改写SQL关联逻辑等方式优化; 3)磁盘性能不足 解决办法:不使用HDD机械盘,推荐使用NVMe SSD盘,并做raid,提升磁盘性能; 4)shardbuffer、操作系统内存不足,导致频繁的磁盘I/O; 解决办法:操作系统应该保持充足的内存,有更多可用缓存(shardbuffer、操作系统cache),同时调整相关参数,适当拉长checkpoint频率,减少磁盘I/O。