在具有 EBS 卷的 AWS EC2 上运行的 MySQL 服务器上
iostat
返回以下内容
avg-cpu: %user %nice %system %iowait %steal %idle
37.67 0.00 5.26 0.75 0.08 56.24
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda1 2.08 2.54 48.01 430018 8121472
sdb 2.58 30.61 167.08 5177922 28261768
sdc 0.00 0.00 0.00 224 0
sdd 0.00 0.00 0.00 224 0
sde 0.00 0.00 0.00 224 0
sdf 25.27 230.56 537.18 38998842 90861888
对 MySQL 守护进程的进程 ID 进行调查,得到以下结果:
# cat /proc/10247/io
rchar: 8660581593
wchar: 938212302
syscr: 23487140
syscw: 557656
read_bytes: 1739915264
write_bytes: 383774720
cancelled_write_bytes: 349511680
第一个问题是这cancelled_write_bytes
看起来是否正常?这是否意味着底层 EBS 卷存在问题?
我的第二个问题是,在以 SELECT 为主的 DB 上,这个数字是否Blk_wrtn/s
高于这个数字是正常的。Blk_read/s
答案1
cancelled_write_bytes: 349511680
对我来说,这是由于截断造成的。如下所述:如果一个进程向文件写入 1MB,然后删除该文件,它实际上不会执行写出。但它将被视为导致 1MB 的写入。
mysql tmp 文件将被创建并相应地截断,这就是您看到那些取消的写入字节的原因。
看proc I/O 解释:cancelled_write_bytes
这里最大的错误是截断。如果一个进程向文件写入 1MB,然后删除该文件,它实际上不会执行写出。但它会被算作导致了 1MB 的写入。
换句话说:此过程通过截断页面缓存导致未发生的字节数。任务也可能导致“负”IO。如果此任务截断一些脏页面缓存,则另一个任务已考虑的一些 IO(在其 write_bytes 中)将不会发生。我们可以只需从截断任务的 write_bytes 中减去该值,但这样做会丢失信息。