专栏名称: OSC开源社区
OSChina 开源中国 官方微信账号
目录
相关文章推荐
程序员的那些事  ·  疯了!我那些怀疑 AI ... ·  4 天前  
程序猿  ·  Spring 之父:我不是 Java ... ·  4 天前  
稀土掘金技术社区  ·  协程中使用 ... ·  4 天前  
51好读  ›  专栏  ›  OSC开源社区

pg_mooncake:PostgreSQL的高性能列存新贵

OSC开源社区  · 公众号  · 程序员  · 2025-06-04 20:20

正文

请到「今天看啥」查看全文


mooncake.enable_memory_metadata_cache

Enable memory cache for Parquet metadata

mooncake.maximum_memory

The maximum memory DuckDB can use (e.g., 1GB)

mooncake.maximum_threads

Maximum number of DuckDB threads per Postgres backend

上面我们有说过pg_mooncake是将pg_duckdb糅合在一起,那可能有的朋友就很好奇,可能会提出这样子的疑问就是说那么pg_duckdb的参数在pg_mooncake中是否有效呢?

答案是无效的,让我们简单看一下 pgmooncake.cpp中的 _PG_init 就一目了然了

void _PG_init() {    MooncakeInitGUC();    DuckdbInitHooks();     DuckdbInitNode();    pgduckdb::RegisterDuckdbXactCallback();// 略过部分代码}

可以看到pg_mooncake在_PG_init时不初始化pg_duckdb的相关参数,所以pg_duckdb的相关参数自然就无效了。

同时我们注意到它调用了pg_duckdb的DuckdbInitHooks、DuckdbInitNode这两个接口(内部实际会有些许改动),也就是说从代码层面论证了我们在上一篇文章中讲到的内容在pg_mooncake依旧有效。

所以实际上来说,什么都不需要设置,创建完拓展之后就可以愉快的玩耍了。


3.2、简单使用

在最开始的时候,我们指出了pg_duckdb的性能瓶颈可能在于将PostgreSQL中存储的行数据转换成duckdb的列数据。并且pg_duckdb仅对 SELECT语句进行了额外的处理,对于其他SQL语句而言,如INSERT、UPDATE、DETELE都是交由PostgreSQL处理。

可能是pg_mooncake看到了这些痛点,所以它将INSERT、UPDATE、DETELE等等都给支持了,并在执行这些相关语句的时候,创建对应的Parquet文件, 并存储相关数据。当访问列存表时,对于数据加载那块便仅需要访问对应的 Parquet文件即可,就这样避免了pg_duckdb在加载数据时的需要付出的昂贵成本。

而且物理文件使用Parquet文件作为外部存储,对于构建数据湖也很方便。

以官方 的测试案例为例:

[postgres@halo-centos8 mooncake_local_tables]$ psql mooncakepsql (16.8)Type "help" for help.
mooncake=# \dx                    List of installed extensions    Name     | Version |   Schema   |          Description          -------------+---------+------------+------------------------------- pg_mooncake | 0.1.2   | public     | Columnstore Table in Postgres plpgsql     | 1.0     | pg_catalog | PL/pgSQL procedural language(2 rows)
mooncake=-- 创建列存表mooncake=CREATE TABLE user_activity(mooncake(#   user_id BIGINT,mooncake(#   activity_type TEXT,mooncake(#   activity_timestamp TIMESTAMP,mooncake(#   duration INTmooncake(# ) USING columnstore;CREATE TABLEmooncake=-- 通过explain来简单判断INSERT是否被支持mooncake=# EXPLAIN VERBOSE INSERT INTO user_activity VALUESmooncake-#   (1'login''2024-01-01 08:00:00'120),mooncake-#   (2'page_view''2024-01-01 08:05:00'30),mooncake-#   (3'logout''2024-01-01 08:30:00'60),mooncake-#   (4'error''2024-01-01 08:13:00'60);                             QUERY PLAN                             -------------------------------------------------------------------- Custom Scan (MooncakeDuckDBScan)  (cost=0.00..0.00 rows=0 width=0)   Output: duckdb_scan.explain_key, duckdb_scan.explain_value   DuckDB Execution Plan: 
 ┌───────────────────────────┐ │     COLUMNSTORE_INSERT    │ └─────────────┬─────────────┘ ┌─────────────┴─────────────┐ │      COLUMN_DATA_SCAN     │ │    ────────────────────   │ │          ~4 Rows          │ └───────────────────────────┘

(14 rows)
mooncake=-- 插入数据mooncake=INSERT INTO user_activity VALUESmooncake-#   (1'login''2024-01-01 08:00:00'120),mooncake-#   (2'page_view''2024-01-01 08:05:00'30),mooncake-#   (3'logout''2024-01-01 08:30:00'60),mooncake-#   (4'error''2024-01-01 08:13:00'60);INSERT 0 4mooncake=-- 查询数据mooncake=SELECT * from user_activity; user_id | activity_type | activity_timestamp  | duration ---------+---------------+---------------------+----------       1 | login         | 2024-01-01 08:00:00 |      120       2 | page_view     | 2024-01-01 08:05:00 |       30       3 | logout        | 2024-01-01 08:30:00 |       60       4 | error         | 2024-01-01 08:13:00 |       60






请到「今天看啥」查看全文