我用 2G 服务器跑通了 OpenTenBase!分布式数据库 Docker 化部署全过程
文章详细介绍了OpenTenBase的HTAP架构(包含GTM、Coordinator和Datanode节点),并列举了编译内存不足、依赖包缺失、GTM初始化失败等常见问题的解决方法。该方案大幅简化了OpenTenBase的部署流程,从原本需要手动配置多个节点和端口,优化为仅需两条命令
前言
说实话,我差点被 OpenTenBase 的部署逼疯了。
作为一个学生,只有一台 2G 内核、1 核 CPU 的腾讯云服务器,想要研究国产分布式数据库 OpenTenBase 的源码和架构。
结果发现:
官方部署流程太复杂了!
需要:
- 编译 30-60 分钟
- 手动配置 14 个步骤
- 分别初始化 GTM、Coordinator、Datanode
- 手动注册节点到
pgxc_node表 - 配置一堆端口和参数
而且,编译到一半就报错,内存不够,CPU 跑满,Docker 容器各种依赖问题…
折腾了三天,我终于把 OpenTenBase 做成了 Docker 一键部署 版本!
现在,只需要 2 命令就能启动完整的 OpenTenBase 集群。
一、OpenTenBase 是什么
OpenTenBase 是腾讯开源的分布式 HTAP 数据库,基于 PostgreSQL 10 开发。
简单说:
- HTAP: 同时支持 OLTP(事务)和 OLAP(分析)
- 分布式: 支持水平扩展,数据自动分片
- 高可用: 支持主备切换、故障自动恢复
架构是这样的:
┌─────────────────────────────────────────────────────────────┐
│ OpenTenBase 集群 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────┐ │
│ │ GTM │ ← 全局事务管理器(Port: 6666) │
│ └─────┬────┘ │
│ │ │
│ ┌─────┴────┐ │
│ │ │ │
│ ┌──▼───┐ ┌──▼───┐ ┌────────┐ │
│ │ CN1 │ │ CN2 │ ... │ CNx │ ← 协调节点(Port: 5432) │
│ └──┬───┘ └──┬───┘ └────────┘ │
│ │ │ │
│ └────┬───┘ │
│ │ │
│ ┌────┴────┐ │
│ │ │ │
│ ┌──▼───┐ ┌──▼───┐ ┌────────┐ │
│ │ DN1 │ │ DN2 │ ... │ DNx │ ← 数据节点(Port: 15432) │
│ └──────┘ └──────┘ └────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

二、为什么官方部署痛苦
2.1 官方部署流程(14 个步骤!)
# 1. 克隆源码
git clone https://github.com/OpenTenBase/OpenTenBase.git
# 2. 安装依赖(30+ 个包)
apt install build-essential bison flex perl \
libreadline-dev zlib1g-dev libssl-dev libpam0g-dev \
libxml2-dev libldap2-dev libossp-uuid-dev uuid-dev \
libcurl4-openssl-dev liblz4-dev libzstd-dev \
libcli11-dev libpqxx-dev libtool pkg-config
# 3. 编译(30-60 分钟)
./configure --prefix=/usr/local/opentenbase
make -j4
make install
# 4. 初始化 GTM
initgtm -D /path/to/gtm_data
# 5. 初始化 Coordinator
initdb -D /path/to/coord_data \
--nodename=coord1 --nodetype=coordinator \
--master_gtm_nodename=gtm_master \
--master_gtm_ip=127.0.0.1 \
--master_gtm_port=6666
# 6. 初始化 Datanode
initdb -D /path/to/dn_data \
--nodename=dn001 --nodetype=datanode \
--master_gtm_nodename=gtm_master \
--master_gtm_ip=127.0.0.1 \
--master_gtm_port=6666
# 7. 配置 postgresql.conf
vim /path/to/coord_data/postgresql.conf
vim /path/to/dn_data/postgresql.conf
# 8. 启动 GTM
gtm_ctl -D /path/to/gtm_data start
# 9. 启动 Coordinator
pg_ctl -D /path/to/coord_data start
# 10. 启动 Datanode
pg_ctl -D /path/to/dn_data start
# 11. 注册节点(在 Coordinator 上执行)
psql -p 5432 -c "CREATE GTM NODE gtm_master WITH (HOST='127.0.0.1', PORT=6666, PRIMARY);"
psql -p 5432 -c "CREATE NODE coord1 WITH (TYPE='coordinator', HOST='127.0.0.1', PORT=5432, FORWARD=6669);"
psql -p 5432 -c "CREATE NODE dn001 WITH (TYPE='datanode', HOST='127.0.0.1', PORT=15432, FORWARD=6670, PRIMARY, PREFERRED);"
# 12. 注册节点(在 Datanode 上执行)
psql -p 15432 -c "CREATE GTM NODE gtm_master WITH (HOST='127.0.0.1', PORT=6666, PRIMARY);"
psql -p 15432 -c "CREATE NODE coord1 WITH (TYPE='coordinator', HOST='127.0.0.1', PORT=5432);"
# 13. 重载连接池
psql -p 5432 -c "SELECT pgxc_pool_reload();"
# 14. 设置默认节点组
psql -p 5432 -c "CREATE NODE GROUP default_group WITH (dn001);"

