pgrust:基于 Rust 生态的 PostgreSQL 兼容数据库项目

Postgres rewritten in Rust, now faster than Postgres and Clickhouse

Branch4Tags3
This repository is empty

pgrust

Postgres 的 Rust 重写版本,性能超过 Postgres 和 ClickHouse。

Postgres 18.3 回归测试套件:100% 版本:v0.2 许可证:AGPL-3.0

在浏览器中试用 pgrust →   |   Discord   |   更新   |   问题

新增: Michael 在 PlanetScale 上关于 pgrust 的演讲幻灯片 — 完整演讲视频即将发布。

AI 如何改变 JIT 编译器的经济学

pgrust 是 Postgres 的重新实现,旨在展示如果 Postgres 在 2026 年构建会是什么样子。它与 Postgres 的 wire 协议兼容,甚至 SQL 方言也兼容。它通过了 Postgres 回归测试套件中的全部 46,066 个测试。 想了解我们为何构建它的故事,请阅读 pgrust:使用 AI 在 Rust 中重建 Postgres

每一行都是 Rust 代码,编写目标是与 C 实现的行为保持一致。 Rust 让重新设计 Postgres 多个核心组件变得轻而易举。pgrust 具备:

  • 全新的向量化、基于推送、JIT 编译的执行器
  • 基于线程的并发模型
  • 一个查询调度器,旨在防止任何单个查询拖垮整个数据库
  • 内置 OOM 杀手,让 pgrust 在内存不足时掌控处理策略,大幅降低整个数据库被操作系统 OOM 杀手终止的风险

还有许多其他出色的组件。调度器和 OOM 杀手针对的是 导致数千次 Postgres 故障的四大元凶 中的两个。 更多信息请查看 v0.2 中的新特性

状态

pgrust 尚未达到生产可用状态。请勿将重要数据放入其中。

pgrust 目前通过 Postgres 回归测试套件。它比 Postgres 和 ClickHouse 更快,但仍存在大量 bug。我们当前的第一优先级 是测试和可靠性。

如果你今天就需要生产可用的 Postgres,请使用 Postgres。

现有 PostgreSQL 扩展无法使用。pgrust 中尚无稳定的扩展 ABI。 部分内置 contrib 模块已完成移植,但 PL/Python、 PL/Perl 和 PL/Tcl 尚未支持。

pgrust 专门针对 Graviton4 进行了调优,且 JIT 编译器仅面向 Graviton4。pgrust 仍可在其他平台上运行,但不会具备 类似性能。

性能

c8g.4xlarge(AWS Graviton4)上针对 PostgreSQL 18.3 进行测量。

在 ClickBench 综合得分中,pgrust 比 ClickHouse 快 18.5%, 比 PostgreSQL 快数百倍。该测试使用了 pgrcolumnar, 即 pgrust 的内置列式存储布局。

在 sysbench-oltp 中,pgrust 在 300GB 规模的只读工作负载下, 吞吐量比 Postgres 18.3 高 30%。

若想了解该加速中某一部分的代码级解析,请阅读 为 300x 更快的分析重建 Postgres:批处理、算子融合与 SIMD

这些运行结果由 Greg Smith 独立复核,他是 PostgreSQL 9.0 High Performance 的作者。

有两点需要如实说明。我们此前报告称,pgrust 比 Postgres 快 50% 以上。在 Kubernetes 上,我们测得更大的 OLTP 差距,为 50-60% 而非 30%;我们尚未定位为何相同的二进制文件在该环境中的表现与裸 EC2 不同,因此引用较低的数字。其次, 我们发布的二进制文件是各自架构下的通用版本。基准测试数据 来自针对 Graviton4 调优的构建(-Ctarget-cpu=neoverse-v2),因此 直接使用下载版本无法完全复现这些数据。

基准测试和持久性设置与默认安装保持一致: fsync 已开启。测试框架位于 benchmarks/,你可以 自行运行。

文章

测试

