详解本地与远程(src_uri)复制、初始快照拷贝选项、分区表支持以及 table_config JSON 参数。
这是本节的多页打印视图。 .
SQL 接口、视图与配置参数参考手册
本节提供 pg_mooncake(v0.3.0) 暴露的全部 SQL 存储过程、表状态查询函数、表访问方法(TAM)以及 PostgreSQL GUC 配置参数的完整参考。
SQL 存储过程与函数(mooncake Schema)
| 对象名称 | 完整函数签名 | 功能说明 |
|---|---|---|
mooncake.create_table |
CALL mooncake.create_table(dst text, src text, src_uri text DEFAULT NULL, table_config json DEFAULT NULL) |
创建只读的 USING mooncake 列存镜像表(dst),从当前本地数据库或远程 PostgreSQL URI(src_uri)中的源表(src)实时复制数据。 |
mooncake.create_snapshot |
CALL mooncake.create_snapshot(dst text) |
等待 Moonlink 追平当前 PostgreSQL WAL 写入 LSN,将内存 Arrow 写缓冲区刷盘为 Parquet,并写入新的 Apache Iceberg v2 元数据快照。 |
mooncake.optimize_table |
CALL mooncake.optimize_table(dst text, mode text) |
对目标列存镜像表 dst 执行文件合并(Compaction)与删除向量清理(mode 支持 'full' 或 'minor')。 |
mooncake.list_tables |
SELECT * FROM mooncake.list_tables() |
表值函数,返回当前数据库中所有活跃 Moonlink 表的 (table text, commit_lsn pg_lsn, flush_lsn pg_lsn, iceberg_warehouse_location text)。 |
mooncake.load_files |
CALL mooncake.load_files(dst text, files text[]) |
在 v0.3.0 中未实现;调用时会显式抛出 SQLSTATE 0A000(FEATURE_NOT_SUPPORTED),避免旧版静默空操作造成的误导。 |
mooncake.list_tables() 返回列说明
| 列名 | 数据类型 | 说明 |
|---|---|---|
table |
text |
列存镜像表的带 Schema 完整名称(例如 public.orders_analytics)。 |
commit_lsn |
pg_lsn |
已摄取进入 Moonlink 内存 Arrow 写缓冲区的最新 PostgreSQL WAL LSN。 |
flush_lsn |
pg_lsn |
已持久化刷盘至 Parquet / Iceberg 快照存储的最新 PostgreSQL WAL LSN。 |
iceberg_warehouse_location |
text |
存放该表 Apache Iceberg v2 元数据与 Parquet 数据文件的本地目录($PGDATA/pg_mooncake/...)或云端路径(s3://...)。 |
表访问方法与事件触发器
- 表访问方法(
USING mooncake):由mooncake.create_table自动创建,并在扩展加载时通过RegisterDuckdbTableAm("mooncake")注册至pg_duckdb 1.2.0。 - 删表清理触发器(
mooncake_drop_trigger):当对列存镜像表执行DROP TABLE <dst>;时,ON sql_drop事件触发器(mooncake_drop_trigger_func)会自动从 Moonlink 注销该表并清理对应的逻辑复制订阅。
GUC 配置参数参考
| 参数名称 | 类型 | 默认值 | 上下文 | 参数说明 |
|---|---|---|---|---|
mooncake.default_bucket |
string |
''(本地 $PGDATA/pg_mooncake) |
USERSET / SUSET |
新创建的 Mooncake 表写入 Parquet 数据文件与 Apache Iceberg v2 元数据的默认对象存储桶路径(例如 's3://my-bucket/warehouse')。 |
mooncake.extension_repository |
string |
$(pg_config --sharedir)/extension/pg_mooncake |
SUSET |
存放随包安装的 v2.0.0/<platform>/mooncake.duckdb_extension 二进制文件的本地扩展仓库目录。 |
mooncake.enable_local_cache |
bool |
true |
SUSET |
写入云端对象存储时是否启用本地磁盘缓存。 |
duckdb.allow_community_extensions |
bool |
false(必须设为 true) |
SUSET |
pg_duckdb 要求开启此项以允许 pg_mooncake 加载 mooncake 存储扩展。 |
duckdb.allow_unsigned_extensions |
bool |
false(必须设为 true) |
SUSET |
允许 pg_duckdb 从本地 mooncake.extension_repository 加载编译生成的 mooncake.duckdb_extension。 |
duckdb.max_memory |
string |
4GB(或可用内存 80%) |
SUSET |
分配给内嵌 DuckDB 2.0 向量化执行引擎的最大内存上限。 |
duckdb.threads |
int |
-1(全部 CPU 核心) |
SUSET |
DuckDB 2.0 用于并行向量化查询执行的工作线程数。 |
专题参考指南
支持的分析型 SQL 查询形态、聚合与过滤、行存混合关联,以及在 PostgreSQL 中暴露 DuckDB 原生函数。
配置 AWS S3 与 Cloudflare R2 密钥、生成 Iceberg v2 快照,并从外部计算引擎直接读取 Mooncake 表。
在 PostgreSQL 内直接扫描外部 Parquet、CSV、JSON、Iceberg、Delta Lake 及 HuggingFace 数据集。
1 - 创建列存镜像表
在 pg_mooncake 中,列存表通过 mooncake.create_table 存储过程创建,作为现有 PostgreSQL 行存表(普通堆表或分区表)的**实时同步镜像(Columnstore Mirror)**运行。
存储过程签名
| 参数名称 | 类型 | 默认值 | 参数说明 |
|---|---|---|---|
dst |
text |
(必填) | 要创建的目标列存镜像表名称(支持 schema.table 格式,未指定 Schema 时默认为 public)。 |
src |
text |
(必填) | 作为复制源的 PostgreSQL 行存表或分区父表名称(支持 schema.table 格式)。 |
src_uri |
text |
NULL |
当从外部远程 PostgreSQL 实例复制时,指定远程连接串(postgresql://user:pass@host:port/dbname)。为 NULL 时默认从当前本地数据库复制。 |
table_config |
json |
NULL |
可选的 JSON 配置对象,用于定制 Moonlink 表级摄取与存储参数(例如 write_buffer_size)。 |
src_uri(而非 source_uri)上游早期 v0.2 文档中存在一处笔误,将远程连接参数写成了 source_uri => 'postgresql://...'。在 pg_mooncake 的真实 SQL 定义(src/functions.rs)中,该参数的准确名称为 src_uri。使用命名参数调用时请务必传入 src_uri => 'postgresql://...'。
1. 为当前数据库中的本地表创建镜像
省略 src_uri(或传 NULL)时,pg_mooncake 直接镜像当前数据库内的 src 表:
执行 CALL mooncake.create_table('orders_analytics', 'orders') 时后台完成的步骤:
pg_mooncake读取orders的列结构,并创建CREATE TABLE orders_analytics (...) USING mooncake。- 如果
orders没有主键,pg_mooncake会自动执行ALTER TABLE orders REPLICA IDENTITY FULL(在v0.3.0中,若orders是分区表,还会自动为所有现有叶子子分区设置REPLICA IDENTITY FULL)。 moonlink建立逻辑复制槽(pgoutput),完成orders存量行的初始快照拷贝,并开始实时流式同步后续的INSERT、UPDATE与DELETE变更。
2. 从远程 PostgreSQL 实例镜像表(src_uri)
你可以在独立的分析型 PostgreSQL 节点上部署 pg_mooncake,并通过 src_uri 实时镜像远程生产 PostgreSQL 数据库(包括自建实例、AWS RDS、Aurora、Supabase 或 Neon)中的业务表:
远程源数据库需满足以下条件:
- 已开启逻辑复制:
wal_level = logical。 src_uri中的数据库用户具备REPLICATION权限以及源表src的SELECT权限。- 若源表没有主键,需在源表上设置
REPLICA IDENTITY FULL。
3. 为分区表创建列存镜像
mooncake.create_table 原生支持 PostgreSQL 声明式分区表(PARTITION BY RANGE、LIST 或 HASH)。调用时只需将分区父表名称作为 src 传入:
create_table 之后新增子分区的注意事项在 pg_mooncake 0.3.0 中,mooncake.create_table 会自动为创建镜像时已存在的所有叶子子分区设置 REPLICA IDENTITY FULL。如果在创建镜像之后又新增了子分区(例如 CREATE TABLE events_2026_12 PARTITION OF events ...)且表没有主键,请在对新分区执行 UPDATE 或 DELETE 前手动执行 ALTER TABLE events_2026_12 REPLICA IDENTITY FULL;。
4. 高级 table_config 参数配置
你可以通过 table_config 传入 JSON 对象来定制单表级 Moonlink 行为(对应 moonlink_backend/src/table_config.rs 中的 TableConfig 结构),包括纯追加(Append-Only)模式、后台合并开关,以及自定义本地文件系统 / S3 / GCS 存储后端:
| JSON 字段路径 | 类型 | 默认值 | 参数说明 |
|---|---|---|---|
mooncake.append_only |
bool |
false |
设为 true 时将表视为纯追加模式,跳过维护主键哈希索引以提升写入吞吐。 |
mooncake.skip_index_merge |
bool |
false |
设为 true 时禁用后台 Puffin 哈希索引 LSM 树合并。 |
mooncake.skip_data_compaction |
bool |
false |
设为 true 时禁用后台 Parquet 数据文件自动合并(Compaction)。 |
iceberg.storage_config |
object |
{"fs": {"root_directory": "$PGDATA/pg_mooncake"}} |
Apache Iceberg v2 元数据与 Parquet 数据文件的存储后端(支持 fs、s3 或 gcs)。 |
wal.storage_config |
object |
{"fs": {"root_directory": "$PGDATA/pg_mooncake"}} |
Moonlink 内部 WAL 日志段的存储后端(支持 fs、s3 或 gcs)。 |
5. 删除列存镜像表
如需删除列存镜像表并自动清理其 Moonlink 元数据与逻辑复制槽,直接执行标准的 DROP TABLE 即可:
2 - 查询列存表与支持的查询形态
通过 CALL mooncake.create_table(dst, src) 创建的列存镜像表可以直接使用标准 PostgreSQL SELECT 语法进行查询。在底层,pg_mooncake 与 pg_duckdb 1.2.0 会将分析型查询自动转换并下推至内嵌的 DuckDB v2.0.0 向量化执行引擎。
查询执行机制
当你查询一张 USING mooncake 列存镜像表时:
- LSN 强一致性同步屏障:
duckdb_mooncake检查当前 PostgreSQL 的 WAL 写入 LSN,并等待moonlink将该 LSN 之前所有已提交的事务摄取完毕。 - Parquet 分段跳过(Segment Elimination):DuckDB 2.0 通过多文件读取器接口检查 Parquet 文件的列级最小/最大值统计信息,直接跳过不可能命中
WHERE过滤条件的文件与行组。 - 零拷贝混合并行扫描:利用 DuckDB 的多线程工作池(
duckdb.threads),并行融合扫描磁盘上的 Parquet 数据文件、Roaring Bitmap 删除向量以及内存中的 Apache Arrow 写缓冲区。
你可以通过 EXPLAIN 验证查询是否已由 DuckDB 接管执行:
推荐的分析型查询形态
列存镜像表专为扫描海量行、读取部分列的 OLAP 分析负载设计,相比传统 PostgreSQL 堆表通常可获得 10× 至 1000× 的查询加速。
1. 多维分组聚合(Aggregations)
2. 大数据集过滤与 Top-N 排序
3. 时序聚合与窗口分析
4. 与常规 PostgreSQL 行存表混合关联(Hybrid Joins)
你可以在同一条 SQL 中将 USING mooncake 列存镜像表与常规 PostgreSQL 行存表(如维度表、字典表)直接关联:
点查与短事务查询(请路由至原行存表)
虽然 pg_mooncake 支持任意 SELECT 语句,但针对单行主键点查(WHERE id = 12345)或极小范围索引扫描,应当直接查询源行存表(利用 PostgreSQL 的 B-Tree 索引获得亚毫秒级响应):
查询转换与调用 DuckDB 原生函数
由于针对 USING mooncake 表的查询由 DuckDB(pg_duckdb)执行,部分没有 DuckDB 直接对应实现的 PostgreSQL 特有函数(例如 to_char()、部分 regexp_* 重载或特定 jsonb_* 操作符)可能需要改写为兼容表达式。
在 PostgreSQL 中暴露 DuckDB 向量化函数
如果你希望在查询列存镜像表时调用 DuckDB 内置的分析函数(例如时序分桶函数 time_bucket),只需在 PostgreSQL 中定义一个同签名的占位 PL/pgSQL 函数。当查询下推至 DuckDB 时,pg_duckdb 会自动将其绑定到 DuckDB 的原生向量化实现:
3 - Apache Iceberg v2 与对象存储配置
pg_mooncake(v0.3.0)中的每一张列存镜像表均由 moonlink 驱动,底层数据存储为标准的 Parquet 文件,并自动维护 Apache Iceberg v2 表元数据。
默认情况下,Moonlink 将文件保存在本地数据目录 $PGDATA/pg_mooncake/ 下。你可以配置 pg_mooncake 直接将数据写入 Amazon S3、Cloudflare R2、MinIO 或 Google Cloud Storage (GCS),从而让外部数据湖计算引擎(DuckDB、Apache Spark、Trino、Snowflake、PyIceberg)直接从对象存储读取你的 PostgreSQL 表数据。
1. 配置对象存储访问凭据(duckdb.secrets)
pg_mooncake 从 pg_duckdb 的 duckdb.secrets 表中读取对象存储凭据,并自动将其同步提供给 Moonlink 与 DuckDB。
配置 Amazon S3
配置 Cloudflare R2 / S3 兼容存储(MinIO)
2. 配置表的对象存储后端(table_config 与 mooncake.default_bucket)
在 pg_mooncake v0.3.0 中,你可以通过 mooncake.create_table 的第四个参数 table_config 直接为表指定 S3 / R2 / GCS 存储后端(或参考上游 v0.1/v0.2 文档中的 mooncake.default_bucket 设置):
3. 物化生成 Apache Iceberg v2 快照
在 PostgreSQL 数据库内部查询 orders_analytics 时,会自动融合扫描已刷盘的 Parquet 文件与 Moonlink 内存中的 Arrow 写缓冲区;但外部 Iceberg 计算引擎只能看到已刷盘写入 Iceberg 元数据快照的数据。
如需强制将当前 PostgreSQL WAL LSN 之前所有已提交的数据刷盘,并生成新的 v*.metadata.json 快照文件,请调用:
v0.3.0(moonlink v0.0.1)非阻塞快照修复在 pg_mooncake 0.3.0 中,即使自上一次对 orders 表写入之后,数据库因其他无关表的写入推进了全局 WAL LSN,调用 CALL mooncake.create_snapshot('orders_analytics') 也能立即完成刷盘并返回,不会发生阻塞挂起。
4. 查看 Iceberg 仓库路径并从外部引擎查询
使用 mooncake.list_tables() 查看当前的提交 LSN、刷盘 LSN 以及准确的 iceberg_warehouse_location 路径:
示例输出:
使用外部 DuckDB / PyIceberg / Spark 直接读取
在 iceberg_warehouse_location 目录下,Moonlink 会维护标准的 Apache Iceberg v2 元数据(metadata/v1.metadata.json、v2.metadata.json 等):
5. 合并文件与清理删除向量(mooncake.optimize_table)
如需将多个小 Parquet 文件合并为大文件,并将 Roaring Bitmap 删除向量重写合并至基础数据文件中,可调用:
4 - 在 Postgres 中直接查询外部数据湖
由于 pg_mooncake(v0.3.0)通过 pg_duckdb 1.2.0 内嵌了 DuckDB v2.0.0 引擎,你可以在不将数据事先导入本地堆表的情况下,直接从 PostgreSQL 查询外部数据湖(本地磁盘、AWS S3、Cloudflare R2、GCS、HTTP 或 HuggingFace hf:// 数据集)中的文件。
支持的外部文件与表格式
- Apache Parquet(
duckdb.read_parquet) - CSV / TSV(
duckdb.read_csv) - JSON / NDJSON(
duckdb.read_json) - Apache Iceberg(
duckdb.iceberg_scan) - Delta Lake(
duckdb.delta_scan)
v0.2 / v0.3(duckdb.*)与旧版 v0.1(mooncake.*)函数区别在 pg_mooncake v0.2 与 v0.3.0 中,外部文件读取函数由 pg_duckdb 直接提供(即 duckdb.read_parquet、duckdb.read_csv、duckdb.iceberg_scan、duckdb.delta_scan)。如果你需要查阅旧版 v0.1 的 mooncake.read_parquet 语法,请参阅 v0.1 查询外部文件。
1. 查询 Parquet 文件(duckdb.read_parquet)
调用 duckdb.read_parquet 并在 AS (...) 子句中声明返回的列结构:
也支持直接扫描按 Hive 分区目录组织的文件集合:
2. 查询 CSV 文件(duckdb.read_csv)
3. 查询外部 Iceberg 与 Delta Lake 表
首先通过 duckdb.install_extension 安装并启用 DuckDB 的 iceberg 或 delta 扩展:
4. 将外部数据湖文件与 PostgreSQL 本地表关联(JOIN)
你可以在单条 SQL 查询中将外部 Parquet、Iceberg 或 Delta Lake 数据集与 PostgreSQL 普通行存表或 USING mooncake 列存镜像表直接 JOIN:
5. 直接查询 HuggingFace 数据集(hf://)
DuckDB 原生支持通过 hf://datasets/<org>/<repo>/<path> 协议直接流式读取公开的 HuggingFace 数据集: