腾讯开源的分布式数据库,我把源码翻了一遍

腾讯开源的分布式数据库,我把源码翻了一遍

2026-10-30 发布3 浏览 · 0 点赞 · 0 收藏

腾讯开源的分布式数据库,我把源码翻了一遍

OpenTenBase 的官网上写着 HTAP。

但我把它的源码拉下来,翻遍整个仓库,没找到列存引擎——只剩一个 --with-colblocksize 的编译选项,和一行 “disable create unlogged column table temporarily” 的注释。

这不是黑它。恰恰相反,一个能编译、能跑、有完整分布式事务的数据库,比 PPT 上的 HTAP 有意思得多。

于是我花了一个下午,把它的架构、代码和坑都翻了一遍。

先说结论:它是一台改装得很彻底的旧底盘。底盘是 PostgreSQL 10,改装件是分布式事务、分片和 Oracle 兼容。它能开,有些路况只有它能开,但你需要懂得维修它。

超链接





一、它到底是什么

一句话:腾讯 TDSQL PG 版的社区开源内核,由开放原子基金会托管,仓库在 OpenTenBase 组织下。

它的底座写得很直白,configure.in 第一行就是 PostgreSQL 10beta3 (Postgres-XL 10alpha2)。也就是说,它是 PostgreSQL 10 加 Postgres-XL 的分布式改造,而不是从零写起的数据库。

这里要澄清一个常见误解。官网说 OpenTenBase“包含两个内核”,但那是整个项目的版图——本仓库只有 PostgreSQL 内核,MySQL 内核 TXSQL 在别的地方。

它的集群由三个角色组成:

CN(Coordinator):负责解析、生成分布式计划、把查询片段发给 DN、汇总结果。它只存元数据,不存用户数据。
DN(DataNode)
:真正存数据、执行片段。和 CN 是同一个二进制,靠 --coordinator / --datanode 启动参数区分。
GTM(Global Transaction Manager)**:独立进程,发放全局事务 ID、全局快照和全局序列,是跨节点一致性的来源。

这个结构决定了它的定位:它是 shared-nothing 的 MPP 数据库,不是“分库分表中间件”。中间件不碰存储引擎,而 OpenTenBase 连执行器和事务层都改了。

二、代码成色

先看几个数字:

  • 8,426 个文件,工作区 223 MB
  • 1,617 个 .c、1,119 个 .h,C 代码约 173 万行
  • 642 个 GUC 参数定义,69 个 contrib 扩展
  • GitHub 上 632 stars、388 个未关闭 issue

但行数会骗人。真正要看的是这些代码从哪来。

src/backend 一个目录就占了 116 万行,几乎就是完整的 PostgreSQL;doc 34 万行是官方文档;src/test 28 万行是回归测试。也就是说,绝大部分代码是继承来的。

OpenTenBase 自己的增量,集中在这么几个地方:

目录 规模 作用
src/gtm 6.6 万行 全局事务管理器,含 Proxy、Standby、XLOG 复制
src/backend/pgxc 4.2 万行 分布式计划、连接池、分片、屏障
src/backend/opentenbase_ora 3 万行 Oracle 兼容语法
src/backend/audit 1 万行 审计与细粒度审计
optimizer/spm 6 个文件 执行计划管理

一个比较好记的说法是:85% 的代码是别人的,15% 决定了它是不是一个分布式数据库。

三、五个发现

下面这五件事,文档里没写,但代码里写得明明白白。

发现一:默认连 HASH 分布都不让你用

如果你照着 Postgres-XL 的教程建表:

CREATE TABLE t (id int) DISTRIBUTE BY HASH(id);

会直接得到:

ERROR: distribute type "HASH" or "MODULO" is not enabled in this build
HINT: Rebuild OpenTenBase with --enable-alltype-distri ...

默认编译只放行 SHARD 和 REPLICATION 两种分布,HASH / MODULO / ROUNDROBIN 要加 --enable-alltype-distri 重新编译。代码里的判断在 tcop/utility.c,写得很显式。

这说明什么?说明在 TDSQL 的产品逻辑里,分片(SHARD)才是主线,Postgres-XL 那套 hash 分布只是保留能力。你如果拿 PGXL 的经验直接套,第一步就会卡住。

发现二:configure 和 configure.in 对不上

一个 Autoconf 项目,configure 是从 configure.in 生成的。

但在 OpenTenBase 里,--disable-license、--enable-alltype-distri、--enable-user-switch 这些关键选项,只存在于生成的 configure 脚本里,configure.in 里搜不到。

这意味着:谁要是习惯性跑一次 autoconf 重新生成,这些开关就全丢了。发布产物和源码不同步,是可复现构建的大忌。

顺带一提,configure 里还有个 --with-colblocksize(列存块大小),定义得一本正经,全仓库却没有任何一处使用它。列存内核在开源版里被剥离了,只留下这个空壳。

发现三:开源版里留着商业版的尾巴

src/backend/license/ 目录下,除了 license.c,还躺着 public.key 和 private.key。

许可证过期后,集群会变成只读——xact.c 里有一段 #ifndef NOLIC 的判断,过期就打印 “license expired or did not exist, cluster can only be read now”。

所以 README 才会在第一屏就教你加 --disable-license。

这件事本身不影响学习,但它传递了一个信号:开源版不等于商业版。列存是例子,许可证是例子,还有一些能力可能只存在于闭源分支里。评估选型时,这一点要算进去。

发现四:Oracle 兼容才是真卖点

如果说分布式是“骨架”,那 Oracle 兼容就是 OpenTenBase 最想卖的“肌肉”。

它不是加几个兼容函数那种敷衍,而是双词法 + 双语法:

  • 通过 sql_mode = opentenbase_ora 切换,同一个内核支持两套 SQL 方言;
  • 独立的 gram_ora.y,691 KB,比主语法文件还大;
  • 支持 CONNECT BY / START WITH / PRIOR,执行器里有专门的 nodeConnectBy;
  • 支持 ROWNUM、DUAL、VARCHAR2、NUMBER 这些 Oracle 数据类型;
  • 有独立的 PL/SQL 方言 oraplsql,支持包(PACKAGE)、游标、异常;
  • 还有一整套 DBMS_* 系统包:DBMS_OUTPUT、DBMS_LOB、DBMS_RANDOM、DBMS_METADATA……

配套的还有 Oracle 风格的审计(AUDIT ... ON ... + 细粒度审计 FGA)和 SPM 执行计划管理。

它兼容的不是 Oracle 的语法,是 Oracle 用户的习惯。 对迁移项目来说,这比多几个功能实在。

发现五:GTM 是命门

全局事务 ID、全局快照、全局序列,全在 GTM 里。DN 上的每一次跨节点提交,都要和它打交道;一致性靠 GTM 发放的 GXID、CSN 提交序列号,再加两阶段提交兜底。

这套设计很经典,也很好理解,代价是:GTM 是单点,也是吞吐瓶颈。GTM-Proxy 和 Standby 能缓解切换问题,但消除不了这个中心。

一个很能说明问题的细节:GTM 启动时会按 CPU 核数做线程绑核。在 ≤2 核的机器上,pthread_setaffinity_np 会失败,进程直接报 FATAL: binding threads failed 起不来。README 把它列为已知问题,建议换 ≥4 核机器,或者用 noaffinity.so 绕过去。

连启动都这么“挑机器”,说明它是按高性能场景设计的——也说明它对部署环境有要求。

四、谁适合用,谁别碰

适合:

  • 想学分布式数据库内核的人。CN/DN/GTM 三件套、全局快照、2PC、下推优化、分片映射,代码齐全且能编译,是很好的教材;
  • 有 Oracle 迁移预研需求的项目。拿它跑一遍存量 PL/SQL,能快速摸出兼容性边界;
  • 国产化选型的 PoC 阶段。它有 TDSQL 血缘和真实案例,值得进候选名单,但一定要和 TiDB、OceanBase、openGauss 放在一起压测。

不建议:

  • 没有 DBA 或内核团队,直接拿它扛核心交易;
  • 期待“开箱即用的 HTAP”。列存和向量化不在这个仓库里,AP 场景要实测;
  • 在 Windows 上开发。核心路径直接依赖 epoll、prctl,非 Linux 环境编译不过,老老实实用 WSL2。

五、最后

如果把数据库比作车,OpenTenBase 更像一辆改装得很彻底的老底盘:底盘是 PG 10,改装件是分布式事务、分片、Oracle 兼容。它能开,而且有些路况只有它能开;但你要会修车,也要接受它偶尔挑路。

它不值得被神化,也不该被一句“套壳”打发。能把 PostgreSQL 改成这样,背后的工程量是真实的;而它留下的那些坑,同样真实。

源码在 GitHub,搜 OpenTenBase 就能找到。下一篇我想聊聊它的分片映射:4096 个槽位、MOVE DATA、以及数据到底是怎么搬的。感兴趣的话,点个关注。


数据来自 2026-10-30 的 master 分支(commit 123e2b3),行数为脚本统计口径。


请前往 登录/注册 即可发表您的看法…