关于 pgrust,我们最常听到问题是:如何让人信任它? 通过测试套件并不意味着我们的代码就是正确的。 让人们能够信任 pgrust,是我们当前最优先的目标。 (仅仅让回归测试套件通过,我们就经历了三次失败尝试;我们将这些死胡同记录在了 在 Rust 中实现 Postgres:让回归测试套件通过 中。)

为实现这一目标,我们正在采取多种不同方法:

  1. 在 3000 个面向用户的 Postgres 函数中,我们已使用 Kani 对其中 1000 个进行了形式化验证, 确认它们在 pgrust 中的行为与 Postgres 完全一致。在此过程中, 我们发现 pgrust 与 Postgres 之间存在 12 处差异。其中 4 处 是 Postgres 本身的缺陷。参见 proofs/
  2. 我们正在与 Antithesis 合作,对 pgrust 进行仿真测试, 以实战方式检验 pgrust。
  3. 我们正在开展激进的差分模糊测试,确保 pgrust 的行为与 Postgres 完全一致。

unsafe 代码

pgrust 使用了 unsafe 代码,但只用于确实需要它的特定场景。 Postgres 将每个内部值表示为 Datum,即一个无类型的 8 字节值, 而 Rust 没有安全的等价机制,因此负责打包和拆包内部值的代码是 unsafe。 对于 pgrust 必须逐字节匹配 Postgres 内存布局的地方也是如此。

如果存在某些不必要的特定 unsafe 代码,并且移除它们不会影响性能,请告诉我们, 因为我们很希望移除更多 unsafe 代码。

快速开始

在浏览器中: https://pgrust.com,一个编译为 WebAssembly 的完整 pgrust 服务器,无需安装。

在你的机器上: pgrust 目前还没有自带 initdbpsql,因此 以下每个流程都会先安装 PostgreSQL 18 客户端工具,然后下载 pgrust,接着初始化并启动一个数据库。请按顺序从上到下粘贴代码块。

macOS(Apple Silicon)

# PostgreSQL 18 client tools (initdb, psql). The formula is keg-only, so
# Homebrew does not put it on your PATH; the export is required.
brew install postgresql@18
export PATH="$(brew --prefix postgresql@18)/bin:$PATH"

# Download pgrust and verify the checksum. Download with curl: curl does not
# set the quarantine flag a browser download gets, so Gatekeeper stays out of
# the way (see the note below).
curl -LO https://pgrust.com/downloads/v0.2/pgrust-0.2-macos-arm64
curl -LO https://pgrust.com/downloads/v0.2/pgrust-0.2-macos-arm64.sha256
shasum -a 256 -c pgrust-0.2-macos-arm64.sha256
chmod +x pgrust-0.2-macos-arm64

# Create a data directory using Postgres' initdb.
initdb -D /tmp/pgrust-data --no-locale --encoding UTF8 -U postgres

# pgrust reads the timezone database and other data files from a Postgres
# share directory at runtime. Without these two variables it looks in
# /usr/local/pgsql/share and refuses to start.
export PGRUST_PGSHAREDIR="$(brew --prefix postgresql@18)/share/postgresql"
export PGRUST_TZDIR="$PGRUST_PGSHAREDIR/timezone"

# Start the server. It runs in the foreground and logs to this terminal.
ulimit -s 65520
RUST_MIN_STACK=33554432 ./pgrust-0.2-macos-arm64 \
  -D /tmp/pgrust-data \
  -k /tmp -p 5432 \
  -c listen_addresses= \
  -c io_method=sync \
  -c max_stack_depth=60000

保持服务器运行,并从第二个终端连接:

export PATH="$(brew --prefix postgresql@18)/bin:$PATH"
psql -h /tmp -p 5432 -U postgres -c "select version()"

你应该看到 pgrust 0.2 (PostgreSQL 18.3 compatible)

macOS Intel: 同样的流程也适用,只需使用 pgrust-0.2-macos-x86_64 替代 pgrust-0.2-macos-arm64brew --prefix 会处理不同的 Homebrew 前缀)。此外还提供 pgrust-0.2-macos-universal,这是一个同时覆盖两种架构的通用二进制文件。

