SlideShare a Scribd company logo
Where is the space, Postgres?
Alexey Ermakov
alexey.ermakov@postgresql-consulting.com
2
О чем сегодня будем говорить
• Куда уходит свободное место?
• Инструменты и запросы
• Каким образом данные в действительности хранятся?
• Действия в аварийной и предаварийной ситуациях
3
Database File Layout
Проблемные места
base
global
pg_clog
pg_dynshmem
pg_log
pg_logical
pg_multixact
pg_notify
pg_replslot
pg_serial
pg_snapshots
pg_stat
pg_stat_tmp
pg_subtrans
pg_tblspc
|-- ~16407 ->
pg_twophase
pg_xlog
4
Database File Layout
Хранение таблиц и индексов
base
|-- 1
|-- 13051
|-- 13056
|-- 79593 481080K
|-- 90694 1024M
|-- 90694.1 1024M
|-- 90694.2 903136K
|-- 90694_fsm 1564672
|-- 90694_vm 0
|-- ...
|-- ...
|-- pgsql_tmp
5
pgsql_tmp
Временные файлы
• пишутся при нехватке work_mem, maintenance_work_mem
• temp_file_limit (9.2+)
• log_temp_files
6
pg_log
Логи
• log_min_duration_statement
• log_directory
• log_filename
• no limit for message length
7
pg_xlog expected size
Write Ahead Log (журнал транзакций)
• 1 WAL segment 16MB
• used for recovery and replication
• removed/recycled after checkpoint
MAX
checkpoint_segments + wal_keep_segments
(2 + checkpoint_completion_target) ∗ checkpoint_segments
8
pg_xlog more than expected size
• broken archive_command
• replication slots
• slow replay
• CPU or I/O overload (renice/ionice startup process)
• long running transactions on standby
9
TOP 20 largest databases
pg-utils/sql/top_databases.sql
name | owner | size
----------+----------+---------
the | postgres | 74 GB
quick | postgres | 65 GB
brown | postgres | 41 GB
fox | postgres | 36 GB
jumps | postgres | 30 GB
over | postgres | 28 GB
lazy | postgres | 25 GB
dog | postgres | 13 GB
10
TOP 20 largest tables/indexes in selected DB
pg-utils/sql/top_tables.sql
nspname | relname | type | size | idxsize | total
---------+--------------------------+------+---------+---------+---------
public | posts | r | 20 GB | 24 GB | 43 GB
public | users | r | 4152 MB | 3215 MB | 7367 MB
public | posts_type_id_created_at | i | 4861 MB | 0 bytes | 4861 MB
public | posts_user_id | i | 2612 MB | 0 bytes | 2612 MB
11
Unused indexes
github.com/pgexperts/pgx_scripts/indexes/unused_indexes.sql
table/index index scans per index table
reason | name | scan % | write | size | size
---------------------------+-----------+--------+----------+---------+---------
Never Used Indexes | ... | 0.00 | 0.00 | 18 GB | 78 GB
Never Used Indexes | ... | 0.00 | 0.00 | 6371 MB | 64 GB
Never Used Indexes | ... | 0.00 | 0.00 | 4875 MB | 64 GB
Never Used Indexes | ... | 0.00 | 0.00 | 4412 MB | 64 GB
Low Scans, High Writes | ... | 0.00 | 0.00 | 6358 MB | 64 GB
Low Scans, High Writes | ... | 0.00 | 0.00 | 6290 MB | 64 GB
Seldom Used Large Indexes | ... | 0.24 | 29811.00 | 1171 MB | 8726 MB
Seldom Used Large Indexes | ... | 0.00 | 3.00 | 1121 MB | 8726 MB
12
Duplicate indexes
github.com/pgexperts/pgx_scripts/indexes/duplicate_indexes_fuzzy.sql
table index index
name | name | cols | indexdef | index_scans
-------+-----------+-------+-------------------------------------+-------------
users | users_a | a | CREATE INDEX ... USING btree (a) | 10140
users | users_a_b | a,b | CREATE INDEX ... USING btree (a, b) | 2194900
13
Compact indexes
Иногда можно создать более компактный индекс
• Partial indexes
• gin indexes (btree_gin) for duplicates
• BRIN indexes
14
Bloat
• multiversion concurrency control (MVCC)
• При каждом update строки создается ее копия
• Ненужные копии подчищаются процессом autovacuum
• autovacuum не может уменьшить размер таблицы, если
только нет пустых страниц в конце файла
15
Bloat
create table test(id integer primary key, flag boolean not null);
insert into test values(1, false);
select to_hex(xmin::text::bigint) as xmin, * from test;
xmin | id | flag
------+----+------
3ec | 1 | f
16
Bloat
update test set flag = true where id = 1;
select to_hex(xmin::text::bigint) as xmin, * from test;
xmin | id | flag
------+----+------
3ed | 1 | t
17
Where did all you zombies come from?
• Long running transactions
• Not tuned autovacuum
• Update large number of rows
• Delete large number of rows
• Drop columns
18
Long running transactions
Как бороться?
• Мониторинг длины самой долгой транзакции (на репликах
с hot_standby_feedback = on тоже!)
• Автоматически прибивать по крону (см.
pg_terminate_backend(), pg_stat_activity)
• Модифицировать приложение
• pg_dump ⇒ pg_basebackup
19
autovacuum
• autovacuum_vacuum_scale_factor по-умолчанию 0.2 (20%
таблицы)
• autovacuum_max_workers
• autovacuum_vacuum_cost_delay
20
Bloat estimation
Оценка bloat на основе данных статистики с разной
степенью достоверности
• heroku pg:bloat github.com/heroku/heroku-pg-extras
• check_postgres.pl
bucardo.org/check_postgres/check_postgres.pl.html
• github.com/ioguix/pgsql-bloat-estimation
• pgstattuple extension
21
Table bloat
pg-utils/sql/table_bloat.sql
table total
total toast waste table waste total
nspname | relname | size | size | percent | waste | percent | waste
---------+-----------+---------+---------+---------+--------+---------+--------
public | obscure | 22 GB | 0 bytes | 72.9 | 16 GB | 72.9 | 16 GB
public | problems | 4814 MB | 0 bytes | 11.6 | 558 MB | 11.6 | 558 MB
public | may | 3428 MB | 8192 by | 2.0 | 68 MB | 2.0 | 68 MB
public | require | 103 MB | 0 bytes | 49.1 | 51 MB | 49.1 | 51 MB
public | unusual | 279 MB | 11 MB | 8.8 | 24 MB | 10.4 | 29 MB
public | solutions | 59 MB | 0 bytes | 41.3 | 24 MB | 41.3 | 24 MB
22
Index bloat
pg-utils/sql/index_bloat.sql (btree indexes only)
table table index index index waste
schema | name | size | name | size | scans | percent | waste
--------+-------+---------+------------+---------+---------+---------+---------
public | alfa | 7046 MB | alfa_unifo | 6226 MB | 273454 | 80.0 | 5041 MB
public | alfa | 7046 MB | alfa_romeo | 4630 MB | 324259 | 69.0 | 3226 MB
public | bravo | 11 GB | bravo_hote | 6197 MB | 3562344 | 13.0 | 808 MB
public | alfa | 7046 MB | alfa_lima | 2154 MB | 6140 | 35.0 | 754 MB
public | delta | 13 GB | delta_echo | 1500 MB | 3045468 | 40.0 | 613 MB
public | alfa | 7046 MB | alfa_charl | 1850 MB | 2699598 | 24.0 | 454 MB
public | delta | 5421 MB | delta_foxt | 1780 MB | 12774 | 18.0 | 329 MB
23
VACUUM FULL/CLUSTER
• exclusive lock
• requires additional space
• could be optimal for small tables
24
create new empty table and swap with existing
• подходит для insert-only таблиц (логи)
• быстро
25
pg_repack
• позволяет сделать cluster таблицы
• требует дополнительное место под копию таблицы
• модифицирует системные каталоги
26
pgcompact/pgcompacttable
• не требует места под копию таблицы
• можно регулировать нагрузку на диски
• работает на уровне приложения
27
pgcompact/pgcompacttable как работает?
• initial vacuum table
• определение bloat таблиц/индексов
• fake updates: update only xxx set a=a where ctid = ANY(?)
• vacuum table
• reindex concurrently
28
pgcompacttable проблемы
• возможное неиспользование индексов на реплике с
pgbouncer 1
• не делается analyze после пересоздания функциональных
индексов
• нет таймаута на alter index xxx rename to yyy
• можно сгенерировать значительное количество WAL
• не сжимает toast’ы
1
http://bit.ly/28YR0F0 Relation cache invalidation on replica
29
TOAST
What is your function?
30
TOAST
• хранение длинных (2kb+) значений
• разбивает на chunk’и по 2кб и хранит в специальной
таблице в схеме pg_toast
• может сжимать данные алгоритмом LZ
• toast таблицы нельзя модифицировать
31
TOAST
#create table test_toast (id serial primary key, payload text);
#insert into test_toast (payload)
select string_agg(md5(j::text),’’) from generate_series(1,1000) gs(j);
INSERT 0 1
# select reltoastrelid::regclass from pg_class where relname = ’test_toast’;
pg_toast.pg_toast_216572
# d+ pg_toast.pg_toast_216572
TOAST table "pg_toast.pg_toast_216572"
Column | Type | Storage
------------+---------+---------
chunk_id | oid | plain
chunk_seq | integer | plain
chunk_data | bytea | plain
32
TOAST cleanup ?
update products set description = description || ’’
where id >= ... and id < ...;
vacuum products;
33
Tuples storage
• 23 bytes tuple header
• 1 byte padding or null bitmask
• total tuple size is multiple of MAXALIGN (8 bytes on x64)
34
Paddings
Какая таблица меньше?
test_paddings (
id integer,
is_active bool,
created_at timestamp,
is_removed bool,
updated_at timestamp
);
test_paddings2 (
id integer,
created_at timestamp,
updated_at timestamp,
is_active bool,
is_removed bool
);
test_paddings3 (
id integer,
is_active bool,
is_removed bool,
created_at timestamp,
updated_at timestamp
);
insert into test_paddings* ...
INSERT 0 100000
35
Paddings
Какая таблица меньше?
test_paddings (
id integer,
is_active bool,
created_at timestamp,
is_removed bool,
updated_at timestamp
);
5912 kB
test_paddings2 (
id integer,
created_at timestamp,
updated_at timestamp,
is_active bool,
is_removed bool
);
5912 kB
test_paddings3 (
id integer,
is_active bool,
is_removed bool,
created_at timestamp,
updated_at timestamp
);
5120 kB
36
Paddings
37
Paddings
select ... from pg_type where typname in (...) order by typlen;
typname | typlen | typalign
-----------+--------+----------
json | -1 | 4
jsonb | -1 | 4
numeric | -1 | 4
varchar | -1 | 4
text | -1 | 4
bool | 1 | 1
int2 | 2 | 2
int4 | 4 | 4
date | 4 | 4
float8 | 8 | 8
timestamp | 8 | 8
int8 | 8 | 8
38
Empty values
name | pg_column_size
------------+----------------
null | 02
’’::text | 4
’{}’::json | 6
’{}’::jsonb | 8
’{}’::int[] | 16
2
when less than 8 nullable fields in a row
39
Emergency? Monitoring!
• check long running transactions
• wal_keep_segments, checkpoint_segments (max_wal_size)
• reserved space
• remove/compress logs
• check biggest tables/indexes
• move to another tablespace
40
Not an emergency?
• Знаем размеры типов, tuple header, paddings
• Удаляем/архивируем ненужное (таблицы, индексы)
• Боремся с bloat
• Следим за местом
• Планируем обновление дисков заранее
41
Useful links
• PostgreSQL Manual 63.1. Database File Layout
• Different Approaches for MVCC used in well known Databases
• PostgreSQL Manual 63.2. TOAST
• github.com/pgexperts/pgx_scripts
• github.com/reorg/pg_repack
• github.com/grayhemp/pgtoolkit
• github.com/PostgreSQL-Consulting/pgcompacttable
• github.com/PostgreSQL-Consulting/pg-utils
• www.slideshare.net/alexius2/
42
Questions?
alexey.ermakov@postgresql-consulting.com

