本文共 1078 字,大约阅读时间需要 3 分钟。
有个MySQL服务器的磁盘I/O总有过高报警,怎么回事?
最近收到小明的来信,说他的MySQL服务器磁盘I/O总是很高。作为一个经验丰富的DBA,我首先想到的就是排查可能导致磁盘I/O高的原因。通常来说,磁盘I/O高可能是由于以下几个原因:磁盘设备性能差、文件系统不支持高IOPS、SQL查询效率低、或者内存不足,导致更多的磁盘读写。
小明的MySQL服务器使用了RAID10阵列,由多块SSD组成,理论上性能应该不错。但监控数据显示IOPS和%util并没有很高,排除了硬件问题。接下来,我检查了文件系统和IO调度。小明使用的是XFS文件系统,IO调度是noop,这些都不是问题,因为noop调度在最新的系统中表现不错。此外,iostat显示IOPS不算低,说明硬件性能没有问题。
然后,我查看了进程列表和慢查询日志,发现没有明显的慢查询,这排除了SQL效率低的可能性。接下来,我关注到了内存使用情况。服务器物理内存是64GB,用free命令查看,发现大部分内存都在缓存中,空闲内存不多。内存不足可能导致更多的磁盘读写,所以接下来我需要详细检查InnoDB的内存配置。
InnoDB的缓冲池大小为18GB,内存只有64GB,缓冲池占了大部分内存,可能不够用。特别是当InnoDB需要频繁读取或写入数据时,缓冲池可能无法及时更新,导致磁盘I/O增加。我还查看了InnoDB的状态,发现unpurge列表有111万条,这意味着有大量的数据需要被刷新到磁盘,进一步加重了磁盘负载。
此外,我发现InnoDB_row_lock_current_waits的值异常高达18,446,744,073,709,551,615,这显然不可能。实际上,这种现象已经被官方报告过一次,问题ID是#71520。这可能是由于InnoDB内部的某些锁管理问题,或者是系统配置的问题。
为了解决这些问题,我调整了以下参数:将InnoDB缓冲池大小设置为40GB,不超过物理内存的70%。同时,调大了innodb-purge-thread的值,原来是1,调整成4;调大了innodb_io_capacity和innodb_io_capacity_max,值分别为2万和2.5万。
调整完成后,重启了MySQL实例。观察到磁盘I/O告警减少,InnoDB_buffer_pool_wait_free一直为0,unpurge列表也大幅减少。这些调整有效地缓解了磁盘压力,问题得到了解决。
最后,我意识到内存不足和InnoDB缓冲池配置不当是主要原因,及时的调整和监控是解决类似问题的关键。
转载地址:http://fqh.baihongyu.com/