PostgreSQL码农集散地

国产数据库真厉害啊!时间点恢复居然能一次成功

参考文档点击文末阅读原文打开; 推荐《最好的PostgreSQL学习镜像》;


穷鬼玩PolarDB RAC系列 | 祝贺时间点恢复(PITR)实验一次成功🏆

发出这样的感慨, 看样子阿泼主被国产数据库吓得不轻! 备份和时间点恢复难道不是最朴实无华的功能么? 

系列请戳: 🏆《穷鬼玩PolarDB RAC系列》🏆

本篇文章介绍一下如何进行时间点恢复(PITR)?  实验环境依赖《在Docker容器中用loop设备模拟共享存储》 , 如果没有环境, 请自行参考以上文章搭建环境.

还需要参考如下文档:

  • https://www.postgresql.org/docs/current/continuous-archiving.html

DEMO

在实时归档机pb4容器演示PITR.

1、首先, 假设你已经按下文开启了实时归档. 确保未来的全量备份有足够的WAL可以用于时间点恢复.

  • 《实时归档》

2、其次, 在开启实时归档后, 假设你已经按下文做了一次全量备份.

  • 《在线备份》

得到:

  • 本地数据目录:/data/backup/primary
  • 共享数据目录:/data/backup/shared_data

3、在pb1 primary节点生成一些数据.

postgres=# create table tbl_digoal (id int, info text, ts timestamp);  
CREATE TABLE  
postgres=# insert into tbl_digoal select generate_series(1,1000), md5(random()::text), clock_timestamp();  
INSERT 0 1000  
postgres=# select * from tbl_digoal limit 5;  
 id |               info               |             ts               
----+----------------------------------+----------------------------  
  1 | 45085479f931ea4bb0c39ec73522cdb4 | 2024-12-19 16:27:37.748317  
  2 | afc44037b7fac9feaa8d3567f331d0db | 2024-12-19 16:27:37.750813  
  3 | 37bcea4e172f13590c5bce35fc965880 | 2024-12-19 16:27:37.750821  
  4 | 0a09b7c73a8994d5023b796cb7aa7e13 | 2024-12-19 16:27:37.750824  
  5 | 37b98e2e52ddd1c6287ceb8624d7bf0a | 2024-12-19 16:27:37.750826  
(5 rows)  

postgres=# select sum(hashtext(t::text)) from tbl_digoal t;  
     sum        
--------------  
 -71405674348  
(1 row)  

4、创建一个恢复点. 记住这个名字, 后面用来恢复.

postgres=# select now();  
              now                
-------------------------------  
 2024-12-19 16:28:27.517757+08  
(1 row)  

postgres=# select pg_create_restore_point('2024-12-19 16:28:27.517757+08');  
 pg_create_restore_point   
-------------------------  
 2/8003E6C0  
(1 row)  

5、在pb1 primary节点修改以上生成的数据.

postgres=# delete from tbl_digoal where id=10;  
DELETE 1  
postgres=# update tbl_digoal set info='new' where id=1;  
UPDATE 1  
postgres=# select sum(hashtext(t::text)) from tbl_digoal t;  
     sum        
--------------  
 -70843053399  
(1 row)  

6、使用备份和归档日志, 将PolarDB恢复到数据被修改之前.

先确保wal日志都已经被实时归档pg_current_wal_lsn与flush_lsn

postgres=# select pg_current_wal_lsn(),* from pg_stat_replication where application_name='pg_receivewal';  
-[ RECORD 1 ]------+------------------------------  
pg_current_wal_lsn | 2/8003E9A0  
pid                | 5255  
usesysid           | 10  
usename            | postgres  
application_name   | pg_receivewal  
client_addr        | 172.17.0.5  
client_hostname    |   
client_port        | 58302  
backend_start      | 2024-12-19 16:32:26.754692+08  
backend_xmin       |   
state              | streaming  
sent_lsn           | 2/8003E9A0  
write_lsn          | 2/8003E9A0  
flush_lsn          | 2/8003E9A0  
replay_lsn         |   
write_lag          | 00:00:00.002957  
flush_lag          | 00:00:00.002957  
replay_lag         | 00:00:00.002957  
sync_priority      | 0  
sync_state         | async  
reply_time         | 2024-12-19 16:32:26.762024+08  

