PGlite 如何用 @electric-sql/pglite-prepopulatedfs 跳过 initdb 加快实例启动?
【免费下载链接】pgliteEmbeddable Postgres with real-time, reactive bindings.项目地址: https://gitcode.com/GitHub_Trending/pg/pglite
如果你的项目需要频繁创建 PGlite 实例——比如每个测试用例各自启动一个数据库,或应用要反复以干净状态初始化 PGlite——那么默认流程里的initdb会吃掉大部分启动时间。PGlite 仓库提供了@electric-sql/pglite-prepopulatedfs包:它内置一份预先初始化好的数据目录归档,创建实例时通过loadDataDir选项直接加载这份归档,从而跳过initdb,换来更快的启动速度。本文给出安装、接入和验证启动提速的完整路径。
它解决什么问题
PGlite 实例默认会运行initdb来初始化数据目录。@electric-sql/pglite-prepopulatedfs的思路是提前把一份初始化完成的文件系统打包进 npm 包作为静态资源,运行时用dataDir()函数取回这个归档(一个Blob),再通过PGlite.create的loadDataDir选项加载。
据仓库文档说明,这份预置文件系统是在 CI 构建阶段生成的:内部流程(见 generateFS.ts)先PGlite.create()生成一个全新实例,再调用pglite.dumpDataDir('gzip')把数据目录导出为 gzip tarball 写入release/prepopulatedfs.tgz,随包一起发布。
准备条件
用任意一种包管理器安装:
npm install @electric-sql/pglite-prepopulatedfs # or yarn add @electric-sql/pglite-prepopulatedfs # or pnpm add @electric-sql/pglite-prepopulatedfs有一个版本约束必须注意:文档明确指出,预置 FS 在构建时生成,只保证与生成它的 PGlite 版本配套工作。如果遇到问题,先确认@electric-sql/pglite-prepopulatedfs的版本与项目里@electric-sql/pglite的版本匹配(例如仓库当前两者都是 0.5.4,见 pglite-prepopulatedfs 的 package.json)。
接入步骤
最小接入方式是两行 import 加一个选项:
import { PGlite } from '@electric-sql/pglite' import { dataDir } from '@electric-sql/pglite-prepopulatedfs' // Create a PGlite instance with the prepopulated FS const pg = await PGlite.create({ loadDataDir: await dataDir(), })loadDataDir接收一个 PGlitedatadir的 tarball(Blob | File),即对应 api.md 中.dumpDataDir()方法产出的格式;dataDir()返回的正是这种归档。dataDir()在不同运行环境下行为一致但取数方式不同:Node 环境从本地文件读取(fs.readFile),浏览器环境则fetch打包后的prepopulatedfs.tgz(见 src/index.ts)。
可选:在 vitest 测试套中使用
文档给出的典型场景是每个测试各自拥有一个 PGlite 实例。此时在beforeEach里创建实例,避免每个用例重复跑initdb:
import { describe, it, expect, beforeEach } from 'vitest' import { PGlite } from '@electric-sql/pglite' import { dataDir } from '@electric-sql/pglite-prepopulatedfs' describe('query and exec with different data sizes', () => { let pg: PGlite beforeEach(async () => { pg = await PGlite.create({ loadDataDir: await dataDir(), }) await pg.exec(` // setup default data `) }) describe('test no. 1', () => { // ... }) // many more tests here })以上示例来自 docs/docs/prepopulatedfs.md,其中的describe体和exec内的建表语句请按自己的测试内容替换;骨架(beforeEach中用dataDir()创建实例)保持不变即可。
验证启动提速
仓库自带的基准测试可以直接作为验证方式,它在 prepopulatedfs.test.ts 中,随该包的自动化测试运行。测试的测量方法:
- 先做一次 warmup
PGlite.create(); - 测量一次经典
initdb路径的PGlite.create()耗时; - 连续 10 次读取
release/prepopulatedfs.tgz、以loadDataDir方式创建实例,对耗时排序后去掉首尾再取平均值; - 断言 prepopulated 平均耗时小于经典
initdb耗时,并打印对比结果。
文档给出的一段 Apple M1 上的示例输出(文档示例,具体机器数值会有差异):
initdb duration: prepopulated avg (trimmed) 263.38 ms vs. classic initdb 886.29 ms. Speedup: 3.37x你可以在本地跑该包的测试观察自己机器上的对比值;断言elapsedPrepopulated < elapsedInitDb通过即说明预置 FS 路径在你的环境确实更快。
代价与边界
- 带宽换时间:文档明确说明,下载
@electric-sql/pglite-prepopulatedfs包需要更多带宽,但换来的是每次实例化免去initdb。适合"频繁以干净状态反复创建 PGlite"的负载(测试套件、批量初始化),不适用于只创建一次实例的场景。 - 版本配套:预置 FS 只保证与生成它的那个 PGlite 版本兼容,升级 PGlite 时留意同步升级本包。
- 该包不改变 PGlite 的数据目录配置方式,
loadDataDir只是启动时加载数据目录的选项;dataDir、fs等其他 options 按文档独立配置即可。
更多背景可参阅 docs/docs/prepopulatedfs.md 与 packages/pglite-prepopulatedfs/README.md。
【免费下载链接】pgliteEmbeddable Postgres with real-time, reactive bindings.项目地址: https://gitcode.com/GitHub_Trending/pg/pglite
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考