More Related Content

What's hot (20)

PPTX
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Ontico
 
PDF
Call of Postgres: Advanced Operations (part 1)
Alexey Lesovsky
 
PDF
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Ontico
 
PDF
Лекция 10. Apache Mahout
Technopark
 
ODP
Hacking PostgreSQL. Физическое представление данных
Anastasia Lubennikova
 
PDF
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
it-people
 
PDF
"Деплой кода процедур" Мурат Кабилов (Avito)
AvitoTech
 
PPTX
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
Ontico
 
PDF
Реализация восстановления после аварий / Сергей Бурладян (Avito)
Ontico
 
PDF
Devconf2012 what-is-mariadb-5.5
Sergey Petrunya
 
PDF
Михаил Давыдов — JavaScript: Асинхронность
Yandex
 
PPTX
Mysql vs postgresql
Daniel Podolsky
 
PDF
Hacking PostgreSQL. Локальная память процессов. Контексты памяти.
Anastasia Lubennikova
 
PDF
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Alexey Lesovsky
 
PDF
"Секционирование без границ" Ильдар Мусин (Postgres Professional)
AvitoTech
 
PDF
20130429 dynamic c_c++_program_analysis-alexey_samsonov
Computer Science Club
 
PDF
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
Yandex
 
PDF
MariaDB 10.4 - что нового
Sergey Petrunya
 
