SlideShare a Scribd company logo
www.postgrespro.ru
In-core compression:
how to shrink your database
size in several times
Aleksander Alekseev
Anastasia Lubennikova
Agenda
●
What does Postgres store?
• A couple of words about storage internals
●
Check list for your schema
• A set of tricks to optimize database size
●
In-core block level compression
• Out-of-box feature of Postgres Pro EE
●
ZSON
• Extension for transparent JSONB compression
What this talk doesn’t cover
●
MVCC bloat
• Tune autovacuum properly
• Drop unused indexes
• Use pg_repack
• Try pg_squeeze
●
Catalog bloat
• Create less temporary tables
●
WAL-log size
• Enable wal_compression
●
FS level compression
• ZFS, btrfs, etc
Data layout
Empty tables are not that empty
●
Imagine we have no data
create table tbl();
insert into tbl select from generate_series(0,1e07);
select pg_size_pretty(pg_relation_size('tbl'));
pg_size_pretty
---------------
???
Empty tables are not that empty
●
Imagine we have no data
create table tbl();
insert into tbl select from generate_series(0,1e07);
select pg_size_pretty(pg_relation_size('tbl'));
pg_size_pretty
---------------
268 MB
Meta information
db=# select * from heap_page_items(get_raw_page('tbl',0));
-[ RECORD 1 ]-------------------
lp | 1
lp_off | 8160
lp_flags | 1
lp_len | 32
t_xmin | 720
t_xmax | 0
t_field3 | 0
t_ctid | (0,1)
t_infomask2 | 2
t_infomask | 2048
t_hoff | 24
t_bits |
t_oid |
t_data |
Order matters
●
Attributes must be aligned inside the row
Safe up to 20% of space.
create table bad (i1 int, b1 bigint, i1 int);
create table good (i1 int, i1 int, b1 bigint);
NULLs for free*
●
Tuple header size: 23 bytes
●
With alignment: 24 bytes
●
Null mask is placed right after a header
●
Result: up to 8 nullable columns cost nothing
●
Also: buy one NULL, get 7 NULLs for free! (plus
alignment)
* not actually free
Alignment and B-tree
All index entries are 8 bytes aligned
create table good (i1 int, i1 int, b1 bigint);
create index idx on good (i1);
create index idx_multi on good (i1, i1);
create index idx_big on good (b1);
Alignment and B-tree
●
It cannot be smaller, but it can keep more data
●
Covering indexes* may come in handy here
• CREATE INDEX tbl_pkey (i1) INCLUDE (i2)
●
+ It enables index-only scan for READ queries
●
– It disables HOT updates for WRITE queries
*Already in PostgresPro, hopefully will be in PostgreSQL 10
Use proper data types
CREATE TABLE b AS
SELECT 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::bytea;
select lp_len, t_data from heap_page_items(get_raw_page('b',0));
lp_len | t_data
-------+---------------------------------------------------------
61 |
x4b61306565626339392d396330622d346566382d626236642d3662623962643
33830613131
CREATE TABLE u AS
SELECT 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid;
select lp_len, t_data from heap_page_items(get_raw_page('u',0));
lp_len | t_data
-------+------------------------------------
40 | xa0eebc999c0b4ef8bb6d6bb9bd380a11
Timetz vs timestamptz
●
timetz: int64 (timestamp) + int32 (timezone)
●
timestamptz: always an int64 in UTC
●
Result: time takes more space then date + time
TOAST
●
Splitting of oversized attributes with an optional
compression
• PGLZ: more or less same (speed, ratio) as ZLIB
• Heuristic: if beginning of the attribute is compressed
well then compress it
• Works out of the box for large string-like attributes
Know your data and your database
●
Use proper data types
●
Reorder columns to avoid padding
●
Pack data into bigger chunks to trigger TOAST
Know your data and your database
●
Use proper data types
●
Reorder columns to avoid padding
●
Pack data into bigger chunks to trigger TOAST
CFS
●
CFS — «compressed file system»
• Out of box (PostgresPro Enterprise Edition)
decompress
compress
Layout changes
●
Postgres layout ●
CFS layout
CFS usage
CREATE TABLESPACE cfs LOCATION
'/home/tblspc/cfs' with (compression=true);
SET default_tablespace=cfs;
CREATE TABLE tbl (x int);
INSERT INTO tbl VALUES (generate_series(1, 1000000));
UPDATE tbl set x=x+1;
SELECT cfs_start_gc(4); /* 4 — number of workers */
Pgbench performance
●
pgbench -s 1000 -i
• 2 times slower
• 98 sec → 214 sec
●
database size
• 18 times smaller
• 15334 MB → 827 MB
●
pgbench -c 10 -j 10 -t 10000
• 5% better
• 3904 TPS → 4126 TPS
Always doubt benchmarks
db=# select * from pgbench_accounts;
-[ RECORD1 ]--------------------------------------
aid | 1
bid | 1
abalance | 0
filler |
db=# d pgbench_accounts
Table "public.pgbench_accounts"
Column | Type | Collation | Nullable | Default
----------+---------------+-----------+----------+---------
aid | integer | | not null |
bid | integer | | |
abalance | integer | | |
filler | character(84) | | |
db=# select pg_column_size(filler) from pgbench_accounts;
pg_column_size
----------------
85
Comparison of
compression algoritms
Configuration Size (Gb) Time (sec)
no compression 15.31 92
snappy 5.18 99
lz4 4.12 91
postgres internal lz 3.89 214
lzfse 2.80 1099
zlib (best speed) 2.43 191
zlib (default level) 2.37 284
zstd 1.69 125
pgbench -i -s 1000
CFS: I/O usage
CPU usage
CFS pros
●
Good compression rate:
• All information on the page is compressed including
headers
●
Better locality:
• CFS always writes new pages sequentially
●
Minimal changes in Postgres core:
• CFS works at the lowest level
●
Flexibility:
• Easy to use various compression algorithms
CFS cons
●
Shared buffers utilization:
• Buffer cache keeps pages uncompressed
●
Inefficient WAL and replication:
• Replica has to perform compression and GC itself
●
Fragmentation
• CFS needs its own garbage collector
ZSON
●
An extension for transparent JSONB compression
●
A dictionary of common strings is created based
on your data (re-learning is also supported)
●
This dictionary is used to replace strings to 16 bit
codes
●
Data is compressed in memory and on the disk
●
In some cases it gives 10% more TPS
●
●
https://github.com/postgrespro/zson
How JSONB looks like
JSONB Problems
●
Redundancy
●
Disk space
●
Memory
●
=> IO & TPS
The Idea
●
Step 1 — replace common strings to 16 bit codes
●
Step 2 — compress using PGLZ as usual
zson_learn
zson_learn(
tables_and_columns text[][],
max_examples int default 10000,
min_length int default 2,
max_length int default 128,
min_count int default 2
)
Example:
select zson_learn('{{"table1", "col1"}, {"table2", "col2"}}');
zson_extract_strings
Other ZSON internals
Encoding
// VARHDRSZ
// zson_version [uint8]
// dict_version [uint32]
// decoded_size [uint32]
// hint [uint8 x PGLZ_HINT_SIZE]
// {
//skip_bytes [uint8]
//... skip_bytes bytes ...
//string_code [uint16], 0 = no_string
// } *
Thank you for your attention!
Any questions?
●
https://postgrespro.com/
●
a.lubennikova@postgrespro.ru
●
a.alekseev@postgrespro.ru
Bonus
Slides!
CFS parameters
●
cfs_gc_workers = 1
• Number of background workers performing CFS
garbage collection
●
cfs_gc_threashold = 50%
• Percent of garbage in the file after which
defragmentation begins
●
cfs_gc_period = 5 seconds
• Interval between CFS garbage collection iterations
●
cfs_gc_delay = 0 milliseconds
• Delay between files defragmentation
CFS: Compression ratio
In-memory dictionary

