Linux命令-sync(将内存缓存写入磁盘))
- 快速参考
- 基本用法
- 工作原理
- 使用场景
- 系统关机/重启
- 基准测试
- 数据持久化保证
- 与相关命令的配合
- 自定义 sync 频率
- 监控脚本
- 常见认知纠正
sync是一个简单但重要的命令,用于将文件系统缓冲区中所有未写入的数据强制刷新到磁盘。Linux 内核使用页面缓存(page cache)延迟写入磁盘以提升性能,而sync确保这些"悬而未决"的数据在关键时刻(如系统重启前、卸载存储设备前)被安全地持久化。
快速参考
sync[选项][文件...]
sync本身几乎立即返回,但实际写入可能需要一些时间完成。关键操作如reboot、halt、umount在内部都会自动调用sync。
基本用法
# 刷新所有文件系统的缓冲区sync# 刷新指定文件的缓冲区sync/path/to/important_file# 多次 sync(传统习惯:sync; sync; sync)sync&&sync&&sync# 显示 sync 执行进度(没有直接选项,但可以结合其他工具)sync&SYNC_PID=$!whilekill-0$SYNC_PID2>/dev/null;doecho"等待 sync 完成..."sleep0.5doneecho"sync 已完成"工作原理
# 查看脏页(dirty pages)——尚未写入磁盘的缓存数据cat/proc/meminfo|grepDirty# Dirty: 1234 kB# 查看写回(writeback)状态cat/proc/meminfo|grepWriteback# Writeback: 0 kB# 查看脏页阈值配置cat/proc/sys/vm/dirty_ratio# 脏页比率上限(默认 20%)cat/proc/sys/vm/dirty_background_ratio# 后台写入阈值(默认 10%)cat/proc/sys/vm/dirty_expire_centisecs# 脏页过期时间(默认 3000 = 30秒)# sync 执行前后对比echo"执行 sync 前:"grep-E"Dirty:|Writeback:"/proc/meminfosyncecho"执行 sync 后:"grep-E"Dirty:|Writeback:"/proc/meminfo# Dirty 值通常变为 0 或极小值使用场景
系统关机/重启
# 尽管 reboot/shutdown 内部会调用 sync,手动执行更安全syncsudoreboot# 紧急关机(Alt+SysRq 序列)# 按住 Alt+SysRq,依次按:# R → 切换键盘为原始模式# E → 向所有进程发送 SIGTERM# I → 向所有进程发送 SIGKILL# S → 同步所有文件系统 ← sync# U → 重新挂载所有文件系统为只读# B → 立即重启# 安全断开 USB 存储设备sync# 1. 刷新缓冲区sudoumount/mnt/usb# 2. 卸载# 3. 物理断开 USB基准测试
# 在 I/O 基准测试前刷新缓存syncecho3|sudotee/proc/sys/vm/drop_caches# 这确保测试的是实际磁盘性能而非缓存性能# drop_caches 说明# echo 1 → 释放页面缓存# echo 2 → 释放 dentries 和 inode 缓存# echo 3 → 释放所有缓存数据持久化保证
# 写入重要数据后的可靠性确认cat>/etc/important_config.conf<<'EOF' # critical config parameter=value EOFsync/etc/important_config.confecho"配置已安全写入磁盘"# 备份脚本中确保数据落盘tarczf backup.tar.gz /important_datasyncbackup.tar.gzecho"备份文件已安全写入"# 批量文件操作后fordirin/data/*/;dorsync-av"$dir"/backup/donesyncecho"所有备份数据已同步到磁盘"与相关命令的配合
# sync + umount: 安全卸载sync&&sudoumount/mnt/data# sync + eject: 弹出光盘sync&&eject# sync + blockdev: 刷新块设备缓冲区sync&&sudoblockdev--flushbufs/dev/sdb# 监控 sync 期间的 I/Osync&iostat-x13# 查看哪些进程造成了脏页cat/proc/*/status2>/dev/null|grep-B2"VmDirty"|grep-E"Name|VmDirty"# 在数据库中 sync 之前先让应用 flushmysql-e"FLUSH TABLES; FLUSH LOGS;"sync自定义 sync 频率
# 查看当前内核脏页写回参数sysctl-a|grepdirty# 调整脏页写回行为(更激进的写回 = 数据更安全但性能稍降)sudosysctl-wvm.dirty_ratio=10sudosysctl-wvm.dirty_background_ratio=5sudosysctl-wvm.dirty_expire_centisecs=1500# 15 秒sudosysctl-wvm.dirty_writeback_centisecs=500# 5 秒间隔# 持久化配置cat>/etc/sysctl.d/60-dirty-pages.conf<<'EOF' # 更激进的脏页写回(数据安全性优先) vm.dirty_ratio = 10 vm.dirty_background_ratio = 5 vm.dirty_expire_centisecs = 1500 vm.dirty_writeback_centisecs = 500 EOFsudosysctl-p/etc/sysctl.d/60-dirty-pages.conf监控脚本
# 脏页监控脚本cat>/usr/local/bin/dirty_pages_monitor.sh<<'EOF' #!/bin/bash INTERVAL=${1:-5} # 监控间隔(秒) echo "监控脏页状态(${INTERVAL}s 间隔)... Ctrl+C 退出" echo "时间 | Dirty (kB) | Writeback (kB) | 脏页占比" echo "------------------|------------|----------------|----------" while true; do DIRTY=$(grep Dirty /proc/meminfo | awk '{print $2}') WRITEBACK=$(grep Writeback /proc/meminfo | awk '{print $2}') TOTAL=$(grep MemTotal /proc/meminfo | awk '{print $2}') PCT=$(awk "BEGIN {printf \"%.2f%%\", ($DIRTY/$TOTAL)*100}") printf "%s | %10s | %14s | %s\n" \ "$(date '+%H:%M:%S')" "$DIRTY" "$WRITEBACK" "$PCT" if [ "$DIRTY" -gt $((TOTAL * 10 / 100)) ]; then echo "⚠️ 脏页超 10%,考虑手动 sync" fi sleep "$INTERVAL" done EOFchmod+x /usr/local/bin/dirty_pages_monitor.sh常见认知纠正
# 认识 1: sync 不会损坏数据# ✅ 正确。sync 只是将缓冲区数据写入磁盘,不会造成数据丢失# 认识 2: sync 执行后数据一定在磁盘上# ⚠️ 不完全是。对于有写缓存的硬件 RAID 卡和某些 SSD,# sync 只能确保数据到达设备驱动层,设备内部可能还有缓存。# 对于关键系统,使用带掉电保护的存储设备。# 认识 3: 多次 sync 比一次更安全# ❌ 在现代 Linux 内核中没有必要。一次 sync 已足够。# sync && sync && sync 是 Unix 时代的"迷信"习惯。# 但无害,可以继续使用。# 认识 4: sync 会阻塞# sync 调用本身几乎不阻塞(它只是触发了写回操作),# 但实际的磁盘写入可能持续一段时间。
sync是 Linux 数据持久化的"保险按钮"。它简单到只有一个单词,却是防止数据丢失的最后一道防线。在拔 U 盘前、断电前、系统维护前,sync三个字符就是数据安全的保证。