任何一个步骤出错,整个集群就无法启动。
而且:
- 编译需要 30-60 分钟
- 2G 服务器内存不够
- 依赖包问题频繁
- 端口冲突、权限问题
- 配置文件复杂
2.2 我遇到的坑
坑 1:编译内存不够
错误信息:
c++: internal compiler error: Killed (program cc1plus)
原因:2G 内存不够编译 OpenTenBase
解决:增加 swap 或者用更大的服务器
[占位符:编译报错截图]
坑 2:依赖包找不到
错误信息:
E: Unable to locate package libcli11-dev
E: Package libpqxx-dev is not available
原因:不同 Ubuntu 版本包名不同
解决:
apt-get install -y libcli11-dev || apt-get install -y libcli-dev
apt-get install -y libpqxx-dev || apt-get install -y libpqxx-7-dev
坑 3:GTM 初始化失败
错误信息:
initgtm: could not initialize GTM
原因:端口冲突或权限问题
解决:检查端口占用,确保用户权限
坑 4:节点注册失败
错误信息:
ERROR: can not get master gtm info from pgxc_node
原因:OpenTenBase v5.0 改用 pgxc_node 表注册节点
解决:
CREATE GTM NODE gtm_master WITH (HOST='127.0.0.1', PORT=6666, PRIMARY);
CREATE NODE coord1 WITH (TYPE='coordinator', HOST='127.0.0.1', PORT=5432, FORWARD=6669);
坑 5:Docker 网络问题
错误信息:
could not connect to GTM: Connection refused
原因:Docker 容器网络隔离
解决:使用 Docker network 和 hostname 连接
坑 6:128-bit atomics 链接错误
错误信息:
undefined reference to `__sync_val_compare_and_swap_16'
原因:Debian 11/12 的 libatomic 不支持 128-bit atomics
解决:使用 __atomic_compare_exchange_n 替代
三、我的解决方案:Docker 一键部署
3.1 整体思路
不做源码编译,直接用 .deb 包 + Docker Compose。

3.2 环境准备
服务器要求:
- CPU: 1 核+
- 内存: 2GB+
- 磁盘: 10GB+
- 操作系统: Ubuntu 20.04/22.04/24.04, Debian 11/12
安装 Docker:
# Ubuntu/Debian
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# 安装 Docker Compose
sudo apt-get install docker-compose-plugin
四、Dockerfile 编写
4.1 运行时镜像
FROM ubuntu:24.04
# 非交互模式
ENV DEBIAN_FRONTEND=noninteractive
# 安装依赖
RUN apt-get update && apt-get install -y \
libreadline8 \
libssl3 \
libpam0g \
libxml2 \
libldap-2.5-0 \
libossp-uuid16 \
uuid-runtime \
libcurl4 \
liblz4-1 \
libzstd1 \
libssh2-1 \
&& rm -rf /var/lib/apt/lists/*
# 创建用户
RUN useradd -r -m -s /bin/bash opentenbase
# 复制 .deb 包
COPY opentenbase_5.0-1ubuntu1_all.deb /tmp/
COPY opentenbase-server_5.0-1ubuntu1_amd64.deb /tmp/
COPY opentenbase-client_5.0-1ubuntu1_amd64.deb /tmp/
COPY opentenbase-contrib_5.0-1ubuntu1_amd64.deb /tmp/
# 安装包
RUN dpkg -i /tmp/*.deb || apt-get install -f -y
# 设置工作目录
WORKDIR /usr/lib/opentenbase
# 暴露端口
EXPOSE 5432 6666 15432 6667 6668 6669 6670
# 默认用户
USER opentenbase
# 默认命令
CMD ["postgres"]
![**[占位符:Dockerfile 完整文件截图]**](https://i-blog.csdnimg.cn/direct/4cf26769b81c4fe79ae500f73d25072d.png)
4.2 构建镜像
# 1. 下载 .deb 包
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/opentenbase_5.0-1ubuntu1_all.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/opentenbase-server_5.0-1ubuntu1_amd64.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/opentenbase-client_5.0-1ubuntu1_amd64.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/opentenbase-contrib_5.0-1ubuntu1_amd64.deb
# 2. 构建镜像
docker build -t opentenbase/opentenbase:5.0 .
# 3. 查看镜像
docker images | grep opentenbase
# 1. 下载 .deb 包
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi8/opentenbase_5.0-1ubuntu1_all.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi8/opentenbase-server_5.0-1ubuntu1_amd64.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi8/opentenbase-client_5.0-1ubuntu1_amd64.deb
wget https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi8/opentenbase-contrib_5.0-1ubuntu1_amd64.deb
2. 构建镜像
docker build -t opentenbase/opentenbase:5.0 .
3. 查看镜像
docker images | grep opentenbase
![**\[占位符:构建过程截图\]**](https://i-blog.csdnimg.cn/direct/a89eb52d7a3c45bcb06b92a035fd543f.png)
---
## 五、deb 包制作
### 5.1 包结构
OpenTenBase 分成 6 个包:
| 包名 | 描述 | 大小 |
|------|------|------|
| `opentenbase` | 元包 | 2.2 KB |
| `opentenbase-server` | 服务器端 | 6.2 MB |
| `opentenbase-client` | 客户端工具 | 737 KB |
| `opentenbase-contrib` | 扩展组件 | 1.4 MB |
| `libopentenbase-dev` | 开发库 | 1.5 MB |
| `opentenbase-doc` | 文档 | 2.6 MB |
### 5.2 一键安装脚本
```bash
curl -sLO https://github.com/muzimu217/OpenTenBase-deb/releases/download/v5.0-multi9/install.sh
sudo bash install.sh
5.3 测试验证数据库启动
初始化集群
# 初始化 GTM + Coordinator + Datanode
opentenbase-ctl init
启动集群
# 启动所有节点
opentenbase-ctl start
检查状态
# 查看集群状态
opentenbase-ctl status
连接数据库
# 通过 psql 连接
opentenbase-psql -h 127.0.0.1 -p 5432 -U opentenbase -d postgres
停止集群
# 停止所有节点
opentenbase-ctl stop