把以下备份拷贝到临时恢复目录中, 当然你也可以直接在备份上进行恢复, 只是这样就把备份文件破坏了. (这也是为什么我非常推崇zfs, 因为zfs 可以基于快照克隆(瞬间完成), 这样不会破坏原有的数据.)

  • 本地数据目录:/data/backup/primary
  • 共享数据目录:/data/backup/shared_data
mkdir /data/recovery  
cp -r /data/backup/primary /data/recovery/  
cp -r /data/backup/shared_data /data/recovery/  

修改postgresql.conf配置文件

cd /data/recovery/primary    

vi postgresql.conf    

# 修改和注释如下      
polar_disk_name='home'
polar_datadir='file-dio:///data/recovery/shared_data'
polar_vfs.localfs_mode=true
# polar_storage_cluster_name='disk'     

# 增加如下, 恢复目标, 拷贝wal的命令     
restore_command = 'cp /data/polardb_wal_archive/%f %p || cp /data/polardb_wal_archive/%f.partial %p'
recovery_target_timeline = latest   
recovery_target_name = '2024-12-19 16:28:27.517757+08'
recovery_target_action = 'pause'

# 其他配置保持不变即可    
huge_pages=off   
port=5432    
polar_hostid=1    
polar_enable_shared_storage_mode=on    
shared_preload_libraries='$libdir/polar_vfs,$libdir/polar_worker'
logging_collector=on    
log_line_prefix='%p\t%r\t%u\t%m\t'
log_directory='pg_log'
listen_addresses='0.0.0.0'
max_connections=200   

删除standby标记文件, 添加recovery标记文件

rm /data/recovery/primary/standby.signal   
rm /data/recovery/shared_data/standby.signal   

touch /data/recovery/primary/recovery.signal  
touch /data/recovery/shared_data/recovery.signal  

启动数据库

pg_ctl start -D /data/recovery/primary  

查看数据库日志, 可以看到已经恢复到了目标recovery_target_name = '2024-12-19 16:28:27.517757+08'

cd /data/recovery/primary/pg_log  

less postgresql-2024-12-19_165344_error.log  

4279                    2024-12-19 16:53:47.757 CST     LOG:  recovery stopping at restore point "2024-12-19 16:28:27.517757+08", time 2024-12-19 16:28:34.938012+08  
4279                    2024-12-19 16:53:47.757 CST     LOG:  pausing at the end of recovery  
4279                    2024-12-19 16:53:47.757 CST     HINT:  Execute pg_wal_replay_resume() to promote.  

最后, 检查一下数据, 确实已经恢复到目标, 数据是更新之前的样子:

$ psql  
psql (PostgreSQL 15.10 (PolarDB 15.10.2.0 build d4f5477d debug) on aarch64-linux-gnu)  
Type "help"forhelp.  

postgres=# select count(*) from tbl_digoal ;  
 count   
-------  
  1000  
(1 row)  

postgres=# select sum(hashtext(t::text)) from tbl_digoal t;  
     sum        
--------------  
 -71405674348  
(1 row)  

用完记得把恢复库关掉:

$ pg_ctl stop -m fast -D /data/recovery/primary   

参考

《穷鬼玩PolarDB RAC一写多读集群系列 | 在Docker容器中用loop设备模拟共享存储》

《穷鬼玩PolarDB RAC一写多读集群系列 | 如何搭建PolarDB容灾(standby)节点》

《穷鬼玩PolarDB RAC一写多读集群系列 | 共享存储在线扩容》

《穷鬼玩PolarDB RAC一写多读集群系列 | 计算节点 Switchover》

《穷鬼玩PolarDB RAC一写多读集群系列 | 在线备份》

《穷鬼玩PolarDB RAC一写多读集群系列 | 在线归档》

《穷鬼玩PolarDB RAC一写多读集群系列 | 实时归档》

