PostgreSQL码农集散地

穷鬼玩PolarDB RAC系列 | 共享存储在线扩容

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


穷鬼玩PolarDB RAC系列 | 共享存储在线扩容

继续穷鬼玩PolarDB RAC一写多读集群系列, 上2篇分别介绍了《在Docker容器中用loop设备模拟共享存储》 ,《如何搭建PolarDB容灾(standby)节点》 .

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

还需要参考如下文档:

  • https://apsaradb.github.io/PolarDB-for-PostgreSQL/zh/operation/grow-storage.html#%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F%E5%B1%82%E6%89%A9%E5%AE%B9

DEMO

现在虚拟磁盘20GB

-rw-r--r--   1 digoal  staff    20G Dec 18 11:19 VirtualDisk.img  

1、宿主机, 扩容虚拟磁盘/data_volumn/VirtualDisk.img , 例如扩容10GB.

cd ~/data_volumn     
dd if=/dev/zero bs=1m count=10240 oflag=direct >> ~/data_volumn/VirtualDisk.img      

扩容后变成了30GB

$ ll  ~/data_volumn/VirtualDisk.img  
-rw-r--r--  1 digoal  staff    30G Dec 18 11:30 /Users/digoal/data_volumn/VirtualDisk.img  

2、在pb1容器中可以看到虚拟磁盘已经变成了30GB

$ ll -h /data/VirtualDisk.img  
-rw-r--r-- 1 postgres postgres 30G Dec 18 11:30 /data/VirtualDisk.img  

3、容器pb1, 扩容loop设备

当前loop1对应的该虚拟磁盘, 显示还是20G

$ losetup -l /dev/loop1  
NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE             DIO LOG-SEC  
/dev/loop1         0      0         0  0 /data/VirtualDisk.img   1     512  

$ lsblk |grep loop1  
loop1    7:1    0    20G  0 loop  

刷新loop1设备容量:

$ sudo losetup -c /dev/loop1  

可以看到, loop设备变成30G了

postgres@dad7520e4620:~/primary$ lsblk |grep loop1  
loop1    7:1    0    30G  0 loop   

pb2 , pb3 容器都变成了30G, 这个还和macOS docker容器技术有关, 如果你的环境没有变化, 可能需要在PolarDB其他容器内也做相应的刷新操作.

postgres@60d4e0a501f7:~/replica1$ lsblk|grep loop1  
loop1    7:1    0    30G  0 loop   

4、文件系统扩容. 使用 PFS 文件系统提供的工具,对块设备上扩大后的物理空间进行格式化,以完成文件系统层面的扩容。

在能够访问共享存储的 任意一台主机上 运行 PFS 的 growfs 命令

$ sudo pfs -C disk growfs -h  
pfs growfs [-o|--oldcknum=n1] [-n|--newcknum=n2] [-f|--force] pbdname  
  -h, --help:             show this help message  
  -o, --oldcknum:         old chunk number(10GB/chunk)  
  -n, --newcknum:         new chunk number  
  -f, --force:            growfs forcedly (default is disabled)  

其中:

-o 表示共享存储扩容前的空间(以 10GB 为单位)  
-n 表示共享存储扩容后的空间(以 10GB 为单位)  

如果你不知道存储目前有多大, 可以使用dumpfs的结果进行计算:

