PostgreSQL码农集散地

主机全毁且没备份,别忙着跑路,数据库还有救

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


穷鬼玩PolarDB RAC系列 | 主机全毁, 只剩共享存储的PolarDB还有救吗?

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

本篇文章介绍一下如果PolarDB的主机(计算节点)全挂了, 只剩共享存储, 应该如何修复集群? 实验环境依赖《在Docker容器中用loop设备模拟共享存储》, 如果没有环境, 请自行参考以上文章搭建环境.

捣毁主机

1、破坏pb1 PolarDB RW节点

pg_ctl stop -m fast -D ~/primary  

rm -rf ~/primary  

2、破坏pb2 PolarDB RO节点

pg_ctl stop -m fast -D ~/replica1  

rm -rf ~/replica1  

现在只剩下共享存储, PolarDB 还能抢救吗?

3、索性破坏彻底一点, 把pb1, pb2容器都删掉, 彻底没了就更好玩了.

docker stop pb1  
docker stop pb2  

docker rm pb1  
docker rm pb2  

把macOS上的Docker Desktop也重启一下, 连loop块设备都没了.

现在只剩下模拟成共享盘的这个文件, 接下来一步一步恢复.

$ cd ~/data_volumn/  
$ ll VirtualDisk.img   
-rw-r--r--  1 digoal  staff    20G Dec 24 11:29 VirtualDisk.img  

DEMO

和原来的计算节点一样, 使用polardb_pg_devel:ubuntu22.04镜像, 自带pfs, 无需再安装pfs.

1、启动容器pb1

cd ~/data_volumn    
PWD=`pwd`    

docker run -d -it -v $PWD:/data -P --shm-size=1g --cap-add=SYS_PTRACE --cap-add SYS_ADMIN --privileged=true --name pb1 registry.cn-hangzhou.aliyuncs.com/polardb_pg/polardb_pg_devel:ubuntu22.04 bash    

记录容器pb1 IP地址

进入容器pb1    
docker exec -ti pb1 bash    

ip addr show    
172.17.0.2  

2、启动容器pb2

cd ~/data_volumn    
PWD=`pwd`    

docker run -d -it -v $PWD:/data -P --shm-size=1g --cap-add=SYS_PTRACE --cap-add SYS_ADMIN --privileged=true --name pb2 registry.cn-hangzhou.aliyuncs.com/polardb_pg/polardb_pg_devel:ubuntu22.04 bash    

记录容器pb2 IP地址

进入容器pb2    
docker exec -ti pb2 bash    

ip addr show    
172.17.0.3    

3、在pb1中使用共享的VirtualDisk.img文件创建loop设备, 需要找到一个空闲的loop设备, 从loop0开始找, 逐渐增加数字. 直到创建loopN成功.

使用 losetup -f 找第一个未使用的loop设备.  
$ losetup -f  
/dev/loop1  

创建loop设备  
$ sudo losetup --direct-io=on /dev/loop1 /data/VirtualDisk.img    

$ ll /dev/loop1    
brw-rw-rw- 1 root root 7, 1 Dec 16 13:52 /dev/loop1    

将loop设备软链到nvme1n1方便使用, 如果你的容器内已经有这个名字, 可以换一个例如nvme2n1.

# 注意: 容器重启后, 这个软链就不存在了, 需重新创建该软链     

sudo ln -s /dev/loop1 /dev/nvme1n1    

4、pb2直接使用pb1创建的loop1即可.(由于我这个环境任何一个容器创建了loop block设备其他容器都能看到. 在实际的生产环境中, 创建loop设备的过程对应的是SAN给主机分配LUN的过程.)

将loop设备软链到nvme1n1方便使用, 如果你的容器内已经有这个名字, 可以换一个例如nvme2n1.

# 注意: 容器重启后, 这个软链就不存在了, 需重新创建该软链     

sudo ln -s /dev/loop1 /dev/nvme1n1    

5、在pb1, pb2都启动pfsd,-w为工作进程数量, 数字越大IO性能越好, 这里受制于容器资源限制设置为1.

pb1 , pb2

sudo /usr/local/polarstore/pfsd/bin/start_pfsd.sh -p nvme1n1 -w 1    

现在共享盘都挂好了, pfsd也启动了, 可以看到共享盘中的数据都还在.

$ sudo pfs -C disk ls /nvme1n1/  

  File  1     4194304           Tue Dec 24 09:45:40 2024  .pfs-paxos  
  File  1     1073741824        Tue Dec 24 09:45:41 2024  .pfs-journal  
   Dir  1     1536              Tue Dec 24 09:52:24 2024  shared_data  
total 2105344 (unit: 512Bytes)  

接下来就安装PolarDB 二进制, 创建计算节点, 恢复PolarDB集群.

6、编译polardb 15.

之前编译过, 直接从共享盘拷贝二进制. 如果你想体验一下编译过程请参考:《穷鬼玩PolarDB RAC一写多读集群系列 | 在Docker容器中用loop设备模拟共享存储》

pb1, pb2. 拷贝PolarDB二进制.

$ cp -r /data/polardb/tmp_polardb_pg_15_base ~/    


$ which psql    
/home/postgres/tmp_polardb_pg_15_base/bin/psql    

7、pb1 恢复primary节点

实际参考了增加replica节点的步骤, 只是把配置文件修改了一下.

mkdir -m 0700 $HOME/primary    
sudo /home/postgres/tmp_polardb_pg_15_base/bin/polar-initdb.sh $HOME/primary/ /nvme1n1/shared_data/ replica    
sudo chmod -R 700 $HOME/primary    
sudo chown -R postgres:postgres  $HOME/primary     

生成配置文件模板

initdb -D /tmp/primary    
cp /tmp/primary/*.conf $HOME/primary/  
rm -rf /tmp/primary  

修改配置文件

postgresql.conf

echo"    
port=5432    
polar_hostid=1    # 注意  
polar_enable_shared_storage_mode=on    
polar_disk_name='nvme1n1'    
polar_datadir='/nvme1n1/shared_data/'    
polar_vfs.localfs_mode=off    
shared_preload_libraries='\$libdir/polar_vfs,\$libdir/polar_worker'    
polar_storage_cluster_name='disk'    
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  
# 下面几个参数解决replica不能promote的问题, 因为RO依赖logindex.  
polar_logindex_mem_size=64MB  
polar_xlog_queue_buffers=64MB  
polar_xlog_page_buffers=64MB  
# 使用pfs时可以关掉 full page write 和 polar_has_partial_write , 否则请打开这两   
full_page_writes = off  
polar_has_partial_write = off   
"
 >> ~/primary/postgresql.conf     

pg_hba.conf

echo"      
host all all 0.0.0.0/0 md5      
host  replication postgres  172.17.0.0/16 trust      
"
 >> ~/primary/pg_hba.conf      

启动RW节点

pg_ctl start -D $HOME/primary    

PolarDB实例里的数据都还在, slot也还在, 启动后standby立刻就连上来了.

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

postgres=# \dt  
        List of relations  
 Schema | Name | Type  |  Owner     
--------+------+-------+----------  
 public | t    | table | postgres  
 public | t1   | table | postgres  
 public | t2   | table | postgres  
 public | tbl  | table | postgres  
(4 rows)  


postgres=# select * from pg_stat_replication;  
 pid | usesysid | usename  | application_name | client_addr | client_hostname | client_port |         backend_start         | backend_xmin |   state   |  sent_lsn  | write_lsn  | flush_lsn  | replay_lsn  
 |    write_lag    |    flush_lag    |   replay_lag    | sync_priority | sync_state |          reply_time             
-----+----------+----------+------------------+-------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+-----------  
-+-----------------+-----------------+-----------------+---------------+------------+-------------------------------  
 794 |       10 | postgres | standby1         | 172.17.0.4  |                 |       57176 | 2024-12-24 11:24:41.435003+08 |              | streaming | 0/40945898 | 0/40945898 | 0/40945898 | 0/40945898  
 | 00:00:00.000545 | 00:00:00.000579 | 00:00:00.000822 |             0 | async      | 2024-12-24 11:24:52.820741+08  
(1 row)  


postgres=# select * from pg_replication_slots ;  
 slot_name | plugin | slot_type | datoid | database | temporary | active | active_pid | xmin | catalog_xmin | restart_lsn | confirmed_flush_lsn | wal_status | safe_wal_size | two_phase   
-----------+--------+-----------+--------+----------+-----------+--------+------------+------+--------------+-------------+---------------------+------------+---------------+-----------  
 replica1  |        | physical  |        |          | f         | f      |            |      |              | 0/409455B0  |                     | reserved   |               | f  
 standby1  |        | physical  |        |          | f         | t      |        794 |      |              | 0/40945898  |                     | reserved   |               | f  
(2 rows)  

RW节点启动过后, 写入一些数据

postgres=# \d t1  
                 Table "public.t1"
 Column |  Type   | Collation | Nullable | Default   
--------+---------+-----------+----------+---------  
 id     | integer |           |          |   

postgres=# insert into t1 values (100);  
INSERT 0 1  
postgres=# select * from t1;  
 id    
-----  
   1  
 100  
(2 rows)  

pb3 standby 节点立即就能查到新增的数据. (由于docker desktop重启过, pb3的loop设备可能要新建, nvme软链也要新建, pfsd要启动, 再启动standby.)

$ sudo losetup --direct-io=on /dev/loop2 /data/VirtualDisk_standby.img   
$ sudo ln -s /dev/loop2 /dev/nvme2n1    
$ sudo /usr/local/polarstore/pfsd/bin/start_pfsd.sh -p nvme2n1 -w 1   
$ pg_ctl start -D ~/standby   

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

postgres=# select * from t1;  
 id    
-----  
   1  
 100  
(2 rows)  

到此RW节点就恢复正常了.

8、pb2 恢复replica节点

mkdir -m 0700 $HOME/replica1    
sudo /home/postgres/tmp_polardb_pg_15_base/bin/polar-initdb.sh $HOME/replica1/ /nvme1n1/shared_data/ replica    
sudo chmod -R 700 $HOME/replica1    
sudo chown -R postgres:postgres  $HOME/replica1     

生成配置文件模板

initdb -D /tmp/replica1    
cp /tmp/replica1/*.conf $HOME/replica1/  
rm -rf /tmp/replica1  

修改配置文件

postgresql.conf 与primary略有不同,

echo"    
port=5432    
polar_hostid=2    # 注意  
polar_enable_shared_storage_mode=on    
polar_disk_name='nvme1n1'    
polar_datadir='/nvme1n1/shared_data/'    
polar_vfs.localfs_mode=off    
shared_preload_libraries='\$libdir/polar_vfs,\$libdir/polar_worker'    
polar_storage_cluster_name='disk'    
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  
# 下面几个参数解决replica不能promote的问题, 因为RO依赖logindex.  
polar_logindex_mem_size=64MB  
polar_xlog_queue_buffers=64MB  
polar_xlog_page_buffers=64MB  
# 使用pfs时可以关掉 full page write 和 polar_has_partial_write , 否则请打开这两   
full_page_writes = off  
polar_has_partial_write = off   

# replication  # 注意  
primary_slot_name='replica1'    
primary_conninfo='host=172.17.0.2 port=5432 user=postgres dbname=postgres application_name=replica1'    
"
 >> ~/replica1/postgresql.conf     

pg_hba.conf

echo"      
host all all 0.0.0.0/0 md5      
host  replication postgres  172.17.0.0/16 trust      
"
 >> ~/replica1/pg_hba.conf      

标识节点以 Replica 模式启动

touch $HOME/replica1/replica.signal    

启动RO节点

pg_ctl start -D $HOME/replica1    

在pb1 RW节点, 检查slot状态是否正常, 修改数据

postgres=# select * from pg_stat_replication;  
 pid  | usesysid | usename  | application_name | client_addr | client_hostname | client_port |         backend_start         | backend_xmin |   state   |  sent_lsn  | write_lsn  | flush_lsn  | replay_ls  
n |    write_lag    |    flush_lag    |   replay_lag    | sync_priority | sync_state |          reply_time             
------+----------+----------+------------------+-------------+-----------------+-------------+-------------------------------+--------------+-----------+------------+------------+------------+----------  
--+-----------------+-----------------+-----------------+---------------+------------+-------------------------------  
 6299 |       10 | postgres | replica1         | 172.17.0.3  |                 |       53504 | 2024-12-24 14:13:34.411357+08 |              | streaming | 0/40945F50 | 0/40945F50 | 0/40945F50 | 0/40945F5  
0 | 00:00:00.000111 | 00:00:00.000111 | 00:00:00.000328 |             0 | async      | 2024-12-24 14:14:01.09425+08  
  215 |       10 | postgres | standby1         | 172.17.0.4  |                 |       53910 | 2024-12-24 14:07:11.652935+08 |              | streaming | 0/40945F50 | 0/40945F50 | 0/40945F50 | 0/40945F5  
0 | 00:00:00.000422 | 00:00:00.000468 | 00:00:00.000696 |             0 | async      | 2024-12-24 14:14:01.094546+08  
(2 rows)  

postgres=# insert into t1 values (200);  
INSERT 0 1  
postgres=# select * from t1;  
 id    
-----  
   1  
 100  
 200  
(3 rows)  

在pb2 检查修改已生效

postgres=# select * from t1;  
 id    
-----  
   1  
 100  
 200  
(3 rows)  

到此RO节点完成修复.

参考

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

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

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

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

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

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

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

《穷鬼玩PolarDB RAC一写多读集群系列 | 时间点恢复(PITR)》

《穷鬼玩PolarDB RAC一写多读集群系列 | 读写分离》

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

当然一款数据库要流行起来, 除了自己要强大, 还离不开生态. 用好周边生态工具, 管理水平战胜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