PDF
Магия в Python: Дескрипторы. Что это?
PyNSK
 
PDF
Call of Postgres: Advanced Operations (part 4)
Alexey Lesovsky
 
Оптимизация работы с данными в мобильных приложениях / Святослав Иванов, Артё...
Ontico
 
Call of Postgres: Advanced Operations (part 1)
Alexey Lesovsky
 
Мониторинг ожиданий в PostgreSQL / Курбангалиев Ильдус (Postgres Professional)
Ontico
 
Лекция 10. Apache Mahout
Technopark
 
Hacking PostgreSQL. Физическое представление данных
Anastasia Lubennikova
 
«Память и Python. Что надо знать для счастья?» Алексей Кузьмин, ЦНС
it-people
 
"Деплой кода процедур" Мурат Кабилов (Avito)
AvitoTech
 
Денормализованное хранение данных в PostgreSQL 9.2 (Александр Коротков)
Ontico
 
Реализация восстановления после аварий / Сергей Бурладян (Avito)
Ontico
 
Devconf2012 what-is-mariadb-5.5
Sergey Petrunya
 
Михаил Давыдов — JavaScript: Асинхронность
Yandex
 
Mysql vs postgresql
Daniel Podolsky
 
Hacking PostgreSQL. Локальная память процессов. Контексты памяти.
Anastasia Lubennikova
 
