Использование дискового пространства в кластере PostgreSQL
На дисках кластера PostgreSQL хранятся:
- временные файлы;
- файлы данных;
- журналы транзакций (WAL);
- слоты логической репликации;
- логи СУБД;
- системные файлы, необходимые для функционирования PostgreSQL.
Вы можете отслеживать заполненность диска с помощью метрик. Подробнее о метриках в инструкции Мониторинг кластера, нод и баз данных PostgreSQL.
Когда объем используемого дискового пространства растет, вы можете проверить:
Если диск кластера будет заполнен на 80%, уведомление появится в панели управления и будет отправлено на электронную почту Владельца аккаунта и тех пользователей, которые подписаны на категорию уведомлений «Услуги и сервисы».
Если диск кластера будет заполнен на 95% и более, кластер перейдет в статус DISK_FULL и будет работать только на чтение.
Чтобы кластер работал на чтение и запись, очистите диск или масштабируйте кластер и выберите конфигурацию с бóльшим размером диска.
Посмотреть размер временных файлов
Временные файлы могут использоваться для сортировки, хеширования и временного хранения результатов запросов.
Чтобы посмотреть общий размер временных файлов в базе данных, используйте SQL-запрос к представлению pg_stat_database:
SELECT datname, temp_files AS "Temporary files", temp_bytes AS "Size of temporary files"
FROM pg_stat_database;
Пример вывода:
datname | temp_files | temp_bytes
--------+--------------+----------------
mydb | 2 | 16384
postgres| 1 | 8192
Здесь:
datname— имя базы данных;temp_files— количество временных файлов в этой базе данных;temp_bytes— размер временных файлов в байтах.
В полях temp_files и temp_bytes учитываются все временные файлы с момента создания кластера.
Данные сбрасываются только после восстановления из бэкапа или после аварийного завершения работы.
Используйте значения этих полей, чтобы следить за изменением общего размера временных файлов.
Размер временных таблиц, создаваемых конкретным запросом, можно получить с помощью команды EXPLAIN ANALYZE.
Проверить потребителей слотов логической репликации
Слоты логической репликации используются для постоянной репликации данных из одной базы в другую. У слотов логической репликации всегда должен быть потребитель. Если потребителя нет, то размер файлов будет расти.
Подробнее об управлении слотами логической репликации в статье Subscription документации PostgreSQL.
Чтобы проверить, есть ли у слотов логической репликации потребители, отправьте SQL-запрос к представлению pg_replication_slots:
SELECT slot_name, pg_size_pretty(pg_wal_lsn_diff(pg_current_wal_lsn(),restart_lsn)) AS replicationSlotLag,active
FROM pg_replication_slots;
Пример вывода:
slot_name | replicationslotlag | active
-----------------+--------------------+--------
myslot1 | 129 GB | f
myslot2 | 704 MB | t
myslot3 | 624 MB | t
Здесь:
slot_name— имя слота логической репликации;replicationslotlag— размер WAL-файлов, которые не будут автоматически удаляться при контрольных точках и которые потребители слота логической репликации могут использовать;active— булево значение показывает, используется ли слот логической репликации:f— у слота нет потребителя;t— у слота есть потребитель.
Если у вас версия PostgreSQL 13 и выше, вы можете о граничить максимальный размер хранимых WAL-файлов с помощью параметра max_slot_wal_keep_size. Учтите, что при использовании этого параметра журнал транзакций может быть удален раньше, чем потребитель прочитает изменения из слота логической репликации.
«Мертвые» кортежи
Когда вы обновляете строки в таблице (UPDATE) или удаляете их (DELETE), кортежи фактически не удаляются с диска, а создаются их новые версии.
Старые версии кортежей будут называться «мертвыми» (dead tuples).
Такое версионирование необходимо для реализации процесса MVCC (Multi-Version Concurrency Control).
Несмотря на то, что строки изменены в одной транзакции, другие активные транзакции могут продолжать видеть старую версию строк.
«Мертвые» кортежи могут быть удалены, только когда все активные транзакции будут закрыты.
«Мертвые» кортежи также будут образовываться на реплике, если вы используете логическую репликацию.
Проверить «мертвые» кортежи
Если «мертвых» кортежей много, то они могут занимать значительный объем дискового пространства.
Чтобы проверить количество «мертвых» кортежей, можно использовать расширение PostgreSQL pgstattuple или представление pg_stat_all_tables.
Пример SQL-запроса к представлению pg_stat_all_tables:
SELECT * FROM pg_stat_all_tables WHERE relname='test';
Пример вывода:
-[ RECORD 1 ]----------+------------------------------
relid | 16395
schemaname | public
relname | test
seq_scan | 3
seq_tup_read | 5280041
idx_scan |
idx_tup_fetch |
n_tup_ins | 2000000
n_tup_upd | 0
n_tup_del | 3639911
n_tup_hot_upd | 0
n_live_tup | 1635941
n_dead_tup | 1999952
n_mod_since_analyze | 3999952
last_vacuum |
last_autovacuum | 2023-02-16 04:49:52.399546+00
last_analyze | 2023-02-09 09:44:56.208889+00
last_autoanalyze | 2023-02-16 04:50:22.581935+00
vacuum_count | 0
autovacuum_count | 1
analyze_count | 1
autoanalyze_count | 1
Здесь n_dead_tup — количество «мертвых» кортежей.
Сравнение способов удаления «мертвых» кортежей
Чтобы удалить «мертвые» кортежи, вы можете использовать стандартные команды VACUUM, VACUUM FULL или перепаковать таблицы и индексы с помощью расширения pg_repack.
Подробнее о командах VACUUM и VACUUM FULL в статье Routine Vacuuming документации PostgreSQL.
Подробнее о расширении pg_repack и его функциях в документации pg_repack.
Перепаковать таблицы и индексы с помощью pg_repack
Запускайте pg_repack в периоды минимальной нагрузки на кластер, так как pg_repack создает дополнительную нагрузку.
Подробнее об отслеживании состояния кластера в инструкции Мониторинг кластера, нод и баз данных PostgreSQL.
Для работы с расширением pg_repack используется одноименный клиент.
Клиент устанавливается на хост, с которого вы подключаетесь к кластеру PostgreSQL.
-
Добавьте расширение
pg_repackв базу данных. -
Определите версию расширения
pg_repack:2.1. Подключитесь к кластеру. При подключении укажите имя базы данных, в которую добавили расширение
pg_repack.2.2. Определите версию расширения:
SELECT
extname AS extension,
extversion AS version,
extnamespace::regnamespace AS schema
FROM pg_extension
WHERE extname = 'pg_repack'; -
Скачайте и установите клиент pg_repack той же версии, что и расширение.
-
Убедитесь, что на диске достаточно свободного места. Для полной перепаковки таблиц требуется свободное дисковое пространство, примерно вдвое превышающее размер обрабатываемых таблиц и индексов. Например, если общий размер обрабатываемых таблиц и индексов составляет 1 ГБ, потребуется дополнительно 2 ГБ дискового пространства.
-
Убедитесь, что в обрабатываемой таблице есть первичный ключ (
PRIMARY KEY) или уникальный индекс (UNIQUE INDEX). -
Перепакуйте таблицы и индексы в базе данных:
pg_repack -k -h <host> -p <port> \
-U <user> \
-d <database_name> \
-t <table_name> \
-i <index_name>Укажите:
<host>— DNS-адрес ноды;<port>— порт для подключения;<user>— имя пользователя базы данных;<database_name>— имя базы данных;- опционально:
-t <table_name>, где<table_name>— имя таблицы. Используйте этот параметр, если нужно перепаковать отдельную таблицу. Чтобы перепаковать несколько таблиц, укажите нужное количество параметров-t