Postgres rewritten in Rust, now faster than Postgres and Clickhouse
pgrust
Postgres 的 Rust 重写版本,性能超过 Postgres 和 ClickHouse。
新增: Michael 在 PlanetScale 上关于 pgrust 的演讲幻灯片 — 完整演讲视频即将发布。
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/,你可以
自行运行。
文章
- AI 如何改变 JIT 编译器的经济学: 用 Rust 构建一个 copy-and-patch ARM64 JIT。
- 为 300 倍更快的分析性能重构 Postgres:批处理、算子融合与 SIMD: pgrust 如何让分析型查询更快。
- 在 Rust 中实现 Postgres:通过 100% 回归测试套件之前的三个死胡同: 在 pgrust 达到完整回归测试套件兼容性之前,哪些尝试失败了。
- pgrust:借助 AI 用 Rust 重构 Postgres: 我们启动这个项目的原因。
测试
关于 pgrust,我们最常听到问题是:如何让人信任它? 通过测试套件并不意味着我们的代码就是正确的。 让人们能够信任 pgrust,是我们当前最优先的目标。 (仅仅让回归测试套件通过,我们就经历了三次失败尝试;我们将这些死胡同记录在了 在 Rust 中实现 Postgres:让回归测试套件通过 中。)
为实现这一目标,我们正在采取多种不同方法:
- 在 3000 个面向用户的 Postgres 函数中,我们已使用
Kani 对其中 1000 个进行了形式化验证,
确认它们在 pgrust 中的行为与 Postgres 完全一致。在此过程中,
我们发现 pgrust 与 Postgres 之间存在 12 处差异。其中 4 处
是 Postgres 本身的缺陷。参见
proofs/。 - 我们正在与 Antithesis 合作,对 pgrust 进行仿真测试, 以实战方式检验 pgrust。
- 我们正在开展激进的差分模糊测试,确保 pgrust 的行为与 Postgres 完全一致。
unsafe 代码
pgrust 使用了 unsafe 代码,但只用于确实需要它的特定场景。 Postgres 将每个内部值表示为 Datum,即一个无类型的 8 字节值, 而 Rust 没有安全的等价机制,因此负责打包和拆包内部值的代码是 unsafe。 对于 pgrust 必须逐字节匹配 Postgres 内存布局的地方也是如此。
如果存在某些不必要的特定 unsafe 代码,并且移除它们不会影响性能,请告诉我们, 因为我们很希望移除更多 unsafe 代码。
快速开始
在浏览器中: https://pgrust.com,一个编译为 WebAssembly 的完整 pgrust 服务器,无需安装。
在你的机器上: pgrust 目前还没有自带 initdb 或 psql,因此
以下每个流程都会先安装 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-arm64(brew --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_PGSHAREDIR和PGRUST_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_PGSHAREDIR 和 PGRUST_TZDIR。Release 构建有意拒绝在没有 RE2 时编译:仅使用回退正则表达式引擎的构建,在正则密集型工作负载上会慢得多。我们发布的二进制文件还会额外使用 --profile dist,开启 fat LTO;它会生成更快的二进制文件,但编译所需时间要长得多。
Docker
Docker Hub 上的预构建镜像是官方 postgres 镜像的直接替代品:相同的环境变量(POSTGRES_PASSWORD、POSTGRES_USER、POSTGRES_DB、PGDATA ...),相同的 /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 以了解署名信息。
联系方式
- Discord: https://discord.gg/FZZ4dbdvwU
- 电子邮件: maintainers@pgrust.com
- 更新: https://pgrust.com/#updates