Отладка и устранение проблем в PostgreSQL Streaming Replication.
Alexey Lesovsky
 
"Секционирование без границ" Ильдар Мусин (Postgres Professional)
AvitoTech
 
20130429 dynamic c_c++_program_analysis-alexey_samsonov
Computer Science Club
 
FrontTalks: Михаил Давыдов (Яндекс), «Promise – это не больно»
Yandex
 
MariaDB 10.4 - что нового
Sergey Petrunya
 
Магия в Python: Дескрипторы. Что это?
PyNSK
 
Call of Postgres: Advanced Operations (part 4)
Alexey Lesovsky
 

Viewers also liked (9)

PDF
Using PostgreSQL statistics to optimize performance
Alexey Ermakov
 
PDF
PostgreSQL Meetup Berlin at Zalando HQ
PostgreSQL-Consulting
 
PDF
PostgreSQL Troubleshoot On-line, (RITfest 2015 meetup at Moscow, Russia).
Alexey Lesovsky
 
PDF
Autovacuum, explained for engineers, new improved version PGConf.eu 2015 Vienna
PostgreSQL-Consulting
 
PDF
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
PostgreSQL-Consulting
 
PDF
Streaming replication in practice
Alexey Lesovsky
 
PDF
Linux tuning to improve PostgreSQL performance
PostgreSQL-Consulting
 
PDF
Troubleshooting PostgreSQL Streaming Replication
Alexey Lesovsky
 
PDF
Deep dive into PostgreSQL statistics.
Alexey Lesovsky
 
Using PostgreSQL statistics to optimize performance
Alexey Ermakov
 
