什么是 fsync 延迟
fsync/fdatasync 把脏页与元数据刷到持久介质后才返回,应用确认写入成功的时间点由它决定,因此数据库提交延迟、日志落盘延迟最终都归结为 fsync 的耗时。观测手段是用 strace -T 记录单次调用耗时并统计分布,关注 P99 与尖峰,而不是平均值:批量落盘、设备写缓存策略、存储链路抖动都会让个别调用明显变慢。
基本信息
| 观测工具 | strace -T/-ttt、perf trace |
|---|---|
| 关注指标 | 单次耗时分布与尖峰,尤其是 P99 |
| 相关调用 | fsync、fdatasync、sync_file_range |
| 写入路径 | 页缓存 → 块层排队 → 设备缓存 → 介质 |
| 影响因素 | 设备缓存策略、队列拥塞、网络存储、日志模式 |
典型使用场景
- 数据库提交延迟升高:确认是否由 fsync 尖峰引起
- 写入放大排查:观察一次事务触发多少次刷盘
- 存储选型与验收:对比不同设备在同一写模式的 fsync 分布
- 参数调优前后验证:改日志模式或缓存策略后回归对比
- 判断是否属于设备故障:区分链路拥塞与介质异常
观测方法
观测方法
sudo strace -T -f -e trace=fsync,fdatasync -p 12345 2>&1 | head -30
# 输出行尾的 <0.012345> 即该次 fsync 用时(秒)
sudo strace -T -f -e trace=fsync,fdatasync -c -p 12345 # 汇总调用次数与耗时
iostat -x 1 5 | tail -5 # 同期看设备 await 与队列
cat /proc/pressure/io # 系统级 IO 压力指标
dd if=/dev/zero of=/data/t bs=1M count=64 conv=fsync oflag=direct # 单点基准耗时分布判读
| 表现 | 可能原因 | 下一步 |
|---|---|---|
| 稳定在亚毫秒级 | 设备缓存吸收写入 | 属于正常,注意是否依赖易失缓存 |
| 周期性尖峰 | 批量回写或日志提交周期 | 对齐应用提交模式再判断 |
| 普遍偏慢且 await 高 | 设备或链路饱和 | 查队列深度与存储侧负载 |
| 个别超长调用 | 网络存储抖动或介质重试 | 结合 dmesg 与存储日志排查 |
strace -T 输出的耗时含系统调用外的调度等待,与挂钟不一致属于正常;要精确归因可结合 /proc/<pid>/stack 与块层指标一起看。
strace 附加会带来额外开销,短窗口采集并避开极端高峰,长时间挂在高并发业务进程上可能明显拖慢它。