$ sudo pfs -C disk dumpfs nvme1n1  
pfs tool cmd record:dumpfs nvme1n1   
[PFS_LOG] Dec 18 13:38:14.693399 INF [31813] pfs build version:libpfs_version_("pfsd-build-desc-_-Wed Sep  4 17:22:25 CST 2024")  
[PFS_LOG] Dec 18 13:38:14.693504 INF [31813] pid: 31812, caller: sudo pfs -C disk dumpfs nvme1n1    
[PFS_LOG] Dec 18 13:38:14.693524 INF [31813] pid: 31811, caller: sudo pfs -C disk dumpfs nvme1n1    
[PFS_LOG] Dec 18 13:38:14.693554 INF [31813] pid: 14, caller: bash    
[PFS_LOG] Dec 18 13:38:14.693579 INF [31813] open device cluster disk, devname nvme1n1, flags 0x1  
[PFS_LOG] Dec 18 13:38:14.693588 INF [31813] disk dev path: /dev/nvme1n1  
[PFS_LOG] Dec 18 13:38:14.693603 INF [31813] open local disk: open(/dev/nvme1n1, 0x10000)  
chunk 0:   
    ck_magic   0x504653434a  
    ck_chunksize 10737418240  
    ck_blksize 4194304  
    ck_sectsize 4096  
    ck_number  0  
    ck_nchunk  2  
    ck_checksum 2397668946  
    ck_physet[MT_BLKTAG].ms_nsect 80  
    ck_physet[MT_DIRENTRY].ms_nsect 64  
    ck_physet[MT_INODE].ms_nsect 64  
    ck_physet[MT_BLKTAG].ms_sectbda 0x1000  
    ck_physet[MT_DIRENTRY].ms_sectbda 0x51000  
    ck_physet[MT_INODE].ms_sectbda 0x91000  
chunk 1:   
    ck_magic   0x5046534348  
    ck_chunksize 10737418240  
    ck_blksize 4194304  
    ck_sectsize 4096  
    ck_number  1  
    ck_nchunk  2  
    ck_checksum 86206895  
    ck_physet[MT_BLKTAG].ms_nsect 80  
    ck_physet[MT_DIRENTRY].ms_nsect 64  
    ck_physet[MT_INODE].ms_nsect 64  
    ck_physet[MT_BLKTAG].ms_sectbda 0x280001000  
    ck_physet[MT_DIRENTRY].ms_sectbda 0x280051000  
    ck_physet[MT_INODE].ms_sectbda 0x280091000  
type free used total  
blktag 4861 259 5120  
dentry 4093 3 4096  
inode 4093 3 4096  

所有chunkck_chunksize相加, 或者ck_blksize 4194304 * blktag total 5120 =

postgres=# select pg_size_pretty(4194304*5120::int8);  
 pg_size_pretty   
----------------  
 20 GB  
(1 row)  

本例将共享存储从 20GB 扩容至 30GB:

sudo pfs -C disk growfs -o 2 -n 3 nvme1n1  

日志如下:  

pfs tool cmd record:growfs -o 2 -n 3 nvme1n1   
[PFS_LOG] Dec 18 13:48:34.705607 INF [31841] pfs build version:libpfs_version_("pfsd-build-desc-_-Wed Sep  4 17:22:25 CST 2024")  
[PFS_LOG] Dec 18 13:48:34.705750 INF [31841] pid: 31840, caller: sudo pfs -C disk growfs -o 2 -n 3 nvme1n1    
[PFS_LOG] Dec 18 13:48:34.705783 INF [31841] pid: 31839, caller: sudo pfs -C disk growfs -o 2 -n 3 nvme1n1    
[PFS_LOG] Dec 18 13:48:34.705799 INF [31841] pid: 14, caller: bash    
Init chunk 2  
  metaset        2/1: sectbda      0x500001000, npage       80, objsize  128, nobj 2560, oid range [    2000,     2a00)  
  metaset        2/2: sectbda      0x500051000, npage       64, objsize  128, nobj 2048, oid range [    1000,     1800)  
  metaset        2/3: sectbda      0x500091000, npage       64, objsize  128, nobj 2048, oid range [    1000,     1800)  

pfs growfs succeeds!  

查看pfs nvme1n1元数据, 可以看到pfs已扩容成功