PostgreSQL Meetup Berlin at Zalando HQ
PostgreSQL-Consulting
 
PostgreSQL Troubleshoot On-line, (RITfest 2015 meetup at Moscow, Russia).
Alexey Lesovsky
 
Autovacuum, explained for engineers, new improved version PGConf.eu 2015 Vienna
PostgreSQL-Consulting
 
How does PostgreSQL work with disks: a DBA's checklist in detail. PGConf.US 2015
PostgreSQL-Consulting
 
Streaming replication in practice
Alexey Lesovsky
 
Linux tuning to improve PostgreSQL performance
PostgreSQL-Consulting
 
Troubleshooting PostgreSQL Streaming Replication
Alexey Lesovsky
 
Deep dive into PostgreSQL statistics.
Alexey Lesovsky
 
Ad

Similar to Where is the space, Postgres? (20)

PDF
PostgreSQL worst practices / Илья Космодемьянский (Data Egret)
Ontico
 
PDF
Народные средства оптимизации PostgreSQL
Nikolay Pisarev
 
PDF
"Мы два месяца долбались, а потом построили индекс" (c) Аксенов
Alex Chistyakov
 
PDF
Павел Лузанов, Postgres Professional. «PostgreSQL для пользователей Oracle»
Mail.ru Group
 
PPT
SAMag2007 Conference: PostgreSQL 8.3 presentation
Nikolay Samokhvalov
 
PDF
Расширяемость PostgreSQL для хакеров и архитекторов / Олег Бартунов, Александ...
Ontico
 
PDF
Postgresql v509
luis perez
 
PDF
Optimization of a big PostgreSQL database
Alex Chistyakov
 
PDF
Владимир Бородин - PostgreSQL
Yandex
 
PDF
Hacking PostgreSQL. Обзор архитектуры.
Anastasia Lubennikova
 
PDF
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
Nikolay Samokhvalov
 
PDF
PG Day'14 Russia, PostgreSQL в avito.ru, Михаил Тюрин
pgdayrussia
 
PDF
PostgreSQL
dev1ant
 
PDF
PostgreSQL Vacuum: Nine Circles of Hell
Alexey Lesovsky
 
PDF
PostgreSQL: вчера, сегодня, завтра, Олег Бартунов, Postgres Professional, Мо...
it-people
 
PDF
SECON'2016. Бартунов Олег, Карьера в Open Source
SECON
 
PDF
PostgreSQL on sas/ssd/nvme/nvdimm
Дмитрий Васильев
 
PDF
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassa...
it-people
 
PDF
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consu...
Ontico
 
PDF
Беспроблемная эксплуатация PostgreSQL
Дмитрий Васильев
 
PostgreSQL worst practices / Илья Космодемьянский (Data Egret)
Ontico
 
Народные средства оптимизации PostgreSQL
Nikolay Pisarev
 
"Мы два месяца долбались, а потом построили индекс" (c) Аксенов
Alex Chistyakov
 
Павел Лузанов, Postgres Professional. «PostgreSQL для пользователей Oracle»
Mail.ru Group
 
SAMag2007 Conference: PostgreSQL 8.3 presentation
Nikolay Samokhvalov
 
Расширяемость PostgreSQL для хакеров и архитекторов / Олег Бартунов, Александ...
Ontico
 
Postgresql v509
luis perez
 
Optimization of a big PostgreSQL database
Alex Chistyakov
 
Владимир Бородин - PostgreSQL
Yandex
 
Hacking PostgreSQL. Обзор архитектуры.
Anastasia Lubennikova
 
Промышленный подход к тюнингу PostgreSQL: эксперименты над базами данных
Nikolay Samokhvalov
 
PG Day'14 Russia, PostgreSQL в avito.ru, Михаил Тюрин
pgdayrussia
 
PostgreSQL
dev1ant
 
PostgreSQL Vacuum: Nine Circles of Hell
Alexey Lesovsky
 
PostgreSQL: вчера, сегодня, завтра, Олег Бартунов, Postgres Professional, Мо...
it-people
 
SECON'2016. Бартунов Олег, Карьера в Open Source
SECON
 
PostgreSQL on sas/ssd/nvme/nvdimm
Дмитрий Васильев
 