More Related Content

PDF
Tuning Linux for Databases.
PDF
Как PostgreSQL работает с диском
PDF
Indexes don't mean slow inserts.
PDF
Advanced backup methods (Postgres@CERN)
PDF
Toro DB- Open-source, MongoDB-compatible database, built on top of PostgreSQL
PDF
PostgreSQL na EXT4, XFS, BTRFS a ZFS / FOSDEM PgDay 2016
PDF
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
PDF
Streaming replication in practice
Tuning Linux for Databases.
Как PostgreSQL работает с диском
Indexes don't mean slow inserts.
Advanced backup methods (Postgres@CERN)
Toro DB- Open-source, MongoDB-compatible database, built on top of PostgreSQL
PostgreSQL na EXT4, XFS, BTRFS a ZFS / FOSDEM PgDay 2016
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
Streaming replication in practice

What's hot (20)

PDF
PostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 Taipei
PDF
PostgreSQL WAL for DBAs
PDF
PostgreSQL Replication Tutorial
PDF
Case Studies on PostgreSQL
PPTX
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
PDF
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
PPT
Hypertable Berlin Buzzwords
PDF
TokuDB internals / Лесин Владислав (Percona)
PDF
Analytics at Speed: Introduction to ClickHouse and Common Use Cases. By Mikha...
PDF
Pgcenter overview
PDF
XtraDB 5.7: key performance algorithms
PDF
Out of the box replication in postgres 9.4
PDF
Page compression. PGCON_2016
ODP
PostgreSQL 8.4 TriLUG 2009-11-12
PDF
Apache tajo configuration
PDF
Pgbr 2013 postgres on aws
PDF
PostgreSQL Streaming Replication Cheatsheet
PDF
PostgreSQL Troubleshoot On-line, (RITfest 2015 meetup at Moscow, Russia).
PPTX
Building Spark as Service in Cloud
PDF
XtraDB 5.6 and 5.7: Key Performance Algorithms
PostgreSQL 9.4, 9.5 and Beyond @ COSCUP 2015 Taipei
PostgreSQL WAL for DBAs
PostgreSQL Replication Tutorial
Case Studies on PostgreSQL
100500 способов кэширования в Oracle Database или как достичь максимальной ск...
PostgreSQL Configuration for Humans / Alvaro Hernandez (OnGres)
Hypertable Berlin Buzzwords
TokuDB internals / Лесин Владислав (Percona)
Analytics at Speed: Introduction to ClickHouse and Common Use Cases. By Mikha...
Pgcenter overview
XtraDB 5.7: key performance algorithms
Out of the box replication in postgres 9.4
Page compression. PGCON_2016
PostgreSQL 8.4 TriLUG 2009-11-12
Apache tajo configuration
Pgbr 2013 postgres on aws
PostgreSQL Streaming Replication Cheatsheet
PostgreSQL Troubleshoot On-line, (RITfest 2015 meetup at Moscow, Russia).
Building Spark as Service in Cloud
XtraDB 5.6 and 5.7: Key Performance Algorithms
Ad

