fsync 尾延迟观测

应用 fsync/fdatasync 的耗时决定写入确认延迟;用 strace -T 看单次耗时,或在写入路径上叠加监控观察 P99。

什么是 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 附加会带来额外开销,短窗口采集并避开极端高峰,长时间挂在高并发业务进程上可能明显拖慢它。

易错点

  • strace 附加有开销,短窗口采集并避开极端高峰,必要时在预发环境复现
  • fsync 慢不一定是盘故障:队列拥塞、日志提交策略、网络存储都可能是原因,只换盘未必解决
  • 把平均值当作结论:fsync 的体验由尾部延迟决定,必须看分布与尖峰频率
  • 忽略设备写缓存带来的假象:廉价的“快”可能意味着数据还在易失缓存里,掉电即丢

数据来源与参考

  • strace 官方文档
  • man-pages fsync(2)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