前言

说实话,我差点被 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 完整文件截图]**

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,我们实现了:

  1. 部署时间从 2-3 小时 → 5 分钟
  2. 配置步骤从 14 步 → 1 命令
  3. 2G 服务器就能跑通
  4. 一键启动完整集群(GTM + CN + 2 DN)
  5. 资源占用仅 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
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