天天看點

PostgreSQL 塊級 snapshot (flash back) - postgrespro improvement

标簽

PostgreSQL , snapshot , zfs

https://github.com/digoal/blog/blob/master/201809/20180909_01.md#%E8%83%8C%E6%99%AF 背景

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》

https://github.com/digoal/blog/blob/master/201809/20180909_01.md#postgresql-snapshot-fs 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

https://github.com/digoal/blog/blob/master/201809/20180909_01.md#snapshot-%E6%93%8D%E4%BD%9C%E6%8E%A5%E5%8F%A3%E5%87%BD%E6%95%B0 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功能非常類似。

https://github.com/digoal/blog/blob/master/201809/20180909_01.md#%E4%BE%8B%E5%AD%90 例子

使用者可以定期給資料庫建立快照(同時定期的删除,比如保留最近3天内的快照),當資料庫被誤操作時,可以SWITCH到過去的某個狀态,檢視過去狀态的資料,并進行快速恢複。

https://github.com/digoal/blog/blob/master/201809/20180909_01.md#%E5%8F%82%E8%80%83 參考

《PostgreSQL 最佳實踐 - 塊級增量備份(ZFS篇)驗證 - recovery test script for zfs snapshot clone + postgresql stream replication + archive》 《PostgreSQL 最佳實踐 - 塊級增量備份(ZFS篇)雙機HA與塊級備份部署》 《PostgreSQL 最佳實踐 - 塊級增量備份(ZFS篇)單個資料庫采用多個zfs卷(如表空間)時如何一緻性備份》 《PostgreSQL 最佳實踐 - 塊級增量備份(ZFS篇)備份集自動校驗》 《PostgreSQL 最佳實踐 - 塊級增量備份(ZFS篇)方案與實戰》