$ sudo pfs -C disk dumpfs nvme1n1  
pfs tool cmd record:dumpfs nvme1n1   
[PFS_LOG] Dec 18 13:55:57.320348 INF [31867] pfs build version:libpfs_version_("pfsd-build-desc-_-Wed Sep  4 17:22:25 CST 2024")  
[PFS_LOG] Dec 18 13:55:57.320437 INF [31867] pid: 31866, caller: sudo pfs -C disk dumpfs nvme1n1    
[PFS_LOG] Dec 18 13:55:57.320459 INF [31867] pid: 31865, caller: sudo pfs -C disk dumpfs nvme1n1    
[PFS_LOG] Dec 18 13:55:57.320472 INF [31867] pid: 14, caller: bash    
[PFS_LOG] Dec 18 13:55:57.320503 INF [31867] open device cluster disk, devname nvme1n1, flags 0x1  
[PFS_LOG] Dec 18 13:55:57.320516 INF [31867] disk dev path: /dev/nvme1n1  
[PFS_LOG] Dec 18 13:55:57.320520 INF [31867] open local disk: open(/dev/nvme1n1, 0x10000)  
chunk 0:   
    ck_magic   0x504653434a  
    ck_chunksize 10737418240  
    ck_blksize 4194304  
    ck_sectsize 4096  
    ck_number  0  
    ck_nchunk  3  
    ck_checksum 2262034622  
    ck_physet[MT_BLKTAG].ms_nsect 80  
    ck_physet[MT_DIRENTRY].ms_nsect 64  
    ck_physet[MT_INODE].ms_nsect 64  
    ck_physet[MT_BLKTAG].ms_sectbda 0x1000  
    ck_physet[MT_DIRENTRY].ms_sectbda 0x51000  
    ck_physet[MT_INODE].ms_sectbda 0x91000  
chunk 1:   
    ck_magic   0x5046534348  
    ck_chunksize 10737418240  
    ck_blksize 4194304  
    ck_sectsize 4096  
    ck_number  1  
    ck_nchunk  3  
    ck_checksum 219744067  
    ck_physet[MT_BLKTAG].ms_nsect 80  
    ck_physet[MT_DIRENTRY].ms_nsect 64  
    ck_physet[MT_INODE].ms_nsect 64  
    ck_physet[MT_BLKTAG].ms_sectbda 0x280001000  
    ck_physet[MT_DIRENTRY].ms_sectbda 0x280051000  
    ck_physet[MT_INODE].ms_sectbda 0x280091000  
chunk 2:   
    ck_magic   0x5046534348  
    ck_chunksize 10737418240  
    ck_blksize 4194304  
    ck_sectsize 4096  
    ck_number  2  
    ck_nchunk  3  
    ck_checksum 3123774169  
    ck_physet[MT_BLKTAG].ms_nsect 80  
    ck_physet[MT_DIRENTRY].ms_nsect 64  
    ck_physet[MT_INODE].ms_nsect 64  
    ck_physet[MT_BLKTAG].ms_sectbda 0x500001000  
    ck_physet[MT_DIRENTRY].ms_sectbda 0x500051000  
    ck_physet[MT_INODE].ms_sectbda 0x500091000  
type free used total  
blktag 7420 260 7680  
dentry 6141 3 6144  
inode 6141 3 6144  

5、数据库实例层扩容, 所有PolarDB 计算节点共享存储的pfsd守护进程都需要刷新一下, 才能知道新空间已经可以被使用了.

在pb1 primary 节点创建polar_vfs插件:

CREATE EXTENSION IF NOT EXISTS polar_vfs;  

在所有replica节点执行以下函数, 函数的参数名为块设备名, 最后在pb1 primary节点执行,注意先后顺序.

SELECT polar_vfs_disk_expansion('nvme1n1');  

返回如下:  
 polar_vfs_disk_expansion   
--------------------------  
 t  
(1 row)  

执行完毕后,数据库实例层面的扩容也就完成了。此时,新的存储空间已经能够被数据库使用了。

参考

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

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

https://apsaradb.github.io/PolarDB-for-PostgreSQL/zh/operation/grow-storage.html#%E6%95%B0%E6%8D%AE%E5%BA%93%E5%AE%9E%E4%BE%8B%E5%B1%82%E6%89%A9%E5%AE%B9

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

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