PostgreSQL 块级 snapshot (flash back) - postgrespro improvement

1 minute read

背景

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篇)验证 - recovery test script for zfs snapshot clone + postgresql stream replication + archive》

《PostgreSQL 最佳实践 - 块级增量备份(ZFS篇)双机HA与块级备份部署》

《PostgreSQL 最佳实践 - 块级增量备份(ZFS篇)单个数据库采用多个zfs卷(如表空间)时如何一致性备份》

《PostgreSQL 最佳实践 - 块级增量备份(ZFS篇)备份集自动校验》

《PostgreSQL 最佳实践 - 块级增量备份(ZFS篇)方案与实战》

Flag Counter

digoal’s 大量PostgreSQL文章入口