Similar to In-core compression: how to shrink your database size in several times (20)

PDF
PgconfSV compression
PDF
PostgreSQL + ZFS best practices
PDF
PostgreSQL and Compressed Documents (pgconf.ru 2018)
PDF
Btree. Explore the heart of PostgreSQL.
PDF
Managing terabytes: When Postgres gets big
PDF
Rob Sullivan at Heroku's Waza 2013: Your Database -- A Story of Indifference
PDF
Learn how zheap works
 
PDF
Learn how zheap works
 
PDF
Managing terabytes: When PostgreSQL gets big
PDF
Performance improvements in PostgreSQL 9.5 and beyond
PDF
Grokking TechTalk #20: PostgreSQL Internals 101
PPTX
Tuning PostgreSQL for High Write Throughput
PDF
PostgreSQL on Solaris
PDF
PostgreSQL on Solaris
PDF
Indexing Complex PostgreSQL Data Types
PDF
20070920 Highload2007 Training Performance Momjian
PDF
a look at the postgresql engine
PDF
10 Reasons to Start Your Analytics Project with PostgreSQL
PDF
12 in 12 – A closer look at twelve or so new things in Postgres 12
PDF
PostgreSQL performance improvements in 9.5 and 9.6
PgconfSV compression
PostgreSQL + ZFS best practices
PostgreSQL and Compressed Documents (pgconf.ru 2018)
Btree. Explore the heart of PostgreSQL.
Managing terabytes: When Postgres gets big
Rob Sullivan at Heroku's Waza 2013: Your Database -- A Story of Indifference
Learn how zheap works
 
