薄克隆依赖 ZFS 或 LVM,宿主机需提前准备对应存储;托管云数据库(如 AWS RDS、Heroku)无法直接物理连接,需在同区域单独 VM 上运行 DBLab 并定期自动刷新数据;社区版需按教程安装,商业版 DBLab SE 需通过 Postgres.ai Console 或 AWS Marketplace 部署。
database-lab-engine
postgres-aiApache-2.0活跃维护给 Postgres 数据库做分支和秒级瘦克隆,让 CI/CD 里的数据库测试跑得更快、成本更低。
DBLab enables 🖖 database branching and ⚡️ thin cloning for any Postgres database and empowers DB testing in CI/CD. This optimizes database-related costs while improving time-to-market and software quality. Follow to stay updated.
README 未给出可直接复制的最小安装命令,仅指向教程:https://postgres.ai/docs/tutorials/database-lab-tutorialREADME 未说明具体显存或 CPU 要求;薄克隆依赖 ZFS(默认)或 LVM,源数据库本身不需要 ZFS 或 Docker。
给任意 PostgreSQL 做秒级薄克隆和数据库分支,用于开发测试与 CI/CD
给 Postgres 数据库做分支和秒级瘦克隆,让 CI/CD 里的数据库测试跑得更快、成本更低。
核心能力
- 基于 ZFS/LVM 的 Copy-on-Write 实现秒级薄克隆
- 支持物理(pg_basebackup、WAL-G、pgBackRest)与逻辑(dump/restore)两种数据获取
- 提供 UI、API 与 CLI 三种操作方式,组件全部打包为 Docker 容器
- 支持克隆、分支、快照的保留策略与删除保护
- 单个克隆可用 pg_upgrade --link 原地升级 PostgreSQL 大版本
容易踩的坑
- v4.2.1最新正式版2026-10-08 · 2026-10-08 14:02 UTC
Improvements and Fixes
- Clone major upgrade no longer fails at the check stage on instances that mount TLS certificates or other files into clones: the upgrade container now gets the volumes from
databaseContainer.containerConfig(!1206, #792) - The "Upgrade clone" button stays visible when clone upgrade is unavailable (for example,
provision.pgUpgradeImageis not set); it is disabled and shows the engine's reason in a tooltip (!1205) - Creating a clone for a restricted user no longer fails with
cannot alter partition ... with an incomplete detachwhen the snapshot holds a partition with a pendingDETACH PARTITION ... CONCURRENTLY; the detach is finalized in the clone (!1208, #795) - Clone state (
sessions.json) is written atomically, and the engine refuses to start on an unreadable state file; a crash in the middle of a write could previously lead to every clone being destroyed on the next start (!1198, #783) - A panic in a background job or an HTTP handler no longer terminates the engine, and data races in WebSocket token cleanup and webhook reload are fixed (!1198, !1199, #783, #784)
- Config reload is synchronized across engine services, fixing data races between a reload and in-flight requests; two concurrent full refreshes can no longer both start, and a clone being provisioned keeps its database config across a reload (!1202, #788)
- A rotated
verificationTokentakes effect on config reload instead of requiring a restart (!1199, #29) - A Postgres start timeout is reported as an error instead of success, and
POST /observation/stopno longer hangs when the observation session ended with an error (!1199, #784) - The pool is activated and branching is initialized when there are no retrieval jobs or the snapshot already exists (!1199, #784)
--extra-configand--tagsvalues without=makedblabreturn an error instead of panicking (!1199, #784)- Not-found and bad-request API errors return 404/400 instead of 500; percent-encoded snapshot IDs are accepted;
POST /snapshotreturns the snapshot model with correct sizes; an emptydeleteAtis rejected with 400; the log of a branch namedsnapshotis reachable (!1197, #782) - The OpenAPI spec matches the engine's routes and models, including 7 previously undocumented operations (!1196)
- The Logs tab no longer leaks WebSocket connections and auto-scrolls again, and a render error shows a message instead of a blan
- Clone major upgrade no longer fails at the check stage on instances that mount TLS certificates or other files into clones: the upgrade container now gets the volumes from
- v4.2.02026-09-11 · 2026-09-11 02:54 UTC
查看更新说明
New Features
- Simplified install: the UI Configuration tab opens in a new Simple mode — paste a source connection URL and password, and the engine detects the provider (RDS, Aurora, Heroku, Supabase and others), Postgres image and tag, databases,
shared_buffers,shared_preload_librariesand query-tuning parameters, then applies the proposed config; Expert mode keeps full control and adds WAL-G and pgBackRest physical-mode fields (!1148, #713) - CLI: new
dblab local-installcommand runs the same source detection and applies the proposed logical-mode config from the terminal (!1148, !1192, #774) - Clone major upgrade: upgrade an existing clone to a newer PostgreSQL major version in place with
pg_upgrade --link, viaPOST /clone/{id}/upgrade,dblab clone upgradeor the UI; the target version comes from the configuredprovision.pgUpgradeImageand is reported on/status, and resetting the clone rolls it back (!1180, !1188, #756, #768) - Deletion protection and auto-deletion for branches and snapshots: protect a branch or snapshot forever or for a set duration, and let the new
retentionconfig section delete unused ones after N minutes (safe-only: anything with clones, children or protection is never removed); newPATCH /branch/{name}andPATCH /snapshot/{id}endpoints and--protectedoptions indblab branchanddblab snapshot update(!1161, !1166, !1171, #727, #735, #742) - Configs: whole-value
${VAR}/$VARenvironment placeholders are expanded in engine, CI checker and CLI configs, including retrieval job options such as source passwords and S3, WAL-G and pgBackRest credentials, so secrets no longer have to be stored in plain text (!1140, !1178, #750) - Retrieval: new
customOptionsfor WAL-G and pgBackRest physical restore passes extra tool flags (for example--restore-specor--mask) without switching tocustomTool(!1182, #760) - Teleport (Standard and Enterprise Editions): opt-in
platform.bindClonesToUserlabels each clone with its owner (dblab_user), so Teleportdb_labelsrules can limit users to their own clones; covers clones created with a personal token and from the Platform console (!1163, !1173, #731) - Teleport: attach custom labels to sidecar
db/appresources with the repeatable--label key=valueflag orTELEPORT_LABELS; instance ownership moves to a dedicateddblab_instancelabel (!1162, [#730](https://gitlab.com/po
- Simplified install: the UI Configuration tab opens in a new Simple mode — paste a source connection URL and password, and the engine detects the provider (RDS, Aurora, Heroku, Supabase and others), Postgres image and tag, databases,
- v4.1.42026-09-01 · 2026-09-01 09:28 UTC
查看更新说明
Security
- Engine: bump the Go toolchain to 1.26.7 and
golang.org/x/modto v0.40.0, and digest-pin therds-refreshAlpine base image (!1183) - Engine: bump
golang.org/x/cryptoto v0.55.0 (!1184) - Engine: track the
docker-cli29.x series instead of an exact-rNpin, so image rebuilds pick up upstream security releases (!1152, !1186) - CE UI: bump
cypressto 15.x, which drops theextract-zipandenquireradvisories that had no upstream fix (!1184) - CE UI: refresh the
pnpmoverrides fordompurify,qs,nanoidand@babel/core(!1184) - CE UI: add the
postcss,brace-expansion,form-data,tmp,fast-uri,immutable,js-yamlandwsoverrides (!1186) - CE UI: pin
viteto 6.4.3, fixing aserver.fs.denybypass and an NTLMv2 hash disclosure throughlaunch-editor(!1186)
Internal
- CI: install
google-cloud-cliinstead of the retiredgoogle-cloud-sdkpackage, which no longer resolves on Debian trixie (!1183)
Full diff
- Engine: bump the Go toolchain to 1.26.7 and
- v4.1.32026-05-08 · 2026-05-08 12:53 UTC
- v4.1.22026-04-29 · 2026-04-29 10:26 UTC
查看更新说明
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
*For managed PostgreSQL cloud services like AWS RDS or Heroku, direct physical connection and PGDATA access aren't possible. In these cases, DBLab should run on a separate VM within the same region. It will routinely auto-refresh its data, effectively acting as a database-as-a-service solution. This setup then offers thin database branching ideal for development and testing.
Why DBLab?
- Build dev/QA/staging environments using full-scale, production-like databases.
- Provide temporary full-size database clones for SQL query analysis and optimization (see also: SQL optimization chatbot Joe).
- Automatically test database changes in CI/CD pipelines, minimizing risks of production incidents.
- Rapidly validate ChatGPT or other LLM concepts, check for hallucinations, and iterate towards effective solutions.
For example, cloning a 1 TiB PostgreSQL database takes just about 10 seconds. On a single machine, you can have dozens of independent clones running simultaneously, supporting extensive development and testing activities without any added hardware costs.
Try it yourself right now:
- Visit Postgres.ai Console, set up your first organization, and provision a DBLab Standard Edition (DBLab SE) to any cloud or on-premises environment.
- Pricing (starting at $62/month)
- Documentation: How to install DBLab SE
- Demo: https://demo.dblab.dev (use the token
demo-tokento access) - Looking for a free version? Install the DBLab Community Edition by following this tutorial.
How it works
Thin cloning is fast because it is based on Copy-on-Write (CoW). DBLab employs two technologies for enabling thin cloning: ZFS (default) and LVM.
Using ZFS, DBLab routinely takes new snapshots of the data directory, managing a collection of them and removing old or unused ones. When requesting a fresh clone, users have the option to select their preferred snapshot.
Read more:
Where to start
- DBLab tutorial for any PostgreSQL database
- DBLab tutorial for Amazon RDS
- How to install DBLab SE using Postgres.ai Console
- How to install DBLab SE using AWS Marketplace
Case studies
Features
- Speed & scale
- Support & technologies
- PostgreSQL containers
- Source database requirements
- Location flexibility: self-managed PostgreSQL, AWS RDS, GCP Cloud SQL, Azure, etc.—no source adjustments needed.
- No ZFS or Docker requirements for source databases
- Data provisioning & retrieval
- Simple-mode setup: paste source URL + password, get a probed configuration in one click (UI Configuration → Simple tab)
- Expert-mode form for both logical (dump/restore) and physical (WAL-G, pgBackRest) retrieval
- Physical (pg_basebackup, WAL-G, pgBackRest) and logical (dump/restore) provisioning
- Partial data retrieval in logical mode (specific databases/tables)
- Database renaming during snapshot creation (
databaseRenameoption) - Continuous update in physical mode
- Periodic full refresh in logical mode without downtime
- Recovery & management
- Fast Point in Time Recovery (PITR) for physical mode
- Auto-deletion of unused clones
- Time-based auto-deletion of unused branches and snapshots (
retentionconfig; safe-only, never force-deletes dependents) - Snapshot retention policies in DBLab configuration
- Clones, branches & snapshots
- "Deletion protection" for clones, branches, and snapshots (blocks manual and auto-deletion, plus count-based retention for snapshots)
- Persistent clones withstand DBLab restarts
- "Reset" command for data version switching
- "Upgrade" command to move a single clone to a newer PostgreSQL major version in place
- Resource quotas: CPU, RAM
- Monitoring & security
/healthzAPI endpoint (no auth), extended/statusendpoint (API docs)- Prometheus metrics endpoint (
/metrics) for monitoring - Netdata module for insights
Clone major upgrade
A single clone can be moved to a newer PostgreSQL major version without touching the rest of the instance, which makes it practical to test an upgrade against production-like data:
dblab clone upgrade my-clone
The target version is not a parameter: it follows from the upgrade image the instance is
configured with, which is built on that major's binaries. The engine reports it in
GET /status as cloneUpgrade.targetVersion, the CLI prints it, and the UI shows it on the
confirmation dialog.
The same action is available in the UI on the clone page and over the API as
POST /clone/{id}/upgrade.
The clone's Postgres is shut down cleanly, pg_upgrade --link converts its data directory in
place, and the clone restarts on an image of the target major. Because --link hard-links the
data files instead of copying them, the upgrade is fast and consumes almost no extra space. The
request returns as soon as the clone enters the UPGRADING state; watch the clone status for the
result.
Enabling it. Set provision.pgUpgradeImage to an upgrade image of the major you want clones
upgraded to. That image is the single source of the target: the engine reads the major out of a
release tag (:17, :17-0.8.0, :17-0.8.0-glibc236), and re-reads it from the image's own
PG_MAJOR before every upgrade, so a tag repointed at another build is caught before any data
moves. A tag outside that grammar — a digest pin, latest, a CI build — states no major, so the
engine fetches the image in the background at startup and reads it from there; until that lands
the upgrade reports itself unavailable. When pgUpgradeImage is unset the feature is simply
unavailable and the endpoint says so; nothing else about the instance changes. The UI keeps the
"Upgrade clone" button visible but disabled in that state, and its tooltip carries the reason
reported on /status, so an unset image is one hover away from being diagnosed.
provision:
pgUpgradeImage: "postgresai/pg-upgrade:17"
pgUpgradeTimeout: 3h
pgUpgradePullTimeout: 1h
pgUpgradeTimeout bounds a single upgrade run; it defaults to three hours. When the budget runs
out, the upgrade container is removed and the clone is put back on the version its data directory
still holds, exactly as it would be after any other failure.
pgUpgradePullTimeout bounds each of the two image pulls that precede it, and defaults to one
hour. The upgrade image carries the target major plus the server packages of the four preceding
ones, so the first upgrade on an instance downloads several gigabytes; pre-pulling both images
makes the step a no-op. Both pulls happen while the clone is still serving traffic, so exceeding
the budget leaves the clone untouched and running. The two budgets are separate on purpose — a
slow pull must not eat into the time pg_upgrade gets once the clone is already stopped.
An upgrade request may name an image explicitly instead of letting the engine substitute the major
in the current tag. provision.upgradeImageAllowList says which repositories such a request may
name. When it is empty, as it is by default, only the repository of the clone image is accepted:
the one databaseContainer.dockerImage points at, plus the repository of the clone's own image
when the clone has already been upgraded to another one. That default accepts exactly the image
the engine would derive itself. List repositories to allow other ones, or "*" to allow any
repository the instance can reach.
provision:
upgradeImageAllowList:
- "postgresai/extended-postgres"
Releases up to v4.2.0 accepted any repository when the list was empty. An instance that relied on
that must now set the list to ["*"].
How it can end. Almost every outcome leaves the clone running:
| Status | Meaning |
|---|---|
OK | The clone runs the target version; dbVersion reports it. |
WARNING | The upgrade was not applied. Either nothing had been converted and the clone still runs its original version, or conversion had begun and the clone was rebuilt from its origin snapshot — in which case data written since the clone was created is lost. The message says which, and points at the pg_upgrade log under <clone dir>/upgrade/logs/. When the postmaster that pg_upgrade started failed, its own fatal error, with the DETAIL and HINT lines that follow it, is appended to the cause, and the run's pg_upgrade_output.d/<timestamp>/ directory (server log, internal log, schema dumps) is preserved under the same logs/ directory; the five most recent failed runs are kept. |
WARNING, clone not running | The upgrade settled on disk but the clone container did not come back up. The data directory is intact and the upgrade is still recorded as pending, so the next engine start finishes or undoes it and brings the clone back. |
FATAL | Recovery itself failed and there is nothing left to finish. Reset or delete the clone. |
Rolling back. Resetting the clone returns it to the version the instance is configured with, because a reset re-provisions from the origin snapshot using the engine-wide image.
Things to know.
- The target must be newer than the clone's current major and at most four majors ahead — the
upgrade image carries binaries for the four preceding versions. A clone outside that range is
refused; upgrading it means pointing
pgUpgradeImageat a different major. - Only majors DBLab ships a default configuration for can be targeted (10–18 today).
- The image tag keeps its extension bundle and glibc suffix; only the major changes
(
…:16-0.8.0-glibc236→…:17-0.8.0-glibc236). Changing the glibc build across an upgrade would change collation behaviour, andpg_upgradedoes not reindex. Pass--docker-imageto override the choice; when its tag names a major, that major has to be the one being upgraded to. pg_upgradeverifies that every extension in the source database has a matching library for the new major. An extension outside the image's set fails this check, and the clone rolls back untouched.- Clones using non-default tablespaces are refused: those live outside the clone dataset.
- In physical mode the sync instance and the pool are untouched — the upgrade only ever acts on a
clone's own dataset. The instance-wide
dockerImagemust still match the source major. - Iteration 1 limitation: a snapshot created from an upgraded clone does not record its major version, so clones created from that snapshot start on the instance-wide image and will fail to start. Avoid snapshotting upgraded clones until snapshot-level version resolution lands.
How to contribute
Support us on GitHub/GitLab
The simplest way to show your support is by giving us a star on GitHub or GitLab! ⭐

Spread the word
- Tweet about DBLab and mention @Database_Lab.
- Share a link to this repository on your favorite social media platform.
Share your experience
If DBLab has been a vital tool for you, tell the world about your journey. Use the logo from the ./assets folder for a visual touch. Whether it's in documents, presentations, applications, or on your website, let everyone know you trust and use DBLab.
HTML snippet for lighter backgrounds:
<a href="http://databaselab.io">
<img width="400" src="https://postgres.ai/assets/powered-by-dle-for-light-background.svg" />
</a>
For darker backgrounds:
<a href="http://databaselab.io">
<img width="400" src="https://postgres.ai/assets/powered-by-dle-for-dark-background.svg" />
</a>
Propose an idea or report a bug
For proposals, bug reports, and participation in development, see our Contributing Guide.
Reference guides
How-to guides
- How to install and initialize Database Lab CLI
- How to manage DBLab
- How to work with clones
- How to work with branches
- How to integrate DBLab with GitHub Actions – TBD
- How to integrate DBLab with GitLab CI/CD – TBD
You can find more in the "How-to guides" section of the documentation.
Miscellaneous
- DBLab Docker images
- Extended Docker images for PostgreSQL (with plenty of extensions)
- SQL Optimization chatbot (Joe Bot)
- DB Migration Checker
License
The DBLab source code is licensed under the OSI-approved open source license Apache 2.0.
Reach out to the PostgresAI team if you want a trial or commercial license that does not contain the GPL clauses: Contact page.
Community & Support
- Database Lab Engine Community Covenant Code of Conduct
- Where to get help: Contact page.
- Community Slack
- If you need to report a security issue, follow the instructions in Database Lab Engine Security Guidelines.
Many thanks to our amazing contributors!
Translations
Making DBLab more accessible to engineers around the globe is a great help for the project. Check details in the translation section of contributing guide.
This README is available in the following translations: