PolarDB PostgreSQL(下文简称为 PolarDB)是一款阿里云自主研发的云原生数据库产品,100% 兼容 PostgreSQL,采用基于 Shared-Storage 的存储计算分离架构,具有极致弹性、毫秒级延迟、HTAP 的能力。
- 极致弹性:存储与计算能力均可独立地横向扩展。
- 当计算能力不够时,可以单独扩展计算集群,数据无需复制。
- 当存储容量或 I/O 不够时,可以单独扩展存储集群,而不中断业务。
- 毫秒级延迟:
- WAL 日志存储在共享存储上,RW 到所有 RO 之间仅复制 WAL 的元数据。
- 独创的 LogIndex 技术,实现了 Lazy 回放和 Parallel 回放,理论上最大程度地缩小了 RW 和 RO 节点间的延迟。
- HTAP 能力:基于 Shared-Storage 的分布式并行执行框架,加速在 OLTP 场景下的 OLAP 查询。一套 OLTP 型的数据,可支持 2 套计算引擎:
- 单机执行引擎:处理高并发的 TP 型负载。
- 分布式执行引擎:处理大查询的 AP 型负载。
PolarDB 还支持时空、GIS、图像、向量、搜索、图谱等多模创新特性,应对企业对数据处理日新月异的需求。
另外,除了上述 Shared-Storage 云原生的模式,PolarDB 还支持以 Shared-Nothing 模式部署,详见 distribute 分支的 README。
PolarDB 后续默认分支为 main 分支,支持存储计算分离的形态。分布式形态由 distribute 分支支持(对应之前的 master 分支)。
PolarDB 采用了基于 Shared-Storage 的存储计算分离架构。数据库由传统的 Share-Nothing 架构,转变成了 Shared-Storage 架构。由原来的 N 份计算 + N 份存储,转变成了 N 份计算 + 1 份存储。虽然共享存储上数据是一份,但是数据在各节点内存中的状态是不同的,需要通过内存状态的同步来维护数据的一致性;同时主节点在刷脏时也需要做协调,避免只读节点读取到超前的 “未来页面”,也要避免只读节点读取到过时的没有在内存中被正确回放的 “过去页面”。为了解决该问题,PolarDB 创造性地设计了 LogIndex 数据结构来维护页面的回放历史,该结构能够实现主节点与只读节点之间的同步。
在存储计算分离后,I/O 单路延迟变大的同时,I/O 的吞吐也变大了。在处理分析型查询时,仅使用单个只读节点无法发挥出存储侧的大 I/O 带宽优势,也无法利用其他只读节点的 CPU、内存和 I/O 资源。为了解决该问题,PolarDB 研发了基于 Shared-Storage 的并行执行引擎,能够在 SQL 级别上弹性利用任意数目的 CPU 来加速分析查询,支持 HTAP 的混合负载场景。
- 产品架构
- 版本规划
- PolarDB PostgreSQL 1.0 版本功能特性
- 数据库监控(即将上线)
- PolarDB Stack
- PolarVFS(即将上线)
我们提供了三种途径来使用PolarDB数据库:阿里巴巴云服务、搭建本地存储的实例、搭建基于 PolarDB Stack共享存储的实例。
阿里云云原生关系型数据库 PolarDB PostgreSQL 引擎:官网地址。
我们提供了一键部署脚本,助您快速编译 PolarDB 内核并搭建本地实例。本节介绍了如何通过提供的一键部署脚本,快速搭建存储为本地磁盘的 PolarDB 实例。
操作系统要求:CentOS 7.5 及以上。以下步骤在 CentOS 7.5 上通过测试。
说明:请使用同一个用户进行以下步骤。请勿使用 root 用户搭建实例。
-
从 这里 下载 PolarDB 源代码。
-
安装相关依赖:
sudo yum install readline-devel zlib-devel perl-CPAN bison flex sudo cpan -fi Test::More IPC::Run
-
根据不同的搭建场景,可选择不同的脚本执行命令:
-
只编译数据库源码,不创建本地实例:
./polardb_build.sh --noinit
-
编译并创建本地单节点实例,节点为主节点(端口为 5432):
./polardb_build.sh
-
编译并创建本地多节点实例,节点包括:
- 1 个主节点(端口为 5432)
- 1 个只读节点(端口为 5433)
./polardb_build.sh --withrep --repnum=1
-
编译并创建本地多节点实例,节点包括:
- 1 个主节点(端口为 5432)
- 1 个只读节点(端口为 5433)
- 1 个备库节点(端口为 5434)
./polardb_build.sh --withrep --repnum=1 --withstandby
-
编译并创建本地多节点实例,节点包括:
- 1 个主节点(端口为 5432)
- 2 个只读节点(端口分别为 5433 与 5434)
- 1 个备库节点(端口为 5435)
./polardb_build.sh --withrep --repnum=2 --withstandby
-
-
部署完成后,需要进行实例检查和测试,确保部署正确。
-
实例检查:
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/psql -p 5432 -c 'select version();' $HOME/tmp_basedir_polardb_pg_1100_bld/bin/psql -p 5432 -c 'select * from pg_replication_slots;'
-
一键执行全量回归测试:
./polardb_build.sh --withrep --repnum=1 --withstandby -r-check-all -e -r-contrib -r-pl -r-external -r-installcheck-all
-
Network Block Device(NBD)是一种网络协议,可以在多个主机间共享块存储设备,它是Client-Server的架构,因此至少需要两台物理机来部署。
以两台物理机环境为例,本小节介绍基于NBD共享存储的实例构建方法大体如下:首先,两台主机通过NBD共享一个块设备;然后,两台主机上均部署PolarDB-FileSystem(PFS)来初始化并挂载到同一个块设备;最后,在两台主机上分别部署PolarDB-for-PostgreSQL内核,构建主节点、只读节点已形成简单的一写多读实例。
操作系统要求:CentOS 7.5 及以上。以下步骤在 CentOS 7.5 上通过测试。
- 安装NBD
- 操作系统支持NBD驱动
说明:操作系统内核需要支持NBD内核模块,如果操作系统当前不支持该内核模块,则需要自己通过对应内核版本进行编译和加载NBD内核模块。
- CentOS官网下载对应内核源码包并解压:
rpm -ihv kernel-3.10.0-862.el7.src.rpm cd ~/rpmbuild/SOURCES tar Jxvf linux-3.10.0-862.el7.tar.xz -C /usr/src/kernels/ cd /usr/src/kernels/linux-3.10.0-862.el7/
- NBD驱动源码路径位于:drivers/block/nbd.c;
- 编译操作系统内核依赖和组件:
cp ../$(uname -r)/Module.symvers ./ make menuconfig # Device Driver -> Block devices -> Set 'M' On 'Network block device support' make prepare && make modules_prepare && make scripts make CONFIG_BLK_DEV_NBD=m M=drivers/block
- 检查是否正常生成驱动:
modinfo drivers/block/nbd.ko
- 拷贝、生成依赖并安装驱动:
cp drivers/block/nbd.ko /lib/modules/$(uname -r)/kernel/drivers/block depmod -a modprobe nbd # 或者 modprobe -f nbd 可以忽略模块版本检查
- 检查是否安装成功:
# 检查已安装内核模块 lsmod | grep nbd # 如果NBD驱动已经安装,则会生成/dev/nbd*设备(例如:/dev/nbd0、/dev/nbd1等) ls /dev/nbd*
- CentOS官网下载对应内核源码包并解压:
- 安装NBD软件包
yum install nbd
- 使用NBD来共享块设备
- 服务端部署
- 拉起NBD服务端,按照同步方式(sync/flush=true)配置,在指定端口(例如:1921)上监听对指定块设备(例如:/dev/vdb)的访问。
nbd-server -C /root/nbd.conf
- 配置文件/root/nbd.conf的内容举例如下:
[generic] #user = nbd #group = nbd listenaddr = 0.0.0.0 port = 1921 [export1] exportname = /dev/vdb readonly = false multifile = false copyonwrite = false flush = true fua = true sync = true
- 拉起NBD服务端,按照同步方式(sync/flush=true)配置,在指定端口(例如:1921)上监听对指定块设备(例如:/dev/vdb)的访问。
- 客户端部署
- NBD驱动安装成功后会看到/dev/nbd*设备, 根据服务端的配置把远程块设备映射为本地的某个NBD设备即可:
nbd-client x.x.x.x 1921 -N export1 /dev/nbd0 # x.x.x.x是NBD服务端主机的IP地址
- NBD驱动安装成功后会看到/dev/nbd*设备, 根据服务端的配置把远程块设备映射为本地的某个NBD设备即可:
- PolarDB-FileSystem安装部署
- PFS编译安装,参见其README
- 块设备重命名
- PFS仅支持特定字符开头的块设备进行访问,建议所有块设备访问节点都通过软链接使用相同名字访问共享块设备。例如:在NBD服务端主机上执行:ln -s /dev/vdb /dev/nvme0n1, NBD客户端主机上执行:ln -s /dev/nbd0 /dev/nvme0n1。
- 如此,便可以在服务端和客户端2台主机,使用相同的路径/dev/nvme0n1来访问同一个块设备。
- 块设备初始化
- 只在NBD服务端执行PFS操作来格式化共享块设备即可:
sudo pfs -C disk mkfs nvme0n1
- 只在NBD服务端执行PFS操作来格式化共享块设备即可:
- 块设备挂载
- 在NBD服务端和客户端上,分别启动PFS,挂载共享盘:
sudo /usr/local/polarstore/pfsd/bin/start_pfsd.sh -p nvme0n1
- 在NBD服务端和客户端上,分别启动PFS,挂载共享盘:
- PolarDB-for-PostgreSQL内核安装部署
说明:请使用同一个用户进行以下步骤。请勿使用 root 用户搭建实例。
- 主节点部署
- 内核编译:
./polardb_build.sh --noinit --with-pfsd
- 节点初始化
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/initdb -D primary # 共享存储初始化 sudo pfs -C disk mkdir /nvme0n1/shared_data sudo /home/[$USER]/tmp_basedir_polardb_pg_1100_bld/bin/polar-initdb.sh /home/[$USER]/primary/ /nvme0n1/shared_data/
- 节点配置
- 打开postgresql.conf,增加以下配置项:
port=5432 polar_hostid=1 polar_enable_shared_storage_mode=on polar_disk_name='nvme0n1' polar_datadir='/nvme0n1/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='*' max_connections=1000 synchronous_standby_names='replica1'
- 打开pg_hba.conf,增加以下配置项:
host replication [$USER] 0.0.0.0/0 trust
- 打开postgresql.conf,增加以下配置项:
- 启动与检查
- 启动
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/pg_ctl start -D $HOME/primary
- 检查
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/psql -p 5432 -d postgres -c 'select version();'
- 启动
- 只读节点的流复制准备
- 创建相应的replication slot,用于接下来创建的只读节点的物理流复制
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/psql -p 5432 -d postgres -c "select pg_create_physical_replication_slot('replica1');"
- 创建相应的replication slot,用于接下来创建的只读节点的物理流复制
- 内核编译:
- 只读节点部署
- 内核编译
./polardb_build.sh --noinit --with-pfsd
- 节点初始化
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/initdb -D replica1
- 节点配置
- 打开postgresql.conf,增加以下配置项:
port=5433 polar_hostid=2 polar_enable_shared_storage_mode=on polar_disk_name='nvme0n1' polar_datadir='/nvme0n1/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='*' max_connections=1000
- 创建recovery.conf,增加以下配置项:
polar_replica='on' recovery_target_timeline='latest' primary_slot_name='replica1' primary_conninfo='host=[主节点所在容器的IP] port=5432 user=[$USER] dbname=postgres application_name=replica1'
- 打开postgresql.conf,增加以下配置项:
- 启动与检查
- 启动
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/pg_ctl start -D $HOME/replica1
- 检查
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/psql -p 5433 -d postgres -c 'select version();'
- 启动
- 内核编译
- 实例检查和测试
- 部署完成后,需要进行实例检查和测试,确保主节点可正常写入数据、只读节点可以正常读取。
- 登录主节点,创建测试表并插入样例数据:
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/psql -q -p 5432 -d postgres -c "create table t(t1 int primary key, t2 int);insert into t values (1, 1),(2, 3),(3, 3);"
- 登录只读节点,查询刚刚插入的样例数据:
$HOME/tmp_basedir_polardb_pg_1100_bld/bin/psql -q -p 5433 -d postgres -c "select * from t;"
PolarDB Stack是轻量级PolarDB PaaS软件。基于共享存储提供一写多读的PolarDB数据库服务,特别定制和深度优化了数据库生命周期管理。通过PolarDB Stack可以一键部署PolarDB-for-PostgreSQL内核和PolarDB-FileSystem。
PolarDB Stack架构如下图所示,进入PolarDB Stack的部署文档
PolarDB 的代码的发布基于 Apache 2.0 版本和 PostgreSQL 代码的软件许可。相关的许可说明可参见 LICENSE 和 NOTICE。
部分代码和设计思路参考了其他开源项目,例如:PG-XC/XL (pgxc_ctl)、TBase (部分基于时间戳的 vacuum 和 MVCC)、Greenplum 以及 Citus (pg_cron)。感谢以上开源项目的贡献。
-
PolarDB PostgreSQL Slack:https://app.slack.com/client/T023NM10KGE/C023VEMKS02
-
使用钉钉扫描如下二维码,加入PolarDB技术推广组钉钉群
Copyright © Alibaba Group, Inc.