BTRFS文件系统下PostgreSQL数据库在线备份:快照前是否需执行sync操作?
BTRFS文件系统下PostgreSQL数据库在线备份:快照前是否需执行sync操作?
嘿,这个问题问到点子上了——毕竟在线备份的核心是一致性,要是快照出来的数据库恢复不了,那备份就白做了对吧?
直接给你明确结论:你必须手动执行sync(或者btrfs filesystem sync),btrfs subvolume snapshot不会帮你自动做这件事。
为啥这么说?得从两个层面理解:
- 首先是PostgreSQL本身:数据库会把大量数据暂存在内存缓存里(比如shared_buffers),还没刷到磁盘文件上;同时正在进行的事务也可能处于半提交状态。
- 其次是BTRFS文件系统:它自己也有写缓存,这些缓存还没真正落到物理磁盘上。
如果跳过sync直接拍快照,你得到的只是磁盘当前的“快照”,但内存里的脏数据、文件系统缓存里的内容都没被包含进去,这样的快照是不一致的——恢复的时候PostgreSQL很可能会报数据损坏错误,甚至直接启动失败。
那正确的在线备份步骤应该是这样的:
- 先让PostgreSQL进入备份模式,强制刷脏页并锁定一致性状态:
(注:PostgreSQL 10+也可以用pg_start_backup('btrfs_snapshot_backup')pg_backup_start,本质是一样的,都是让数据库进入安全的备份状态) - 执行文件系统sync,把所有缓存刷到物理磁盘:
(用btrfs filesystem sync /var/lib/postgresql/14/main # 替换成你的Postgres数据目录btrfs filesystem sync比全局sync更高效,它只会同步指定挂载点的缓存) - 创建只读的BTRFS子卷快照(只读快照更安全,避免后续意外修改):
btrfs subvolume snapshot -r /var/lib/postgresql/14/main /mnt/backup/postgres_snapshot_20240520 - 最后让PostgreSQL退出备份模式:
pg_stop_backup()
额外提醒一句:光靠sync还不够,必须配合PostgreSQL的备份前后命令。因为即使文件系统同步了,PostgreSQL内部的事务日志(WAL)需要覆盖快照点到备份结束的这段时间,这样恢复的时候才能通过WAL回放把数据库拉到完全一致的状态。
备注:内容来源于stack exchange,提问作者Jonas
相关产品推荐
相关产品推荐