Learn how zheap works
 
Managing terabytes: When PostgreSQL gets big
Performance improvements in PostgreSQL 9.5 and beyond
Grokking TechTalk #20: PostgreSQL Internals 101
Tuning PostgreSQL for High Write Throughput
PostgreSQL on Solaris
PostgreSQL on Solaris
Indexing Complex PostgreSQL Data Types
20070920 Highload2007 Training Performance Momjian
a look at the postgresql engine
10 Reasons to Start Your Analytics Project with PostgreSQL
12 in 12 – A closer look at twelve or so new things in Postgres 12
PostgreSQL performance improvements in 9.5 and 9.6
Ad

More from Aleksander Alekseev (12)

PDF
Growing up new PostgreSQL developers (pgcon.org 2018)
PDF
PostgreSQL Sharding and HA: Theory and Practice (PGConf.ASIA 2017)
PDF
Data recovery using pg_filedump
PDF
Full Text Search in PostgreSQL
PDF
pg_filedump
PDF
Quality Assurance in PostgreSQL
PDF
ZSON, или прозрачное сжатие JSON
PDF
Профилирование кода на C/C++ в *nix системах
PDF
Новые технологии репликации данных в PostgreSQL - Александр Алексеев
PDF
Haskell - это просто - Александр Алексеев
PDF
Работа с Akka Cluster - Александр Алексеев
PDF
Функциональное программирование - Александр Алексеев
Growing up new PostgreSQL developers (pgcon.org 2018)
PostgreSQL Sharding and HA: Theory and Practice (PGConf.ASIA 2017)
Data recovery using pg_filedump
Full Text Search in PostgreSQL
pg_filedump
Quality Assurance in PostgreSQL
ZSON, или прозрачное сжатие JSON
Профилирование кода на C/C++ в *nix системах
Новые технологии репликации данных в PostgreSQL - Александр Алексеев
Haskell - это просто - Александр Алексеев
Работа с Akka Cluster - Александр Алексеев
Функциональное программирование - Александр Алексеев

Recently uploaded (20)

PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
Understanding_Digital_Forensics_Presentation.pptx
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
KodekX | Application Modernization Development
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
Big Data Technologies - Introduction.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Cloud computing and distributed systems.
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Review of recent advances in non-invasive hemoglobin estimation
Spectral efficient network and resource selection model in 5G networks
Understanding_Digital_Forensics_Presentation.pptx
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
The AUB Centre for AI in Media Proposal.docx
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Per capita expenditure prediction using model stacking based on satellite ima...
Unlocking AI with Model Context Protocol (MCP)
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
The Rise and Fall of 3GPP – Time for a Sabbatical?
KodekX | Application Modernization Development
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
NewMind AI Weekly Chronicles - August'25 Week I
Encapsulation_ Review paper, used for researhc scholars
Big Data Technologies - Introduction.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Cloud computing and distributed systems.
Mobile App Security Testing_ A Comprehensive Guide.pdf
20250228 LYD VKU AI Blended-Learning.pptx
Review of recent advances in non-invasive hemoglobin estimation

