Xupeng's blog

圆外之大,心向往之

2.6.38 / 2.6.39 + XFS 的性能极差

线上的 MySQL 服务器一直都在使用 XFS 文件系统,性能和稳定性都表现良好,使用的内核版本是 2.6.29,经过时间和访问压力的验证,表现也不错。

前一段时间在测试几款 SSD 产品,考虑到 XFS 在内核 2.6.38 之后才加入了对 FITRIM 的支持(ref1 ref2),就在 2.6.38 和 2.6.39 上对 SSD 做了测试,测试结果却让人大跌眼镜,XFS 在 2.6.38 和 2.6.39 之上的性能差到完全不能接受。

我在内核 2.6.29 和 2.6.39 下使用 fio 分别对 raw device、XFS 和 ext4 做了一个简单的 IO 测试,测试参数是这样的:

1
2
3
fio --filename=$PATH-TO-TEST-FILE --direct=1 --rw=randrw --bs=16k \
    --size=50G --numjobs=16 --runtime=120 --group_reporting \
    --name=test --rwmixread=90 --thread --ioengine=psync

大意是:使用 non-buffered I/O,16 个并发 IO 线程,做 16KB 块大小的随机读写混合测试,读写比为 9:1

下面是 2.6.29 下的测试结果:

可以看到,ext4, XFS 和 raw device 的 IOPS 都在 12000 上下,考虑到测试之间会有误差,基本可以认为三者的性能一样。

下面是 2.6.39 下的测试结果:

ext4 和 raw device 的 IOPS 约为 12900,比在 2.6.29 下略有提升,但是 XFS 的性能就有点惨不忍睹了,竟然只有不到 4000。

尝试了很多种不同的 XFS 格式化、mount 参数,IOPS 都只是在 4000 左右徘徊,还没有找到解决方案,目前在部分服务器上尝试使用了 ext4,进一步监测 ext4 的性能和稳定性,或许未来会在数据库服务器上全部使用 ext4。

更新:在 XFS 邮件列表咨询之后,确认了这是 XFS 的已知 bug:

commit 686da49e5aa50117d8d824c579c3fd9e0318fbc6
Author: Dave Chinner
Date: Thu Dec 1 17:27:39 2011 -0600

xfs: don’t serialise direct IO reads on page cache checks

commit 0c38a2512df272b14ef4238b476a2e4f70da1479 upstream.

There is no need to grab the i_mutex of the IO lock in exclusive
mode if we don’t need to invalidate the page cache. Taking these
locks on every direct IO effective serialises them as taking the IO
lock in exclusive mode has to wait for all shared holders to drop
the lock. That only happens when IO is complete, so effective it
prevents dispatch of concurrent direct IO reads to the same inode.

Fix this by taking the IO lock shared to check the page cache state,
and only then drop it and take the IO lock exclusively if there is
work to be done. Hence for the normal direct IO case, no exclusive
locking will occur.

3.0.11, 3.1.5 和 3.2-rc1 中已经修复。XFS 用户在升级内核时需要注意,升级到修复后的版本,并做充分的性能测试。

Comments