https://www.postgresql.org/docs/current/continuous-archiving.html

https://www.postgresql.org/docs/current/runtime-config-wal.html

《PostgreSQL PITR THREE recovery target MODE: name,xid,time USE CASE - 2》

《PostgreSQL PITR THREE recovery target MODE: name,xid,time USE CASE - 1》

《PostgreSQL recovery target introduce》

《PostgreSQL 时间点恢复(PITR)时查找wal record的顺序 - loop(pg_wal, restore_command, stream)》

《PostgreSQL 增量备份集的有效恢复位点》

《PostgreSQL如何支持可选择性表空间(Selectivity Tablespace)备份和时间点(PITR)恢复?》

文末彩蛋:国产数据库周边生态

当然一款数据库要流行起来, 除了自己要强大, 还离不开生态. 用好周边生态工具, 管理水平战胜90%老司机!!! 下面简单介绍一下国产数据库周边生态.

1、管控软件

鸣嵩(前阿里云数据库总经理 / 研究员)等大佬们创业创办的云猿生, 核心产品是KubeBlocks. 他们的理念是让管理数据库和搭积木一样简单, 如果你要管理很多套并且种类(OLTP\OLAP\NoSQL\KV\TS\MQ等)很多的数据库产品, 推荐首选.

  • https://github.com/apecloud/kubeblocks

PG中文社区核心委员唐成老师的公司乘数开源的Clup, 专用管理PostgreSQL和PolarDB的集群管理软件, 如果你要管理很多套数据库, 推荐选择. 并且Clup还提供了企业版、自研的连接池、分布式存储、一体机、备份平台等, 是企业用户推荐之选.

  • https://www.csudata.com/

若航老司机开源的pigsty, 集成了300多个PG插件的PG集群和PolarDB集群管理软件, 如果你要管理很多套PG或PolarDB数据库, 且对插件有特别多的需求, 推荐选择.

  • https://pigsty.cc/zh/

2、审计监控诊断优化

翟总(曾经是我背后的男人)到海信聚好看后研发的 DBdoctor, 采用ebpf技术, 在对数据库几乎没有影响的情况下实时监控数据库和服务器的各项指标, 发现和诊断问题根因非常方便.

  • https://www.dbdoctor.cn/

天舟老哥的核心产品Bytebase 是位于您和数据库之间的中间件。它是数据库 DevOps 的 GitLab/GitHub,专为开发人员、DBA 和平台工程师打造。

  • https://bytebase.cc/docs/introduction/what-is-bytebase/

PawSQL, SQL优化和诊断产品.  

D-Smart, Oracle老前辈白老大出品, 专注企业级市场, 将业界顶级DBA经验的产品化作品, 产品功能包括数据库监控、诊断、优化等.

  • https://www.modb.pro/db/567140

3、国产数据库IDE

IDE是开发者的必备工具,例如社区有pgAdmin, 国产IDE则可以看看老程序猿达刚老师的DeskUI:

  • https://www.deskui.com

4、数据同步&迁移&备份恢复

NineData, 老领导出去创业做的产品, 产品涵盖了数据同步、迁移、备份、比对、devops、chatDBA等.

  • https://www.ninedata.cloud/home

DSG, 非常老牌的数据库同步迁移企业级产品, 支持各种数据库的异构和同构迁移, 用他们的话说, 没有dsg搞不定的迁移, 比goldengate还牛.

  • https://www.dsgdata.com/

公开课

如果你对PolarDB学习感兴趣可以阅读这个公开课系列:

除了PolarDB还非常值得关注的几款PG栈国产数据库:

  • HaloDB(基于PG兼容PostgreSQL、Oracle、MySQL. http://www.halodbtech.com/ )、
  • IvorySQL(基于开源PG兼容PG、Oracle. https://www.ivorysql.org/zh-cn/ )、
  • ProtonBase(云原生分布式数仓. https://protonbase.com/ )、
  • 成都文武数据库(https://ww-it.cn)

参考文档点击阅读原文获得


感谢关注我的github (https://github.com/digoal/blog) 及视频号:

Image