我正在为 MySQL 表建立索引。它会给该计算机带来很高的负载。
这似乎是由于高 iowait 造成的。但也表明wMB/s仅为2.87。
即使是普通的 SATA HDD 也不能处理超过 2.87MB/s 的速度吗?那么为什么进程这么慢呢?
iostat -x
报告:
avg-cpu: %user %nice %system %iowait %steal %idle
1.74 0.00 3.48 47.51 0.00 47.26
Device: rrqm/s wrqm/s r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await svctm %util
sda 0.00 300.00 0.00 383.00 0.00 2.87 15.35 142.00 374.64 2.61 99.90
sdb 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
scd0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
sdc 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
dm-0 0.00 0.00 0.00 2507.00 0.00 9.79 8.00 263.88 110.06 0.40 99.90
dm-1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
dm-2 0.00 0.00 0.00 2.00 0.00 0.01 8.00 0.41 196.00 202.50 40.50
dm-3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
答案1
您正在执行小型随机写入,这几乎是在旋转磁盘上可以执行的最慢的操作,所以我想说您的吞吐量满足(我的)期望。
您的avgrq-sz
大小是 15.35,这意味着您的平均请求是 15.35 x SATA 磁盘的扇区大小(最常见的是 512 字节,但在非常新的 SATA 磁盘上可能是 4096 字节),因此您要写入 15.35 x 512 字节 = 7,859.2 字节(平均)每个请求iostat
乘以报告的每秒 383 次写入,得到 3,010,073.6 字节(我们乘以平均值,因此这就是 0.6 字节的来源)。而 3,010,073.6 字节/秒就是 2.87MB/s。
每秒可以执行的写入次数取决于磁盘需要移动磁头的量,但粗略地说,您正在接近设备每秒可以执行的最大写入次数。
当您将每秒少量写入与大量写入结合起来时,旋转磁盘上的写入速度会更高avgrq-sz
。
如果这对您来说是一个关键的性能问题,我建议您研究各种 SSD 选项,这些选项通常会在此类工作负载上提供更好的性能。
答案2
您需要iostat
在监控过程中运行多次,以真实了解正在发生的情况。那,或者使用类似的工具仙人掌为您保留一段时间内的此类统计数据,以便您可以查看历史图表。
最有可能发生的情况是,由于数据库表扫描,磁盘也在进行大量读取,而iostat
您发布的运行恰好是在 DBMS 正在写入而不是读取时完成的。在硬盘上,写入和读取交错的速度非常慢,因为它涉及查找,这是硬盘驱动器执行的最慢的操作。如果您听一下硬盘驱动器的声音,您可能会听到它在对硬盘的不同部分快速交替写入和读取时疯狂地发出嘎嘎声。
为了使这个进程以您期望的两位数 MByte/s 的速率运行,您必须将进程分成两部分,在进行表扫描时在 RAM 中构建索引,然后写出完整的索引。 MySQL 是高度优化的软件,因此如果可以这样做,我希望它会,因为它不是,所以它不能。也就是说,它可能没有足够的 RAM 来执行此操作。这要么意味着您的机器中没有足够的物理 RAM 让 MySQL 部分包含完整的索引,要么意味着您没有在 MySQL 配置文件中为其提供足够高的系统 RAM 部分。然而,调优 MySQL 是另一个论坛的主题。