PostgreSQL 14 GA: обновляем первый production-кластер и меряем LZ4-сжатие на toast
PostgreSQL 14 вышел GA. Обновляем первый production DWH до PG14, включаем LZ4 на toast-таблицах event-логов и документируем zero-downtime upgrade через pg_upgrade.
PostgreSQL 14 выходит GA (14 октября 2021) с улучшенным vacuum, LZ4/Zstandard сжатием и расширенным JSON SQL
PostgreSQL 14 вышел GA. Мы ждали именно этого момента - не RC, не бету, а первый production-пригодный тег. У нас уже был готов стенд с клиентской схемой и понимание чего ждать: бенчмарки на RC показали реальный прирост на партиционированных DWH-запросах. Теперь двигаем первый боевой кластер.
Что именно в 14-й версии нас интересует
Из анонса несколько вещей, которые реально влияют на нашу DWH-инфраструктуру:
Новые алгоритмы сжатия TOAST. PostgreSQL 14 добавляет поддержку LZ4 и Zstandard в дополнение к стандартному pglz. Алгоритм задаётся на уровне столбца через SET STORAGE или через параметр default_toast_compression. LZ4 интересен прежде всего скоростью распаковки - существенно быстрее pglz при сопоставимой или лучшей степени сжатия на типичных данных.
Улучшения vacuum. vacuum_failsafe_age - новый порог, при достижении которого autovacuum форсирует прогон, игнорируя прочие настройки, чтобы не допустить wraparound. Менее заметно снаружи, но важно для долгоживущих кластеров с высоким transaction rate.
JSON/SQL расширения. Предикат IS JSON, новые флаги в jsonb_path_*-функциях, расширенная обработка ошибок в SQL/JSON Path - PostgreSQL 14 продолжает движение к стандарту SQL/JSON, хотя до полного набора конструкций (JSON_TABLE и т.п.) ещё далеко. Мы это смотрели ещё на бете, для нашего основного клиента актуальность пока умеренная, но для схем с полудокументными данными - направление понятно.
Производительность logical replication и pipeline mode в libpq - тоже в списке, хотя на нашем конкретном кластере это второй приоритет.
Кластер, который обновляем первым
Выбрали не самый критичный, но и не тестовый - промежуточный вариант: DWH-кластер с event-логами одного из клиентов. Объём базы около 400 ГБ, нагрузка - преимущественно аналитические запросы, запись идёт батчами раз в несколько минут через ETL. Это разумный кандидат для первого GA-апгрейда: если что-то пойдёт не так, есть несколько часов на откат без катастрофических последствий.
Особенность схемы: несколько крупных таблиц с jsonb-столбцами, куда складываются сырые event-payload'ы. На них TOAST работает активно, и именно здесь LZ4 должен дать заметный эффект.
Zero-downtime upgrade: наша процедура
«Zero-downtime» в нашем контексте - это «без остановки записывающих ETL-процессов больше чем на 5 минут». Полного zero в смысле незаметного для клиентского приложения тут нет - pg_upgrade требует остановки кластера.
Процедура, которую мы задокументировали и прогнали:
Подготовка. Убеждаемся что на новом хосте (или в новом data directory) стоит PG14, прогоняем pg_upgrade --check без реальной миграции - это проверяет совместимость без изменения данных. Исправляем что нашлось (у нас - расширение с бинарным форматом, пришлось пересобрать под PG14).
Снепшот. Делаем слепок volume на уровне хранилища непосредственно перед апгрейдом. Это наш реальный откат, а не просто pg_dump.
Остановка записи. Останавливаем ETL-джобы, ждём завершения активных транзакций, проверяем через pg_stat_activity что активных соединений с записью нет.
pg_upgrade --link. Флаг --link вместо копирования файлов - за счёт hardlink'ов процедура на 400 ГБ занимает минуты, а не часы. Обратная сторона: после --link исходный кластер PG13 нельзя просто поднять - данные уже переиспользованы. Поэтому снепшот обязателен.
Старт PG14, базовая проверка. Несколько контрольных запросов, COUNT(*) по ключевым таблицам, проверка индексов.
Включение ETL. Общее downtime кластера - около 7 минут для этого объёма.
После апгрейда: ANALYZE на всей базе (статистика не переносится из PG13), запуск vacuumdb --analyze-in-stages для постепенного прогрева статистики без блокировки аналитических запросов.
LZ4 на toast: что получили
Это та часть, ради которой всё и затевалось. После апгрейда включаем LZ4 на столбцах с jsonb-payload:
ALTER TABLE raw_events
ALTER COLUMN payload SET (compression = lz4);
Важно понимать: существующие строки не перепаковываются автоматически. LZ4 применится к новым вставкам. Старые данные остаются с pglz. Чтобы перепаковать историю - нужен VACUUM FULL или пересоздание таблицы, что для 400 ГБ не вариант без maintenance window.
Смотрим на прирост постепенно, по мере накопления новых данных. После недели новых вставок под LZ4 размер toast-таблицы для нового периода примерно на 35% меньше аналогичного периода под pglz. Это не финальная цифра по всей базе - итоговое уменьшение будет пропорционально доле перезаписанных данных. Но направление понятно.
По скорости: чтение payload-столбцов в аналитических запросах с EXPLAIN (ANALYZE, BUFFERS) показывает снижение времени на декомпрессии. LZ4 на CPU заметно дешевле - это ощущается на запросах, которые поднимают много toast-данных.
Autovacuum: первые наблюдения
За неделю после апгрейда смотрим pg_stat_user_tables на bloat в staging-области. Пока autovacuum справляется лучше чем на PG13 при той же нагрузке - таблицы чище, прогоны короче. Новый vacuum_failsafe_age не сработал ни разу (хорошо - значит до критической отметки далеко), но само наличие этого механизма снижает тревогу за wraparound на долго работающих кластерах.
Что дальше
Первый кластер прошёл без сюрпризов. Процедуру задокументировали, теперь она у нас как runbook - следующий апгрейд будет быстрее. Второй по очереди кластер - основной OLTP-источник для DWH, там схема сложнее и расширений больше, там будем аккуратнее.
LZ4 на новых вставках работает, смотрим дальше. Когда накопится достаточно данных под новым алгоритмом - сделаем более полный срез по размеру и производительности.
Про DWH-проекты и аналитическую инфраструктуру - там вся контекстная информация.