Executando verificação de segurança...
3

Pitch: Publiquei uma extensão de armazenamento para PostgreSQL 18 🐘

storage_engine: Armazenamento Colunar e por Lotes para PostgreSQL 18

storage_engine é uma extensão open-source que adiciona dois novos mecanismos de armazenamento (Table Access Methods) ao PostgreSQL — sem precisar modificar o core do banco:

colcompress — armazenamento colunar, leitura vetorizada, pruning de stripes por min/max (estilo MergeTree do ClickHouse, mas dentro do PostgreSQL)

rowcompress — linhas comprimidas em lotes, com suporte a DELETE/UPDATE e scan paralelo


Compressão real

Uma tabela de 3.353 MB de documentos fiscais (XML + metadados) ficou em 89 MB com colcompress/zstd — redução de 38× — sem perder nenhuma funcionalidade do PostgreSQL.

TabelaEngineTamanhoRedução
documentos_fiscaisheap3.353 MB
documentos_fiscais_colcolcompress/zstd104 MB32×
documentos_fiscais_col_sortedcolcompress/zstd + merge89 MB38×
documentos_fiscais_rowrowcompress/zstd110 MB30×

Benchmark — 1 milhão de linhas, PostgreSQL 18

17 colunas (numérico, texto, JSONB, arrays, booleanos), compressão lz4, dados pré-ordenados por event_date e mergeados.

Serial (núcleo único, JIT off)

Queryheapcolcompressrowcompresscitus_columnar
count(*) full scan39 ms42 ms314 ms37 ms
SUM/AVG numérico+double181 ms119 ms364 ms126 ms
GROUP BY 10 países215 ms161 ms400 ms136 ms
GROUP BY + percentil p95534 ms446 ms689 ms469 ms
DATE range (1 mês, pruned)21 ms23 ms60 ms21 ms
JSONB @> filtro125 ms159 ms329 ms237 ms
JSONB key + GROUP BY382 ms310 ms547 ms350 ms
Array @> filtro62 ms126 ms272 ms143 ms
LIKE text scan147 ms93 ms344 ms95 ms
Agregação pesada (10 métricas)1.953 ms1.970 ms2.098 ms1.948 ms

Paralelo (JIT on, 16 workers)

Queryheapcolcompressrowcompresscitus_columnar
count(*) full scan18 ms16 ms149 ms38 ms
SUM/AVG numérico+double51 ms31 ms147 ms123 ms
DATE range (1 mês)21 ms29 ms70 ms21 ms
JSONB @> filtro83 ms44 ms471 ms240 ms
JSONB key + GROUP BY390 ms67 ms697 ms358 ms
Array @> filtro60 ms34 ms275 ms144 ms
LIKE text scan44 ms26 ms145 ms91 ms
Agregação pesada (10 métricas)1.960 ms674 ms2.111 ms1.957 ms

O citus_columnar não paraleliza — os tempos são praticamente idênticos entre serial e paralelo. O colcompress alcança 2,9× de speedup na agregação pesada com 16 workers (1.970 ms → 674 ms).


Dois casos de uso, uma extensão

📊 Analítico (orderby + merge)

Defina um orderby, carregue os dados, execute engine.colcompress_merge(). O planner passa a ignorar stripes inteiras com base em estatísticas min/max — antes de descomprimir um único byte. Não crie índices B-tree nas colunas do orderby: um B-tree faz o planner escolher IndexScan, desabilitando o pruning.

SELECT engine.alter_colcompress_table_set('events'::regclass,
    orderby     => 'event_date ASC',
    compression => 'lz4'
);
SELECT engine.colcompress_merge('events');

🗄️ Repositório de arquivos (index_scan)

Habilite index_scan = true por tabela. A extensão adiciona um scan path customizado que busca apenas as linhas apontadas pelo índice B-tree existente. Combina compressão zstd 30–38× com velocidade de point-lookup — ideal para tabelas de documentos (XML, PDF, JSON) onde cada busca é por chave específica.

SELECT engine.alter_colcompress_table_set('documents'::regclass,
    compression => 'zstd',
    index_scan  => true
);

Instalação

git clone https://github.com/saulojb/storage_engine
cd storage_engine
sudo make -j$(nproc) install
-- postgresql.conf
shared_preload_libraries = 'storage_engine'

-- no banco
CREATE EXTENSION storage_engine;
CREATE TABLE events (...) USING colcompress;

🔗 GitHub: https://github.com/saulojb/storage_engine
📦 PGXN: https://pgxn.org/dist/storage_engine/

O kit de benchmark completo (SQL de setup, scripts de execução, gerador de gráficos) está em tests/bench/.


Proveniência: storage_engine é um fork reestruturado do Hydra Columnar, que por sua vez deriva do Citus Columnar (Citus Data / Microsoft). O formato colunar de base (stripes, chunks, compressão) vem desse trabalho upstream. As adições desta versão incluem: schema engine, rowcompress AM, orderby sort key por tabela, pruning de stripes por min/max, scan paralelo DSM, ANALYZE rápido por amostragem de chunk groups, DELETE/UPDATE para rowcompress, e os fixes de SIGSEGV e index scan. Atribuições completas no arquivo NOTICE (AGPLv3).


Saulo José Benvenutti — Arquiteto de Dados / DBA PostgreSQL
📧 saulojb@gmail.com · 🔗 github.com/saulojb

Carregando publicação patrocinada...