关于 Gatekeeper: 这些二进制文件尚未由 Apple 完成公证。如果你按照上述方式使用 curl 下载,文件不会被隔离,也就不会出现此类问题。如果你改用浏览器下载,macOS 会拒绝运行该二进制文件,并提示“Apple 无法验证 ... 不含恶意软件”。你可以使用 xattr -d com.apple.quarantine pgrust-0.2-macos-arm64 清除隔离标记,或者在 系统设置 > 隐私与安全性 > “仍要打开”中批准运行该二进制文件。

Linux(Debian 和 Ubuntu)

# Pick your architecture.
PLATFORM=linux-x86_64    # or: linux-aarch64

# PostgreSQL 18 client tools (initdb, psql) from the PGDG apt repo. On
# Debian and Ubuntu, initdb ships in the server package, postgresql-18, and
# is not placed on PATH, hence the export.
sudo apt-get update
sudo apt-get install -y curl ca-certificates gnupg
sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -fsSL -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
  https://www.postgresql.org/media/keys/ACCC4CF8.asc
echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] http://apt.postgresql.org/pub/repos/apt $(. /etc/os-release && echo $VERSION_CODENAME)-pgdg main" \
  | sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt-get update
sudo apt-get install -y postgresql-18 postgresql-client-18
export PATH="/usr/lib/postgresql/18/bin:$PATH"

# Download pgrust and verify the checksum.
curl -LO "https://pgrust.com/downloads/v0.2/pgrust-0.2-$PLATFORM"
curl -LO "https://pgrust.com/downloads/v0.2/pgrust-0.2-$PLATFORM.sha256"
sha256sum -c "pgrust-0.2-$PLATFORM.sha256"
chmod +x "pgrust-0.2-$PLATFORM"

# Create a data directory using Postgres' initdb.
initdb -D /tmp/pgrust-data --no-locale --encoding UTF8 -U postgres

# pgrust reads the timezone database and other data files from a Postgres
# share directory at runtime. Without these two variables it looks in
# /usr/local/pgsql/share and refuses to start. Debian builds Postgres
# against the system tzdata, so PGRUST_TZDIR points at zoneinfo.
export PGRUST_PGSHAREDIR=/usr/share/postgresql/18
export PGRUST_TZDIR=/usr/share/zoneinfo

# Start the server. It runs in the foreground and logs to this terminal.
ulimit -s 65520
RUST_MIN_STACK=33554432 "./pgrust-0.2-$PLATFORM" \
  -D /tmp/pgrust-data \
  -k /tmp -p 5432 \
  -c listen_addresses= \
  -c io_method=sync \
  -c max_stack_depth=60000

保持服务器运行,并从第二个终端连接:

psql -h /tmp -p 5432 -U postgres -c "select version()"

你应该看到 pgrust 0.2 (PostgreSQL 18.3 compatible)

停止、重启与清理

  • 停止服务器:在其终端中按 Ctrl-C,或执行 kill -INT <pid>。这是 Postgres 的快速关闭方式,并且是安全的。
  • 再次启动:使用相同的数据目录重新执行同一个服务器命令。你的数据会在重启后保留。
  • 重新开始:删除数据目录:rm -rf /tmp/pgrust-data。这会删除其中所有数据。
  • 如果启动失败并提示 FATAL: lock file "/tmp/.s.PGSQL.5432.lock" already exists,则表示另一个服务器,很可能是现有的 Postgres 安装,已经在使用 5432 端口。请使用 -p 5433 在不同端口启动 pgrust,并使用 psql -h /tmp -p 5433 -U postgres 连接。只要同一台机器上正在运行普通 Postgres 实例,连接后都请检查 select version();很容易悄无声息地连接到错误的服务器,然后疑惑为什么行为与 pgrust 完全不同。
  • 如果启动失败并提示 could not open directory "/usr/local/pgsql/share/timezone",说明 quickstart 中的 PGRUST_PGSHAREDIRPGRUST_TZDIR 变量未在运行服务器的 shell 中设置。

从源码构建

