标签
PostgreSQL , snapshot , zfs
背景
Postgrepro提供了一个snapshot fs的功能,允许用户对数据库状态打快照,并可以在将来迅速的闪回到某个过去的快照。
这个功能是通过数据库page级COW来实现的,类似ZFS文件系统的快照功能,在PostgreSQL 内核层面实现了。
snapshot fs与逻辑flashback query是不一样的,flashback query实际上用的是TUPLE级别的UNDO或未回收的旧版本来查看表的过去状态的。而snapshot fs则是块级别的多版本,如果要回退,实际上是将整个数据库回退到过去的状态,而不是单个表,当然如果要做表级别的snapshot siwtch或recovery,功能上也是可以实现的。
《PostgreSQL flashback(闪回) 功能实现与介绍》
《PostgreSQL 闪回 - flash back query emulate by trigger》
PostgreSQL snapshot fs
替换了原有的文件操作接口,实现COW。
https://github.com/postgrespro/snapfs/commit/673c5e9ecd0cab52e96c261205db1f570545b4c5
https://github.com/postgrespro/snapfs/blob/pg_snap/src/backend/storage/file/snapfs.c
https://github.com/postgrespro/snapfs/blob/pg_snap/src/backend/storage/file/fd.c
https://github.com/postgrespro/snapfs/blob/pg_snap/src/include/storage/snapfs.h
snapshot 操作接口函数
1、创建快照,当BLOCK发生变更时,变更之前的BLOCK(旧版本),写入*.snapmap.SNAP_ID file
文件中。直到snapshot被删除。
/*
* Create new snapshot. Starting from this moment Postgres will store original copies of all updated pages.
* Them will be stored in shanpshot file (*.snap.SNAP_ID and addressed through *.snapmap.SNAP_ID file) until
* snapshot is deleted by sfs_remove_snapshot function or new snapshot is created.
*/
extern SnapshotId sfs_make_snapshot(void);
2、删除snapshot.
/*
* Remove snapshot with all it's files
*/
extern void sfs_remove_snapshot(SnapshotId sid);
3、将数据库恢复到指定snapshot.
/*
* Reset database state to the paritcular snapshot.
* It will be not possible any more to recover to any of more recent snashots or to the most recent database state.
*/
extern void sfs_recover_to_snapshot(SnapshotId sid);
4、查看数据库过去的某个状态。(并不是恢复到过去的状态)
/*
* Temporary switch instance to the particular snashot. It will be possible to return back to the most recent database state or to switch to any other snapshot
*/
extern void sfs_switch_to_snapshot(SnapshotId sid);
5、仅仅将当前的BACKEND PID,切换到数据库过去某个SNAPSHOT ID的状态,而不是将所有BACKEND切换到过去的某个状态。
/*
* Set snapshot for backend, unlike sfs_switch_to_snapshot function, it switchces snapshot for the current backend and not for all server instance.
*/
extern void sfs_set_backend_snapshot(SnapshotId sid);
这些接口与ZFS的SNAPSHOT功能非常类似。
例子
用户可以定期给数据库创建快照(同时定期的删除,比如保留最近3天内的快照),当数据库被误操作时,可以SWITCH到过去的某个状态,查看过去状态的数据,并进行快速恢复。
参考
https://github.com/postgrespro/snapfs/commit/673c5e9ecd0cab52e96c261205db1f570545b4c5
《PostgreSQL 最佳实践 - 块级增量备份(ZFS篇)双机HA与块级备份部署》
《PostgreSQL 最佳实践 - 块级增量备份(ZFS篇)单个数据库采用多个zfs卷(如表空间)时如何一致性备份》