Aleksey Yeschenko "Моделирование данных с помощью CQL3". Выступление на Cassa...
it-people
 
Девять кругов ада или PostgreSQL Vacuum / Алексей Лесовский (PostgreSQL-Consu...
Ontico
 
Беспроблемная эксплуатация PostgreSQL
Дмитрий Васильев
 
Ad

Where is the space, Postgres?

  • 1. Where is the space, Postgres? Alexey Ermakov [email protected]
  • 2. 2 О чем сегодня будем говорить • Куда уходит свободное место? • Инструменты и запросы • Каким образом данные в действительности хранятся? • Действия в аварийной и предаварийной ситуациях
  • 3. 3 Database File Layout Проблемные места base global pg_clog pg_dynshmem pg_log pg_logical pg_multixact pg_notify pg_replslot pg_serial pg_snapshots pg_stat pg_stat_tmp pg_subtrans pg_tblspc |-- ~16407 -> pg_twophase pg_xlog
  • 4. 4 Database File Layout Хранение таблиц и индексов base |-- 1 |-- 13051 |-- 13056 |-- 79593 481080K |-- 90694 1024M |-- 90694.1 1024M |-- 90694.2 903136K |-- 90694_fsm 1564672 |-- 90694_vm 0 |-- ... |-- ... |-- pgsql_tmp
  • 5. 5 pgsql_tmp Временные файлы • пишутся при нехватке work_mem, maintenance_work_mem • temp_file_limit (9.2+) • log_temp_files
  • 6. 6 pg_log Логи • log_min_duration_statement • log_directory • log_filename • no limit for message length
  • 7. 7 pg_xlog expected size Write Ahead Log (журнал транзакций) • 1 WAL segment 16MB • used for recovery and replication • removed/recycled after checkpoint MAX checkpoint_segments + wal_keep_segments (2 + checkpoint_completion_target) ∗ checkpoint_segments
  • 8. 8 pg_xlog more than expected size • broken archive_command • replication slots • slow replay • CPU or I/O overload (renice/ionice startup process) • long running transactions on standby
  • 9. 9 TOP 20 largest databases pg-utils/sql/top_databases.sql name | owner | size ----------+----------+--------- the | postgres | 74 GB quick | postgres | 65 GB brown | postgres | 41 GB fox | postgres | 36 GB jumps | postgres | 30 GB over | postgres | 28 GB lazy | postgres | 25 GB dog | postgres | 13 GB
  • 10. 10 TOP 20 largest tables/indexes in selected DB pg-utils/sql/top_tables.sql nspname | relname | type | size | idxsize | total ---------+--------------------------+------+---------+---------+--------- public | posts | r | 20 GB | 24 GB | 43 GB public | users | r | 4152 MB | 3215 MB | 7367 MB public | posts_type_id_created_at | i | 4861 MB | 0 bytes | 4861 MB public | posts_user_id | i | 2612 MB | 0 bytes | 2612 MB
  • 11. 11 Unused indexes github.com/pgexperts/pgx_scripts/indexes/unused_indexes.sql table/index index scans per index table reason | name | scan % | write | size | size ---------------------------+-----------+--------+----------+---------+--------- Never Used Indexes | ... | 0.00 | 0.00 | 18 GB | 78 GB Never Used Indexes | ... | 0.00 | 0.00 | 6371 MB | 64 GB Never Used Indexes | ... | 0.00 | 0.00 | 4875 MB | 64 GB Never Used Indexes | ... | 0.00 | 0.00 | 4412 MB | 64 GB Low Scans, High Writes | ... | 0.00 | 0.00 | 6358 MB | 64 GB Low Scans, High Writes | ... | 0.00 | 0.00 | 6290 MB | 64 GB Seldom Used Large Indexes | ... | 0.24 | 29811.00 | 1171 MB | 8726 MB Seldom Used Large Indexes | ... | 0.00 | 3.00 | 1121 MB | 8726 MB
  • 12. 12 Duplicate indexes github.com/pgexperts/pgx_scripts/indexes/duplicate_indexes_fuzzy.sql table index index name | name | cols | indexdef | index_scans -------+-----------+-------+-------------------------------------+------------- users | users_a | a | CREATE INDEX ... USING btree (a) | 10140 users | users_a_b | a,b | CREATE INDEX ... USING btree (a, b) | 2194900
  • 13. 13 Compact indexes Иногда можно создать более компактный индекс • Partial indexes • gin indexes (btree_gin) for duplicates • BRIN indexes
  • 14. 14 Bloat • multiversion concurrency control (MVCC) • При каждом update строки создается ее копия • Ненужные копии подчищаются процессом autovacuum • autovacuum не может уменьшить размер таблицы, если только нет пустых страниц в конце файла
  • 15. 15 Bloat create table test(id integer primary key, flag boolean not null); insert into test values(1, false); select to_hex(xmin::text::bigint) as xmin, * from test; xmin | id | flag ------+----+------ 3ec | 1 | f
  • 16. 16 Bloat update test set flag = true where id = 1; select to_hex(xmin::text::bigint) as xmin, * from test; xmin | id | flag ------+----+------ 3ed | 1 | t
  • 17. 17 Where did all you zombies come from? • Long running transactions • Not tuned autovacuum • Update large number of rows • Delete large number of rows • Drop columns
  • 18. 18 Long running transactions Как бороться? • Мониторинг длины самой долгой транзакции (на репликах с hot_standby_feedback = on тоже!) • Автоматически прибивать по крону (см. pg_terminate_backend(), pg_stat_activity) • Модифицировать приложение • pg_dump ⇒ pg_basebackup
  • 19. 19 autovacuum • autovacuum_vacuum_scale_factor по-умолчанию 0.2 (20% таблицы) • autovacuum_max_workers • autovacuum_vacuum_cost_delay
  • 20. 20 Bloat estimation Оценка bloat на основе данных статистики с разной степенью достоверности • heroku pg:bloat github.com/heroku/heroku-pg-extras • check_postgres.pl bucardo.org/check_postgres/check_postgres.pl.html • github.com/ioguix/pgsql-bloat-estimation • pgstattuple extension
  • 21. 21 Table bloat pg-utils/sql/table_bloat.sql table total total toast waste table waste total nspname | relname | size | size | percent | waste | percent | waste ---------+-----------+---------+---------+---------+--------+---------+-------- public | obscure | 22 GB | 0 bytes | 72.9 | 16 GB | 72.9 | 16 GB public | problems | 4814 MB | 0 bytes | 11.6 | 558 MB | 11.6 | 558 MB public | may | 3428 MB | 8192 by | 2.0 | 68 MB | 2.0 | 68 MB public | require | 103 MB | 0 bytes | 49.1 | 51 MB | 49.1 | 51 MB public | unusual | 279 MB | 11 MB | 8.8 | 24 MB | 10.4 | 29 MB public | solutions | 59 MB | 0 bytes | 41.3 | 24 MB | 41.3 | 24 MB
  • 22. 22 Index bloat pg-utils/sql/index_bloat.sql (btree indexes only) table table index index index waste schema | name | size | name | size | scans | percent | waste --------+-------+---------+------------+---------+---------+---------+--------- public | alfa | 7046 MB | alfa_unifo | 6226 MB | 273454 | 80.0 | 5041 MB public | alfa | 7046 MB | alfa_romeo | 4630 MB | 324259 | 69.0 | 3226 MB public | bravo | 11 GB | bravo_hote | 6197 MB | 3562344 | 13.0 | 808 MB public | alfa | 7046 MB | alfa_lima | 2154 MB | 6140 | 35.0 | 754 MB public | delta | 13 GB | delta_echo | 1500 MB | 3045468 | 40.0 | 613 MB public | alfa | 7046 MB | alfa_charl | 1850 MB | 2699598 | 24.0 | 454 MB public | delta | 5421 MB | delta_foxt | 1780 MB | 12774 | 18.0 | 329 MB
  • 23. 23 VACUUM FULL/CLUSTER • exclusive lock • requires additional space • could be optimal for small tables
  • 24. 24 create new empty table and swap with existing • подходит для insert-only таблиц (логи) • быстро
  • 25. 25 pg_repack • позволяет сделать cluster таблицы • требует дополнительное место под копию таблицы • модифицирует системные каталоги
  • 26. 26 pgcompact/pgcompacttable • не требует места под копию таблицы • можно регулировать нагрузку на диски • работает на уровне приложения
  • 27. 27 pgcompact/pgcompacttable как работает? • initial vacuum table • определение bloat таблиц/индексов • fake updates: update only xxx set a=a where ctid = ANY(?) • vacuum table • reindex concurrently
  • 28. 28 pgcompacttable проблемы • возможное неиспользование индексов на реплике с pgbouncer 1 • не делается analyze после пересоздания функциональных индексов • нет таймаута на alter index xxx rename to yyy • можно сгенерировать значительное количество WAL • не сжимает toast’ы 1 http://bit.ly/28YR0F0 Relation cache invalidation on replica
  • 30. 30 TOAST • хранение длинных (2kb+) значений • разбивает на chunk’и по 2кб и хранит в специальной таблице в схеме pg_toast • может сжимать данные алгоритмом LZ • toast таблицы нельзя модифицировать
  • 31. 31 TOAST #create table test_toast (id serial primary key, payload text); #insert into test_toast (payload) select string_agg(md5(j::text),’’) from generate_series(1,1000) gs(j); INSERT 0 1 # select reltoastrelid::regclass from pg_class where relname = ’test_toast’; pg_toast.pg_toast_216572 # d+ pg_toast.pg_toast_216572 TOAST table "pg_toast.pg_toast_216572" Column | Type | Storage ------------+---------+--------- chunk_id | oid | plain chunk_seq | integer | plain chunk_data | bytea | plain
  • 32. 32 TOAST cleanup ? update products set description = description || ’’ where id >= ... and id < ...; vacuum products;
  • 33. 33 Tuples storage • 23 bytes tuple header • 1 byte padding or null bitmask • total tuple size is multiple of MAXALIGN (8 bytes on x64)
  • 34. 34 Paddings Какая таблица меньше? test_paddings ( id integer, is_active bool, created_at timestamp, is_removed bool, updated_at timestamp ); test_paddings2 ( id integer, created_at timestamp, updated_at timestamp, is_active bool, is_removed bool ); test_paddings3 ( id integer, is_active bool, is_removed bool, created_at timestamp, updated_at timestamp ); insert into test_paddings* ... INSERT 0 100000
  • 35. 35 Paddings Какая таблица меньше? test_paddings ( id integer, is_active bool, created_at timestamp, is_removed bool, updated_at timestamp ); 5912 kB test_paddings2 ( id integer, created_at timestamp, updated_at timestamp, is_active bool, is_removed bool ); 5912 kB test_paddings3 ( id integer, is_active bool, is_removed bool, created_at timestamp, updated_at timestamp ); 5120 kB
  • 37. 37 Paddings select ... from pg_type where typname in (...) order by typlen; typname | typlen | typalign -----------+--------+---------- json | -1 | 4 jsonb | -1 | 4 numeric | -1 | 4 varchar | -1 | 4 text | -1 | 4 bool | 1 | 1 int2 | 2 | 2 int4 | 4 | 4 date | 4 | 4 float8 | 8 | 8 timestamp | 8 | 8 int8 | 8 | 8
  • 38. 38 Empty values name | pg_column_size ------------+---------------- null | 02 ’’::text | 4 ’{}’::json | 6 ’{}’::jsonb | 8 ’{}’::int[] | 16 2 when less than 8 nullable fields in a row
  • 39. 39 Emergency? Monitoring! • check long running transactions • wal_keep_segments, checkpoint_segments (max_wal_size) • reserved space • remove/compress logs • check biggest tables/indexes • move to another tablespace
  • 40. 40 Not an emergency? • Знаем размеры типов, tuple header, paddings • Удаляем/архивируем ненужное (таблицы, индексы) • Боремся с bloat • Следим за местом • Планируем обновление дисков заранее
  • 41. 41 Useful links • PostgreSQL Manual 63.1. Database File Layout • Different Approaches for MVCC used in well known Databases • PostgreSQL Manual 63.2. TOAST • github.com/pgexperts/pgx_scripts • github.com/reorg/pg_repack • github.com/grayhemp/pgtoolkit • github.com/PostgreSQL-Consulting/pgcompacttable • github.com/PostgreSQL-Consulting/pg-utils • www.slideshare.net/alexius2/