你需要 Rust 工具链(任意 rustup 安装均可;rust-toolchain.toml 会将构建锁定到 Rust 1.96.0,并且 rustup 会自动获取它)以及 RE2 正则表达式库:

  • Debian/Ubuntu: sudo apt-get install -y build-essential pkg-config libre2-dev
  • macOS: brew install re2 pkg-config
cargo build --release --locked --bin postgres

服务器二进制文件位于 target/release/postgres。请像快速入门中的已下载二进制文件那样运行它,包括 PGRUST_PGSHAREDIRPGRUST_TZDIR。Release 构建有意拒绝在没有 RE2 时编译:仅使用回退正则表达式引擎的构建,在正则密集型工作负载上会慢得多。我们发布的二进制文件还会额外使用 --profile dist,开启 fat LTO;它会生成更快的二进制文件,但编译所需时间要长得多。

Docker

Docker Hub 上的预构建镜像是官方 postgres 镜像的直接替代品:相同的环境变量(POSTGRES_PASSWORDPOSTGRES_USERPOSTGRES_DBPGDATA ...),相同的 /docker-entrypoint-initdb.d 初始化脚本,相同的 /var/lib/postgresql/data 数据卷。多架构(amd64 + arm64):

docker run -d --name pgrust -e POSTGRES_PASSWORD=secret -p 5432:5432 malisper/pgrust:v0.2

然后连接:

psql -h localhost -p 5432 -U postgres

如果改为从源码构建镜像,仓库中的 Dockerfile 使用了 BuildKit 缓存挂载,因此请使用 buildx 进行构建 (这是当前 Docker 的默认方式;在旧版安装中请改用 DOCKER_BUILDKIT=1 docker build):

docker buildx build --load -t pgrust .

v0.2 更新内容

执行器

  • 一种新的向量化推式执行器,支持 JIT 编译。
  • 一种直接输出机器码的 JIT,将编译时间从 ~50ms 缩短至 ~5µs。目前仅面向 neoverse-v2(Graviton4)。
  • 一种缓存优化的哈希表,会动态调整策略以最大化 L1/L2 命中率。目前用于聚合操作。

并行

  • 连接与并行查询均采用线程而非进程。
  • Postgres 中新增的查询调度器。每个查询都会被分配优先级,长时间运行的查询会被降低优先级,从而减少重型查询对快速查询的干扰。
  • 并行查询基于工作窃取机制重构:空闲线程会被动态分配,以加速正在执行中的查询。

存储

  • pgrcolumnar,一种列式存储格式,支持字典编码和多种其他压缩方式。
  • 流水线化 fsync。worker 在调用 fsync 后、其完成前释放锁。这是安全的,因为在 fsync 完成之前,查询不会被确认,其任何效果也不会被观察到。它将高争用更新的速度提升 30-50 倍。

其他

  • 内置 OOM killer。当接近机器内存上限时,pgrust 会选择终止一个 worker,使单个查询终止,同时让服务器本身继续运行。
  • 使用 PGO 优化可执行文件布局

路线图

v0.2 证明了我们可以实现优于 Postgres 和 ClickHouse 的性能,同时保持与 Postgres 完全一致的行为。接下来,我们正在对 pgrust 进行测试与实战验证,并让人们能够放心地将数据交给 pgrust。

除此之外,我们还希望加入:

  • 即时 fork
  • 自动扩缩容,包括缩容到零
  • Planner 支持 JSON
  • 用于无 vacuum 设计的 Undo 日志支持
  • 自适应计划器,用于防止糟糕的执行计划
  • 一个为测试和嵌入设计的 pgrust 迷你版本

贡献

目前我们暂不主动接收 Pull Request。如果你想帮助项目,请在 Discord 上联系我们。

如果出现问题、配置过程令人困惑,或存在你希望匹配的 Postgres 行为,请仍然提交 issue。

许可证

pgrust 采用 AGPL-3.0 许可证。pgrust 是对 PostgreSQL 的独立 重新实现;请参阅 NOTICE 以了解署名信息。

联系方式

Introduction

用 Rust 重写的 Postgres,现已通过 100% 的 Postgres 回归测试【此简介由AI生成】

Customize your domain
434.99 K191Visit GitHub