好了,这个时候就可以使用OpenTenBase数据库了
以上内容是软件包的一键部署教程,如果是需要开发数据库的佬友,目前我们这边也是支持Docker Compose 一键集群部署:
六、docker compose 集群
此处是数据库开发者参考内容
6.1 docker-compose.yml
version: '3.8'
services:
gtm:
image: opentenbase/opentenbase:5.0
container_name: opentenbase-gtm
hostname: gtm
ports:
- "6666:6666"
volumes:
- gtm_data:/var/lib/opentenbase/gtm
- gtm_log:/var/log/opentenbase
environment:
- NODE_TYPE=gtm
- GTM_PORT=6666
- NODE_NAME=gtm_master
networks:
- opentenbase-net
command: >
bash -c "
install -d -o opentenbase -g opentenbase -m 0700 /var/lib/opentenbase/gtm
su - opentenbase -c '/usr/lib/opentenbase/bin/initgtm -Z gtm -D /var/lib/opentenbase/gtm'
su - opentenbase -c '/usr/lib/opentenbase/bin/gtm_ctl -D /var/lib/opentenbase/gtm -l /var/log/opentenbase/gtm.log start'
"
healthcheck:
test: ["CMD", "su", "-", "opentenbase", "-c", "pg_isready -p 6666"]
interval: 10s
timeout: 5s
retries: 5
coordinator:
image: opentenbase/opentenbase:5.0
container_name: opentenbase-coordinator
hostname: coordinator
ports:
- "5432:5432"
volumes:
- coord_data:/var/lib/opentenbase/coordinator
- coord_log:/var/log/opentenbase
environment:
- NODE_TYPE=coordinator
- COORD_PORT=5432
- GTM_HOST=gtm
- GTM_PORT=6666
- NODE_NAME=coord1
networks:
- opentenbase-net
depends_on:
gtm:
condition: service_healthy
command: >
bash -c "
install -d -o opentenbase -g opentenbase -m 0700 /var/lib/opentenbase/coordinator
su - opentenbase -c '/usr/lib/opentenbase/bin/initdb -D /var/lib/opentenbase/coordinator --nodename=coord1 --nodetype=coordinator --master_gtm_nodename=gtm_master --master_gtm_ip=gtm --master_gtm_port=6666 -E UTF8 -U opentenbase'
sed -i 's/port = 5432/port = 5432/' /var/lib/opentenbase/coordinator/postgresql.conf
su - opentenbase -c '/usr/lib/opentenbase/bin/pg_ctl -D /var/lib/opentenbase/coordinator -l /var/log/opentenbase/coord.log start'
sleep 5
su - opentenbase -c '/usr/lib/opentenbase/bin/psql -p 5432 -c \"CREATE GTM NODE gtm_master WITH (HOST=\\'gtm\\', PORT=6666, PRIMARY);\"'
su - opentenbase -c '/usr/lib/opentenbase/bin/psql -p 5432 -c \"CREATE NODE coord1 WITH (TYPE=\\'coordinator\\', HOST=\\'coordinator\\', PORT=5432, FORWARD=6669);\"'
tail -f /var/log/opentenbase/coord.log
"
healthcheck:
test: ["CMD", "su", "-", "opentenbase", "-c", "pg_isready -p 5432"]
interval: 10s
timeout: 5s
retries: 5
dn1:
image: opentenbase/opentenbase:5.0
container_name: opentenbase-dn1
hostname: dn1
ports:
- "15432:15432"
volumes:
- dn1_data:/var/lib/opentenbase/dn1
- dn1_log:/var/log/opentenbase
environment:
- NODE_TYPE=datanode
- DN_PORT=15432
- GTM_HOST=gtm
- GTM_PORT=6666
- NODE_NAME=dn001
networks:
- opentenbase-net
depends_on:
coordinator:
condition: service_healthy
command: >
bash -c "
install -d -o opentenbase -g opentenbase -m 0700 /var/lib/opentenbase/dn1
su - opentenbase -c '/usr/lib/opentenbase/bin/initdb -D /var/lib/opentenbase/dn1 --nodename=dn001 --nodetype=datanode --master_gtm_nodename=gtm_master --master_gtm_ip=gtm --master_gtm_port=6666 -E UTF8 -U opentenbase'
su - opentenbase -c '/usr/lib/opentenbase/bin/pg_ctl -D /var/lib/opentenbase/dn1 -l /var/log/opentenbase/dn1.log start'
sleep 5
su - opentenbase -c '/usr/lib/opentenbase/bin/psql -h coordinator -p 5432 -c \"CREATE NODE dn001 WITH (TYPE=\\'datanode\\', HOST=\\'dn1\\', PORT=15432, FORWARD=6670, PRIMARY, PREFERRED);\"'
su - opentenbase -c '/usr/lib/opentenbase/bin/psql -h coordinator -p 5432 -c \"SELECT pgxc_pool_reload();\"'
tail -f /var/log/opentenbase/dn1.log
"
healthcheck:
test: ["CMD", "su", "-", "opentenbase", "-c", "pg_isready -p 15432"]
interval: 10s
timeout: 5s
retries: 5
dn2:
image: opentenbase/opentenbase:5.0
container_name: opentenbase-dn2
hostname: dn2
ports:
- "15433:15433"
volumes:
- dn2_data:/var/lib/opentenbase/dn2
- dn2_log:/var/log/opentenbase
environment:
- NODE_TYPE=datanode
- DN_PORT=15433
- GTM_HOST=gtm
- GTM_PORT=6666
- NODE_NAME=dn002
networks:
- opentenbase-net
depends_on:
coordinator:
condition: service_healthy
command: >
bash -c "
install -d -o opentenbase -g opentenbase -m 0700 /var/lib/opentenbase/dn2
su - opentenbase -c '/usr/lib/opentenbase/bin/initdb -D /var/lib/opentenbase/dn2 --nodename=dn002 --nodetype=datanode --master_gtm_nodename=gtm_master --master_gtm_ip=gtm --master_gtm_port=6666 -E UTF8 -U opentenbase'
su - opentenbase -c '/usr/lib/opentenbase/bin/pg_ctl -D /var/lib/opentenbase/dn2 -l /var/log/opentenbase/dn2.log start'
sleep 5
su - opentenbase -c '/usr/lib/opentenbase/bin/psql -h coordinator -p 5432 -c \"CREATE NODE dn002 WITH (TYPE=\\'datanode\\', HOST=\\'dn2\\', PORT=15433, FORWARD=6671);\"'
su - opentenbase -c '/usr/lib/opentenbase/bin/psql -h coordinator -p 5432 -c \"SELECT pgxc_pool_reload();\"'
tail -f /var/log/opentenbase/dn2.log
"
healthcheck:
test: ["CMD", "su", "-", "opentenbase", "-c", "pg_isready -p 15433"]
interval: 10s
timeout: 5s
retries: 5
networks:
opentenbase-net:
driver: bridge
volumes:
gtm_data:
gtm_log:
coord_data:
coord_log:
dn1_data:
dn1_log:
dn2_data:
dn2_log:
6.2 启动集群
# 1. 启动集群
docker compose up -d
# 2. 查看状态
docker compose ps
输出应该是这样:
NAME COMMAND SERVICE STATUS
opentenbase-coordinator "bash -c install -d …" coordinator running
opentenbase-dn1 "bash -c install -d …" dn1 running
opentenbase-dn2 "bash -c install -d …" dn2 running
opentenbase-gtm "bash -c install -d …" gtm running
七、初始化数据库
7.1 等待服务就绪(docker)
# 查看日志
docker compose logs -f coordinator
# 等待看到类似这样的输出:
# LOG: database system is ready to accept connections
7.2 连接数据库(docker)
# 连接 Coordinator
docker exec -it opentenbase-coordinator \
/usr/lib/opentenbase/bin/psql -U opentenbase -d postgres
八、常见报错解决
8.1 容器启动失败
错误:
Error: Container failed to start
解决:
# 查看日志
docker compose logs coordinator
# 常见原因:
# 1. GTM 没启动成功
# 2. 端口冲突
# 3. 内存不够
# 检查端口
sudo netstat -tlnp | grep -E '(5432|6666|15432)'
# 检查内存
free -h
8.2 节点注册失败
错误:
ERROR: can not get master gtm info from pgxc_node
解决:
# 检查 GTM 是否运行
docker compose exec gtm pg_isready -p 6666
# 检查节点是否注册
docker compose exec coordinator \
/usr/lib/opentenbase/bin/psql -c "SELECT * FROM pgxc_node;"
# 手动注册(如果需要)
docker compose exec coordinator \
/usr/lib/opentenbase/bin/psql -c "CREATE GTM NODE gtm_master WITH (HOST='gtm', PORT=6666, PRIMARY);"
8.3 连接被拒绝
错误:
psql: error: could not connect to server: Connection refused
解决:
# 检查服务是否运行
docker compose ps
# 检查端口是否监听
sudo netstat -tlnp | grep 5432
# 检查防火墙
sudo ufw status
# 检查日志
docker compose logs coordinator
8.4 Docker 内存不够
错误:
OOMKilled
解决:
# docker-compose.yml 添加内存限制
services:
coordinator:
mem_limit: 1g
shm_size: 512mb
dn1:
mem_limit: 1g
shm_size: 512mb
九、SQL 测试
9.1 基础测试
-- 查看版本
SELECT version();
-- 查看节点
SELECT * FROM pgxc_node;
-- 创建测试表
CREATE TABLE test (id INT, name TEXT);
-- 插入数据
INSERT INTO test VALUES (1, 'Alice'), (2, 'Bob');
-- 查询数据
SELECT * FROM test;
-- 聚合查询
SELECT COUNT(*), AVG(id) FROM test;
-- 分布式查询
SELECT * FROM test WHERE id = 1;
9.2 性能测试
-- 创建大表
CREATE TABLE big_test (id INT, data TEXT);
-- 插入 10 万条数据
INSERT INTO big_test
SELECT generate_series(1, 100000), 'test data';
-- 查询性能
EXPLAIN ANALYZE SELECT COUNT(*) FROM big_test;
-- 分布式查询性能
EXPLAIN ANALYZE SELECT * FROM big_test WHERE id = 50000;
十、最终效果
10.1 资源占用
测试环境:
- CPU: 1 核
- 内存: 2GB
- 磁盘: 20GB
结果:
| 节点 | CPU | 内存 | 磁盘 |
|---|---|---|---|
| GTM | < 5% | 50MB | 20MB |
| Coordinator | 10-20% | 100MB | 50MB |
| Datanode 1 | 10-20% | 100MB | 50MB |
| Datanode 2 | 10-20% | 100MB | 50MB |
| 总计 | 35-65% | 350MB | 170MB |
2G 服务器完全够用!
10.2 部署时间对比
| 方式 | 时间 | 步骤 |
|---|---|---|
| 官方编译 | 2-3 小时 | 14 步 |
| 我的方案 | 5 分钟 | 1 命令 |
10.3 最终效果
# 一键启动
docker compose up -d
# 查看集群状态
docker compose ps
# 连接数据库
docker exec -it opentenbase-coordinator \
/usr/lib/opentenbase/bin/psql -U opentenbase -d postgres
# 运行 SQL
SELECT * FROM pgxc_node;
[占位符:最终效果完整截图]
十一、总结
通过 Docker Compose,我们实现了:
- ✅ 部署时间从 2-3 小时 → 5 分钟
- ✅ 配置步骤从 14 步 → 1 命令
- ✅ 2G 服务器就能跑通
- ✅ 一键启动完整集群(GTM + CN + 2 DN)
- ✅ 资源占用仅 350MB
核心优势:
- 不需要编译
- 不需要手动配置
- 自动处理节点注册
- 自动处理依赖
- 环境隔离,易于清理
适用场景:
- 学习研究 OpenTenBase
- 快速搭建测试环境
- CI/CD 集成测试
- 演示和教学
项目地址:
- GitHub: https://github.com/muzimu217/OpenTenBase-deb
- Docker Hub: https://hub.docker.com/r/opentenbase/opentenbase
如果你也在折腾 OpenTenBase,希望这个方案能帮你节省时间!
有问题欢迎留言交流~
作者:折腾 OpenTenBase 的学生
项目地址:
- GitHub: https://github.com/muzimu217/OpenTenBase-deb
- Docker Hub: https://hub.docker.com/r/opentenbase/opentenbase
openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构
更多推荐



所有评论(0)