不会丢应用数据,但会清空内核页缓存、目录项和inode缓存,仅影响已写入磁盘且未被修改的干净页,不触发writeback,不影响dirty page及数据库自身缓冲区。

直接改 /proc/sys/vm/drop_caches 会立即丢数据吗?
不会丢应用数据,但会清空内核页缓存、目录项和 inode 缓存。它只影响已写入磁盘且未被修改的缓存页,drop_caches 不触发 writeback,也不影响 dirty page。换句话说:正在写的文件、没 sync 的修改、数据库自己的 buffer 都不受影响——但后续读这些文件时会变慢,因为得重新从磁盘加载。
- 这个操作本质是“让内核放弃它认为可以安全丢弃的缓存”,不是强制刷盘也不是清空所有内存
- 必须用
echo 3 > /proc/sys/vm/drop_caches(或1/2),仅 root 可写 - 普通用户执行会报错:
Permission denied - 它不等同于
sync && echo 3 > ...;sync是确保 dirty page 写盘,drop_caches是之后才清理干净页
drop_caches=3 在 MySQL 或 PostgreSQL 场景下有什么副作用?
会让数据库下次查询响应明显变长,尤其在冷启动或大表扫描后手动清缓存时。PostgreSQL 的 shared_buffers 不受影响(那是自己管理的),但 OS page cache 里缓存的 WAL 文件、数据文件块会被清掉;MySQL 的 InnoDB Buffer Pool 同理独立,但 query cache(已弃用)或文件系统层预读缓存没了。
- 如果刚做完
mysqldump或逻辑备份,接着跑drop_caches,后续恢复或导入会更慢 - 备份工具如
percona-xtrabackup依赖大量文件读取,清缓存后 IO 压力会瞬间拉高 -
drop_caches对 LSM-tree 类引擎(如 RocksDB)影响较小,因为它们更依赖自身 block cache,而非 page cache
为什么 echo 3 > /proc/sys/vm/drop_caches 在容器里经常失效?
因为容器默认没有 sys_admin cap,且 /proc/sys/vm/ 是 host namespace 的,容器进程即使挂载了该路径,写入也会被拒绝,报错:Operation not permitted。
- 即使你用
docker run --privileged,也得确认 cgroup v2 下是否放开了vm.drop_caches控制器(通常不开放) - Kubernetes Pod 默认禁止该操作,除非显式加
securityContext.capabilities.add: ["SYS_ADMIN"],且节点允许 - 更隐蔽的问题:某些发行版(如 RHEL/CentOS 8+)启用了
kernel.unprivileged_userns_clone=0,连 root 在 user namespace 里都写不了
替代 drop_caches 的更可控手段有哪些?
真要模拟“清缓存测性能”,优先考虑隔离测试环境,而不是在线生产清。线上唯一合理用途是排除 page cache 干扰后的 IO 性能对比,且必须配合监控确认无业务抖动。
- 用
posix_fadvise(fd, 0, 0, POSIX_FADV_DONTNEED)在应用层提示内核丢弃某文件缓存,比全局清更精准 - 测试时用
stress-ng --vm 1 --vm-bytes 4G --vm-hang 0 --timeout 30s占满内存再释放,效果接近但可逆 - 真要清,务必先
echo 1 > /proc/sys/vm/compact_memory防止内存碎片导致后续分配慢(尤其在低内存压力下)
有些团队把 drop_caches 当“重启前清理”用,其实是在掩盖内存泄漏或 buffer 配置不合理的问题。它不解决根本,只掩盖症状,而且时机稍有偏差就可能卡住 IO 调度器几秒。










