XFS对MySQL写入吞吐更友好,因其分配组(AG)机制支持并行元数据操作,而EXT4全局锁易成瓶颈;但XFS不支持在线缩容,且AG耗尽会导致写失败,需合理设置agcount。

XFS 对 MySQL 的写入吞吐更友好
MySQL 在高并发写入(尤其是 INSERT、UPDATE 大量行,或 binlog / redo log 持续刷盘)时,XFS 的延迟抖动更小、吞吐更稳。这不是玄学——XFS 的分配组(AG)机制天然支持并行元数据操作,而 EXT4 的全局 ext4_super_block 锁在重负载下容易成为瓶颈。
实操建议:
- 若实例以写为主(如订单库、日志归档库),优先选 XFS;
- EXT4 仍可胜任中小负载,但需确认已禁用
barrier=1(新版内核默认关闭,老版本需在挂载参数加barrier=0); - XFS 不支持在线 shrink(缩容),扩容虽支持但需先
xfs_growfs,这点比 EXT4 灵活度低; - 别迷信 “XFS 更快” —— 如果你的 workload 是大量小文件随机读(比如 mysqldump 临时导出目录),EXT4 的 extent tree 可能反而响应更快。
EXT4 的 journal 模式直接影响 crash-safe 行为
EXT4 默认用 data=ordered,它不记录数据块本身,只保证元数据和文件内容的提交顺序。MySQL 依赖自身 innodb_flush_log_at_trx_commit=1 和 sync_binlog=1 实现 ACID,此时 EXT4 的 journal 模式实际不参与事务持久化决策——但一旦设成 data=writeback,就可能丢事务(尤其断电时)。
常见错误现象:
- 服务器异常掉电后,MySQL 启动报
InnoDB: Database page corruption on disk或无法 recover; - binlog 有记录,但 InnoDB 表数据缺失(
data=writeback+ 未配innodb_doublewrite=ON);
实操建议:
- 始终用
data=ordered(默认值,无需显式指定); - 绝对不要用
data=writeback; - 如果追求极致性能且能接受极小概率数据不一致,可考虑
data=journal,但会显著拖慢写入——MySQL 自身已做日志双写,纯属冗余。
XFS 的 mount 选项对 MySQL 性能影响明显
XFS 默认挂载行为偏保守,几个关键选项不调,InnoDB 的预写日志(redo log)和 buffer pool 刷脏页容易被卡住。
实操建议:
- 必须加
nobarrier:XFS 默认开启 barrier,但现代 SSD/NVMe 已内置掉电保护,开 barrier 只增延迟不增安全; - 推荐加
noatime,inode64:noatime避免每次 SELECT 更新访问时间戳;inode64允许 inode 分布在整个磁盘而非仅前 1TB,避免大容量盘上 inode 分配争用; - 慎用
logbsize:默认 256K,若 redo log 文件远大于此(如 2G),可设logbsize=256k对齐,但多数场景无感; - 别碰
swalloc:它本意是优化交换分区,对 MySQL 数据文件无效,还可能干扰预分配逻辑。
df -h 看似空闲,但 XFS 的 free space 可能“不可用”
XFS 的空间分配是按 allocation group(AG)进行的,即使 df -h 显示还有 30% 空间,若某个 AG 耗尽,INSERT 就可能突然报 ERROR 1030 (HY000): Got error -1 from storage engine(底层是 ENOSPC)。
常见错误现象:
- 表持续增长,某天开始频繁写失败,
df却显示空间充足; -
xfs_info /path/to/mysql显示 agcount 很小(如 4),而磁盘已超 1TB;
实操建议:
- 创建 XFS 文件系统时,用
-d agcount=N手动指定 AG 数(例如mkfs.xfs -d agcount=32 /dev/sdb),N 建议 ≥ 磁盘总 GiB 数 ÷ 32; - 监控命令换成
xfs_db -c "freesp -h" /dev/sdb,看各 AG 的空闲 extent 是否均衡; - EXT4 没这问题,它的 block group 是线性分布,只要总空间够,就能分。
文件系统不是黑盒,XFS 的 AG 和 EXT4 的 block group 设计差异,直接决定 MySQL 写入是否“突然卡住”。调参前先看 workload 类型,再查实际分配状态,比盲目换格式更有效。










