尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

PGlite 数据备份指南:使用 pglite-tools 的 pgDump 将数据库导出为 SQL

PGlite 数据备份指南:使用 pglite-tools 的 pgDump 将数据库导出为 SQL PGlite 数据备份指南使用 pglite-tools 的 pgDump 将数据库导出为 SQL【免费下载链接】pgliteEmbeddable Postgres with real-time, reactive bindings.项目地址: https://gitcode.com/GitHub_Trending/pg/pglite导读electric-sql/pglite-tools是 PGlite 官方工具包其中最重要的能力是pgDump一个将 PostgreSQL 官方pg_dump编译为 WASM 的版本可以在浏览器或任意 JavaScript 运行时中把 PGlite 数据库完整导出为 SQL 文件。读完本文你将掌握pgDump的安装、参数使用、备份与恢复的完整实战流程并理解其底层基于 Emscripten 与 PGlite 原始协议流通信的实现原理。一、pglite-tools 是什么PGlite 是运行在 WASM 中的嵌入式 PostgreSQL而pglite-tools是为其配套的工具集合目前核心成员是pg_dump的 WASM 移植版。它解决了如何把 PGlite 内存/持久化数据库里的结构与数据完整导出这一实际问题导出的产物是一份标准的 PostgreSQL SQL 脚本可以在任意 PostgreSQL 环境包括新的 PGlite 实例中回放还原。包的元信息可在 packages/pglite-tools/package.json 中确认包名为electric-sql/pglite-tools采用 ESM/CJS 双格式构建通过exports字段同时暴露.与./pg_dump两个入口声明electric-sql/pglite为 peer 依赖。安装npm install electric-sql/pglite-tools安装后在代码中按子路径导入即可import { pgDump } from electric-sql/pglite-tools/pg_dump二、pgDumpWASM 版的 pg_dumppg_dump是 PostgreSQL 自带的逻辑备份工具将数据库导出为 SQL 脚本。pglite-tools 中的pgDump是其 WASM 构建版本因此不依赖 Node.js 原生进程可以在浏览器、Deno、Worker 等 JavaScript 环境里直接运行与 PGlite 共用同一套 WASM 运行环境。注意pgDump运行在与 PGlite 相同的单条连接上每次 dump 结束后会执行DEALLOCATE ALL;。这意味着你在调用pgDump之前通过该连接创建的 prepared statements预处理语句都会被释放若后续还要复用它们需要重新 prepare。三、快速上手导出并恢复一个数据库以下示例来自 packages/pglite-tools/README.md 的完整流程建表、插入数据、记录初始 search_path、导出、新建实例恢复。import { PGlite } from electric-sql/pglite import { pgDump } from electric-sql/pglite-tools/pg_dump const pg await PGlite.create() // Create a table and insert some data await pg.exec( CREATE TABLE test ( id SERIAL PRIMARY KEY, name TEXT ); ) await pg.exec( INSERT INTO test (name) VALUES (test); ) // store the current search path so it can be used in the restored db const initialSearchPath (await pg.query{ search_path: string }(SHOW SEARCH_PATH;)).rows[0].search_path // Dump the database to a file const dump await pgDump({ pg }) // Get the dump text - used for restore const dumpContent await dump.text() // Create a new database const restoredPG await PGlite.create() // ... and restore it using the dump await restoredPG.exec(dumpContent) // optional - after importing, set search path back to the initial one await restoredPG.exec(SET search_path TO ${initialSearchPath};)仓库还提供了可直接运行的最小示例 packages/pglite/examples/pg_dump.js创建test表并插入一行数据后调用pgDump({ pg })再console.log(await dump.text())打印出 dump 内容。四、选项Options详解pgDump接受一个配置对象支持以下字段选项类型说明pgPGlite要导出的 PGlite 实例必填argsstring[]透传给 pg_dump 的参数数组例如[--schema-only]fileNamestring导出文件名称默认dump.sql在 packages/pglite-tools/src/pg_dump.ts 中还可以看到接口额外预留了database与verbose两个字段但从当前实现看pgDump函数体只消费了pg、args、fileName三个其余字段暂未生效使用时请以文档与当前源码为准。自动追加的命令行参数args中你传入的参数会被放在命令前部而以下参数由pgDump自动追加在命令末尾对应源码中baseArgs数组见 src/pg_dump.ts--inserts使用INSERT语句格式输出数据而非COPY格式。这是为了让 dump 结果可以被直接喂给pg.exec()回放执行因为纯 SQL 的INSERT脚本无需任何特殊协议支持。-j 1并发级别固定为 1。WASM 环境不支持 pg_dump 的多线程并行因此强制单线程。-f /tmp/out.sql输出文件始终写入虚拟文件系统中的/tmp/out.sql随后由 JS 侧读取该路径拿到内容。-U postgres固定以postgres用户执行与 PGlite 默认超级用户一致。由于这些参数被追加到末尾它们会覆盖你在args中传入的同名参数——例如你想用--schema-only只导出结构这个参数不会与自动追加项冲突可以正常生效测试用例 tests/pg_dump.test.ts 验证了--schema-only导出不含INSERT语句但若试图自定义-f或-U最终生效的仍将是自动追加的值。五、返回值File 对象pgDump返回一个标准的File对象JavaScript 原生 Filename为你传入的fileName默认dump.sqlMIME 类型为text/plain。const dump await pgDump({ pg, fileName: backup.sql }) console.log(dump.name) // backup.sql const content await dump.text() // 获取 SQL 文本用于 pg.exec 恢复由于是File对象你也可以直接把它用于浏览器中的下载、上传或 Blob URL 预览等场景。六、底层实现原理源码级理解pgDump的实现有助于你在复杂场景下正确使用它。整个执行链路在 src/pg_dump.ts 中核心步骤如下加载 WASM 模块通过PgDumpModFactory见 src/pgDumpModFactory.ts加载预编译的 pg_dump Emscripten 模块并注入print/printErr/onExit回调来捕获 stdout、stderr 与退出码。设置环境变量在preRun阶段将HOME、USER、LOGNAME设置为postgres并对~/.pgpass执行chmod 0600满足 libpq 的权限校验要求。桥接 PGlite通过addFunction注册一对读写回调再调用mod._pgl_set_rw_cbs(read_cb, write_cb)把 pg_dump 的 socket 读写重定向到 PGlite——写侧调用 PGlite 的execProtocolRawStream把协议字节流交给数据库执行该方法定义于 packages/pglite/src/pglite.ts 附近读侧从缓冲的返回字节中取数据回传给 pg_dump。读取产物mod.callMain(args)执行 pg_dump退出码为 0 时从虚拟文件系统读取/tmp/out.sql的 UTF-8 内容。清理与恢复dump 结束后执行DEALLOCATE ALL并把SEARCH_PATH恢复为调用前的值若恢复后 search_path 仍不一致会打印警告。后处理用正则移除输出中 psql 的\restrict/\unrestrict元命令见源码注释引用的 PostgreSQL 17 psql 文档保证脚本可被pg.exec直接执行。返回 File将处理后的文本包装为File返回若退出码非 0则抛出包含 stderr 的异常。测试用例印证packages/pglite-tools/tests/pg_dump.test.ts 覆盖了这些行为可作为使用参考空库可正常 dump内容包含PostgreSQL database dump头L23-L31同一实例可连续多次 dumpL33-L44含多张表与数据的库会导出CREATE TABLE public.xxx与INSERT INTO public.xxxL46-L74自定义fileName生效L76-L80--schema-only只导结构不导数据L82-L94dump → 新实例恢复的完整往返数据可查回L96-L125调用pgDump前后SEARCH_PATH保持一致L127-L137指定dataDir创建的实例同样可 dumpL139-L173--quote-all-identifiers会导出带引号的标识符如CREATE TABLE public.test1L175-L203。七、实战场景与进阶用法1. 备份与迁移最常规的用法即导出 SQL → 新实例恢复覆盖了内存库、dataDir持久化库之间的数据迁移。恢复时直接await restoredPG.exec(dumpContent)即可无需 psql 客户端。2. 只导出结构不含数据配合--schema-only可生成仅含 DDL 的脚本用于克隆表结构、生成建表文档或测试迁移脚本const schemaDump await pgDump({ pg, args: [--schema-only] })3. 其他 pg_dump 参数透传args数组会原样透传给 WASM 版 pg_dumpPostgreSQL 官方 pg_dump 支持的大部分参数如--quote-all-identifiers、-t指定表、--no-owner等都可以尝试传入但需注意多线程相关参数-j会被自动覆盖为1。八、注意事项Caveatssearch_path恢复 dump 后新实例的默认 search_path 可能与原库不同。建议在恢复后执行SET search_path TO 原值;还原原库的值可在 dump 前通过SHOW SEARCH_PATH;取得。pgDump自身也会在 dump 过程中尽力保护原实例的 search_path但恢复侧仍需手动处理。prepared statementsDEALLOCATE ALL会在每次 dump 后执行且作用于同一个连接因此你先前 prepare 的语句会失效需要重新 prepare。单连接限制-j 1意味着导出是单线程的数据量极大时耗时较长这是 WASM 环境的固有约束。输出格式自动追加的--inserts保证了脚本可直接用pg.exec()回放但也意味着不使用高效的 COPY 二进制格式超大表的导出脚本体积会更大。九、总结electric-sql/pglite-tools的pgDump把 PostgreSQL 官方的 pg_dump 完整搬进了 WASM 世界让浏览器端与任意 JS 运行时中的 PGlite 数据库都能获得标准的 SQL 导出能力。其实现通过 Emscripten 模块 execProtocolRawStream原始协议流桥接在单连接约束下完成了导出 → 清理 → 返回 File的闭环配合--inserts、--schema-only、--quote-all-identifiers等参数足以覆盖备份、迁移、结构克隆等绝大多数场景。使用时的两个关键提醒是恢复后记得还原 search_path且调用前注意 prepared statements 会被清空。【免费下载链接】pgliteEmbeddable Postgres with real-time, reactive bindings.项目地址: https://gitcode.com/GitHub_Trending/pg/pglite创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表