文章目录一次文件写入:从调用到落盘的全流程——清晰描述一次文件写入从调用开始到落盘的全过程以及潜在瓶颈整体调用链(自上而下)逐层详解① 用户态:libc 与用户缓冲② 系统调用陷入内核③ VFS 层(generic_perform_write)④ Page Cache —— write() 在此返回⑤ writeback 线程 → submit_bio⑥ 块层:I/O 调度 / 合并 / 重排⑦ 设备驱动:DMA 下发⑧ 设备内部:控制器缓存 → 物理介质关键工具:fsync / fdatasync / sync数据库的实战做法:MySQL 双 1潜在瓶颈全景图第⑤步之后:谁在控制执行,如何保证真正落盘一、每一层「谁在执行」⑤ writeback 线程(pdflush 的演进):内核后台线程⑥ Block Layer:内核软中断 + blk-mq⑦ Device Driver:中断驱动⑧ 设备控制器 → 介质:硬件自主二、怎样保证"一定落盘了"——三层缓存都要刷穿1. 穿透用户缓冲 + Page Cache:`fsync()` / `fdatasync()`2. 穿透设备缓存:FLUSH / FUA 命令3. 文件系统 journal(崩溃一致性的最后一道防线)4. 关掉写缓存(终极保险,但有代价)三、一句话总结文件写入落盘 · 完整执行流程图(纯文本线图)一、主流程链路图二、三层缓存穿透图(保证落盘的关键)三、异步 vs 同步路径对比图一次文件写入:从调用到落盘的全流程——清晰描述一次文件写入从调用开始到落盘的全过程以及潜在瓶颈下面以 Linux 为例(Windows、MySQL 的机制在底层原理上相通),把一次write(fd, buf, len)从用户态调用一直追到磁盘物理扇区,逐层拆解,并标注每层的潜在瓶颈。整体调用链(自上而下)用户程序 write() │ ① 用户态:libc 包装 + 用户缓冲 ▼ glibc write() → syscall 指令 │ ② 系统调用陷入内核 ▼ VFS (sys_write → vfs_write → generic_perform_write) │ ③ 虚拟文件系统:权限/锁/页缓存 ▼ Page Cache (地址空间 radix tree) │ ④ 写入页缓存,标记 Dirty —— write() 在这里就返回了! ▼ (异步) pdflush / writeback 线程 │ ⑤ 脏页回写:扫描 dirty page → submit_bio ▼ Block Layer (I/O 调度 / 合并 / 重排) │ ⑥ 电梯算法、merge/bounce、请求队列 ▼ Device Driver (SCSI/NVMe/SATA 驱动) │ ⑦ DMA 提交,下发命令到设备 ▼ 磁盘 / SSD 控制器 │ ⑧ 设备内部缓存 + FUA/Flush → 物理介质 ▼ NAND 闪存单元 / 磁盘盘片 ✅ 真正落盘
一次文件写入:从调用到落盘的全流程——清晰描述一次文件写入从调用开始到落盘的全过程以及潜在瓶颈
文章目录一次文件写入:从调用到落盘的全流程——清晰描述一次文件写入从调用开始到落盘的全过程以及潜在瓶颈整体调用链(自上而下)逐层详解① 用户态:libc 与用户缓冲② 系统调用陷入内核③ VFS 层(generic_perform_write)④ Page Cache —— write() 在此返回⑤ writeback 线程 → submit_bio⑥ 块层:I/O 调度 / 合并 / 重排⑦ 设备驱动:DMA 下发⑧ 设备内部:控制器缓存 → 物理介质关键工具:fsync / fdatasync / sync数据库的实战做法:MySQL 双 1潜在瓶颈全景图第⑤步之后:谁在控制执行,如何保证真正落盘一、每一层「谁在执行」⑤ writeback 线程(pdflush 的演进):内核后台线程⑥ Block Layer:内核软中断 + blk-mq⑦ Device Driver:中断驱动⑧ 设备控制器 → 介质:硬件自主二、怎样保证"一定落盘了"——三层缓存都要刷穿1. 穿透用户缓冲 + Page Cache:`fsync()` / `fdatasync()`2. 穿透设备缓存:FLUSH / FUA 命令3. 文件系统 journal(崩溃一致性的最后一道防线)4. 关掉写缓存(终极保险,但有代价)三、一句话总结文件写入落盘 · 完整执行流程图(纯文本线图)一、主流程链路图二、三层缓存穿透图(保证落盘的关键)三、异步 vs 同步路径对比图一次文件写入:从调用到落盘的全流程——清晰描述一次文件写入从调用开始到落盘的全过程以及潜在瓶颈下面以 Linux 为例(Windows、MySQL 的机制在底层原理上相通),把一次write(fd, buf, len)从用户态调用一直追到磁盘物理扇区,逐层拆解,并标注每层的潜在瓶颈。整体调用链(自上而下)用户程序 write() │ ① 用户态:libc 包装 + 用户缓冲 ▼ glibc write() → syscall 指令 │ ② 系统调用陷入内核 ▼ VFS (sys_write → vfs_write → generic_perform_write) │ ③ 虚拟文件系统:权限/锁/页缓存 ▼ Page Cache (地址空间 radix tree) │ ④ 写入页缓存,标记 Dirty —— write() 在这里就返回了! ▼ (异步) pdflush / writeback 线程 │ ⑤ 脏页回写:扫描 dirty page → submit_bio ▼ Block Layer (I/O 调度 / 合并 / 重排) │ ⑥ 电梯算法、merge/bounce、请求队列 ▼ Device Driver (SCSI/NVMe/SATA 驱动) │ ⑦ DMA 提交,下发命令到设备 ▼ 磁盘 / SSD 控制器 │ ⑧ 设备内部缓存 + FUA/Flush → 物理介质 ▼ NAND 闪存单元 / 磁盘盘片 ✅ 真正落盘