In-core compression: how to shrink your database size in several times

  • 1. www.postgrespro.ru In-core compression: how to shrink your database size in several times Aleksander Alekseev Anastasia Lubennikova
  • 2. Agenda ● What does Postgres store? • A couple of words about storage internals ● Check list for your schema • A set of tricks to optimize database size ● In-core block level compression • Out-of-box feature of Postgres Pro EE ● ZSON • Extension for transparent JSONB compression
  • 3. What this talk doesn’t cover ● MVCC bloat • Tune autovacuum properly • Drop unused indexes • Use pg_repack • Try pg_squeeze ● Catalog bloat • Create less temporary tables ● WAL-log size • Enable wal_compression ● FS level compression • ZFS, btrfs, etc
  • 5. Empty tables are not that empty ● Imagine we have no data create table tbl(); insert into tbl select from generate_series(0,1e07); select pg_size_pretty(pg_relation_size('tbl')); pg_size_pretty --------------- ???
  • 6. Empty tables are not that empty ● Imagine we have no data create table tbl(); insert into tbl select from generate_series(0,1e07); select pg_size_pretty(pg_relation_size('tbl')); pg_size_pretty --------------- 268 MB
  • 7. Meta information db=# select * from heap_page_items(get_raw_page('tbl',0)); -[ RECORD 1 ]------------------- lp | 1 lp_off | 8160 lp_flags | 1 lp_len | 32 t_xmin | 720 t_xmax | 0 t_field3 | 0 t_ctid | (0,1) t_infomask2 | 2 t_infomask | 2048 t_hoff | 24 t_bits | t_oid | t_data |
  • 8. Order matters ● Attributes must be aligned inside the row Safe up to 20% of space. create table bad (i1 int, b1 bigint, i1 int); create table good (i1 int, i1 int, b1 bigint);
  • 9. NULLs for free* ● Tuple header size: 23 bytes ● With alignment: 24 bytes ● Null mask is placed right after a header ● Result: up to 8 nullable columns cost nothing ● Also: buy one NULL, get 7 NULLs for free! (plus alignment) * not actually free
  • 10. Alignment and B-tree All index entries are 8 bytes aligned create table good (i1 int, i1 int, b1 bigint); create index idx on good (i1); create index idx_multi on good (i1, i1); create index idx_big on good (b1);
  • 11. Alignment and B-tree ● It cannot be smaller, but it can keep more data ● Covering indexes* may come in handy here • CREATE INDEX tbl_pkey (i1) INCLUDE (i2) ● + It enables index-only scan for READ queries ● – It disables HOT updates for WRITE queries *Already in PostgresPro, hopefully will be in PostgreSQL 10
  • 12. Use proper data types CREATE TABLE b AS SELECT 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::bytea; select lp_len, t_data from heap_page_items(get_raw_page('b',0)); lp_len | t_data -------+--------------------------------------------------------- 61 | x4b61306565626339392d396330622d346566382d626236642d3662623962643 33830613131 CREATE TABLE u AS SELECT 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'::uuid; select lp_len, t_data from heap_page_items(get_raw_page('u',0)); lp_len | t_data -------+------------------------------------ 40 | xa0eebc999c0b4ef8bb6d6bb9bd380a11
  • 13. Timetz vs timestamptz ● timetz: int64 (timestamp) + int32 (timezone) ● timestamptz: always an int64 in UTC ● Result: time takes more space then date + time
  • 14. TOAST ● Splitting of oversized attributes with an optional compression • PGLZ: more or less same (speed, ratio) as ZLIB • Heuristic: if beginning of the attribute is compressed well then compress it • Works out of the box for large string-like attributes
  • 15. Know your data and your database ● Use proper data types ● Reorder columns to avoid padding ● Pack data into bigger chunks to trigger TOAST
  • 16. Know your data and your database ● Use proper data types ● Reorder columns to avoid padding ● Pack data into bigger chunks to trigger TOAST
  • 17. CFS ● CFS — «compressed file system» • Out of box (PostgresPro Enterprise Edition) decompress compress
  • 19. CFS usage CREATE TABLESPACE cfs LOCATION '/home/tblspc/cfs' with (compression=true); SET default_tablespace=cfs; CREATE TABLE tbl (x int); INSERT INTO tbl VALUES (generate_series(1, 1000000)); UPDATE tbl set x=x+1; SELECT cfs_start_gc(4); /* 4 — number of workers */
  • 20. Pgbench performance ● pgbench -s 1000 -i • 2 times slower • 98 sec → 214 sec ● database size • 18 times smaller • 15334 MB → 827 MB ● pgbench -c 10 -j 10 -t 10000 • 5% better • 3904 TPS → 4126 TPS
  • 21. Always doubt benchmarks db=# select * from pgbench_accounts; -[ RECORD1 ]-------------------------------------- aid | 1 bid | 1 abalance | 0 filler | db=# d pgbench_accounts Table "public.pgbench_accounts" Column | Type | Collation | Nullable | Default ----------+---------------+-----------+----------+--------- aid | integer | | not null | bid | integer | | | abalance | integer | | | filler | character(84) | | | db=# select pg_column_size(filler) from pgbench_accounts; pg_column_size ---------------- 85
  • 22. Comparison of compression algoritms Configuration Size (Gb) Time (sec) no compression 15.31 92 snappy 5.18 99 lz4 4.12 91 postgres internal lz 3.89 214 lzfse 2.80 1099 zlib (best speed) 2.43 191 zlib (default level) 2.37 284 zstd 1.69 125 pgbench -i -s 1000
  • 25. CFS pros ● Good compression rate: • All information on the page is compressed including headers ● Better locality: • CFS always writes new pages sequentially ● Minimal changes in Postgres core: • CFS works at the lowest level ● Flexibility: • Easy to use various compression algorithms
  • 26. CFS cons ● Shared buffers utilization: • Buffer cache keeps pages uncompressed ● Inefficient WAL and replication: • Replica has to perform compression and GC itself ● Fragmentation • CFS needs its own garbage collector
  • 27. ZSON ● An extension for transparent JSONB compression ● A dictionary of common strings is created based on your data (re-learning is also supported) ● This dictionary is used to replace strings to 16 bit codes ● Data is compressed in memory and on the disk ● In some cases it gives 10% more TPS ● ● https://github.com/postgrespro/zson
  • 30. The Idea ● Step 1 — replace common strings to 16 bit codes ● Step 2 — compress using PGLZ as usual
  • 31. zson_learn zson_learn( tables_and_columns text[][], max_examples int default 10000, min_length int default 2, max_length int default 128, min_count int default 2 ) Example: select zson_learn('{{"table1", "col1"}, {"table2", "col2"}}');
  • 34. Encoding // VARHDRSZ // zson_version [uint8] // dict_version [uint32] // decoded_size [uint32] // hint [uint8 x PGLZ_HINT_SIZE] // { //skip_bytes [uint8] //... skip_bytes bytes ... //string_code [uint16], 0 = no_string // } *
  • 35. Thank you for your attention! Any questions? ● https://postgrespro.com/ ● a.lubennikova@postgrespro.ru ● a.alekseev@postgrespro.ru
  • 37. CFS parameters ● cfs_gc_workers = 1 • Number of background workers performing CFS garbage collection ● cfs_gc_threashold = 50% • Percent of garbage in the file after which defragmentation begins ● cfs_gc_period = 5 seconds • Interval between CFS garbage collection iterations ● cfs_gc_delay = 0 milliseconds • Delay between files defragmentation