PostgreSQL
Обновление PostgreSQL
PostgreSQL 12 (2019) -> PostgreSQL 16 (2023). Между ними: pg14 с WAL compression, pg15 с row-level security improvements, pg16 с logical replication from standby и параллельными запросами для многих операций. Каждый major release - значительные улучшения. Но 40% компаний работают на EOL версиях PostgreSQL. Страх апгрейда. Знание паттернов upgrade убирает страх.
- **Zalando** - 500+ PostgreSQL кластеров, все на актуальных major версиях. Patroni + logical replication upgrade: < 30 секунд downtime на кластер, автоматизировано через Ansible
- **AWS RDS** - blue-green upgrade как managed service: один клик создаёт Green из Blue, репликация настраивается автоматически, cutover по команде
- **Supabase** - logical replication upgrade для tenant databases: zero-downtime для клиентов при переходе на новую PostgreSQL major версию
pg_upgrade: быстрое обновление major версии
**pg_upgrade** обновляет PostgreSQL major версию in-place. Вместо dump+restore (часы/дни) - pg_upgrade переиспользует файлы данных, обновляя только системные каталоги. С флагом `--link` (hardlinks) - практически мгновенно. Требует downtime: 5-30 минут для большинства баз.
**--link** использует hardlinks: pg15 файлы стали pg16. Если что-то пошло не так после запуска pg16 - нельзя просто вернуться к pg15 (файлы уже изменены pg16). Всегда делать pg_basebackup перед upgrade для rollback возможности.
pg_upgrade с --link выполнен. PostgreSQL 16 запущен. Обнаружена проблема совместимости приложения. Как выполнить rollback к PostgreSQL 15?
Zero-Downtime Upgrade через Logical Replication
**Logical replication upgrade** - zero-downtime обновление major версии. Запустить новый pg16 сервер, подписать на publikation pg15, дождаться синхронизации, переключить трафик. Downtime: 10-60 секунд для переключения DNS/соединений.
**DDL синхронизация** - главная сложность logical replication upgrade. Нужно применить все CREATE TABLE, ALTER TABLE, CREATE INDEX на pg16 до создания subscription. Использовать pg_dump --schema-only pg15 | psql pg16 для начального состояния схемы.
Logical replication upgrade pg15→pg16. pg16 подписан на pg15. Разработчик добавляет новый столбец на pg15 в production. Что происходит с репликацией?
Blue-Green Deployment для PostgreSQL
**Blue-Green deployment** - держать два окружения (blue = production, green = новое). Переключение трафика через DNS или load balancer. Для PostgreSQL: green реплицируется из blue через logical replication, при переключении - traffic cutover + subscription promotion.
**Zalando использует этот паттерн** для обновления 500+ PostgreSQL кластеров. Patroni + logical replication: green поднимается рядом, репликация настраивается, Patroni делает automatic failover при переключении. Downtime < 30 секунд на каждый кластер.
Green (PG16) запущен, logical replication настроена. Lag = 0. Что нужно сделать ДО переключения трафика?
Тестирование совместимости
**Тестирование перед major upgrade** - обязательный этап. PostgreSQL major версии могут менять: порядок оптимизаций планировщика (запросы меняют планы), синтаксис deprecated функций, поведение при граничных случаях. Тестирование на staging с production-данными обнаруживает 95% проблем.
**Collation changes** - тихая проблема major upgrade. PostgreSQL 15 изменил ICU library - некоторые индексы стали невалидны. После upgrade с изменёнными collation нужен REINDEX. pg_upgrade --check предупредит если обнаружит несовместимые collation.
pg_upgrade --check прошёл успешно. Приложение протестировано на staging с синтетическими данными. Upgrade безопасен?
Rollback Plan: путь назад
**Rollback plan** - обязательная часть любого major upgrade. Нужно знать: как откатиться, за какое время, какие данные потеряются. Без explicit rollback plan upgrade делать нельзя. Три уровня rollback: pg_basebackup recovery, держать Blue alive, PITR.
pg_upgrade с --link очень быстрый и обратимый - можно сделать и откатить если что-то не так
--link использует hardlinks: pg15 и pg16 делят одни файлы. После запуска pg16 и записи данных - pg15 файлы изменены. Rollback возможен только из заранее сделанного pg_basebackup
Hardlinks - это не копии файлов. Оба каталога данных указывают на одни блоки на диске. pg16 обновляет системные каталоги и пишет новые данные. Блоки изменены. pg15 не сможет корректно прочитать эти изменённые страницы. Всегда делать pg_basebackup перед upgrade с --link
Blue-Green upgrade. Трафик переключён на Green (PG16). Через 2 часа обнаружен баг: один из отчётов возвращает неверные данные (изменился план запроса). Что делать?
Итоги
- **pg_upgrade** - быстрый upgrade с downtime 5-30 мин. --link = hardlinks, мгновенно, но необратимо без бэкапа
- **Logical replication upgrade** - zero-downtime: pg16 подписан на pg15, lag=0, maintenance mode, cutover, promote
- **Blue-Green** = logical replication + держать старый кластер живым для быстрого rollback. Downtime < 60 сек
- **DDL не реплицируется** - применить схему на Green вручную ДО подписки. Изменения схемы во время миграции - синхронизировать вручную
- **Rollback plan обязателен**: pg_basebackup ДО upgrade или Blue-Green с alive old cluster
Связанные темы
Upgrade PostgreSQL использует несколько ключевых механизмов:
- Logical Replication — Основа zero-downtime upgrade: PUBLICATION на старом, SUBSCRIPTION на новом, синхронизация данных без downtime
- Backup и восстановление — pg_basebackup перед upgrade - обязательная точка rollback. PITR как альтернативный rollback путь
- Безопасные миграции — Применение DDL-изменений на новом сервере без downtime - те же принципы: CONCURRENTLY, expand-contract, батчинг
Вопросы для размышления
- Компания на PostgreSQL 13 (EOL в ноябре 2025). БД 2 ТБ. Бизнес не может позволить downtime более 2 минут. Какую стратегию upgrade выбрать и почему? Что является самым рискованным шагом?
- Logical replication upgrade начат. Через 3 дня обнаружено: один сервис делает прямые SQL запросы к pg15 напрямую, минуя приложение. После cutover эти данные потеряются. Как обнаружить такие сервисы ДО cutover?
- pg_upgrade --check выдаёт предупреждение: 'your installation contains databases with unicode text search configuration'. Что это означает и как это исправить до upgrade?