Как бы ты обновлял версию PostgreSQL в production?

«Как бы ты обновлял версию PostgreSQL в production?» — вопрос из категории Базы данных, который задают на 23% собеседований Devops Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Для обновления PostgreSQL с минимальным простоем я использую логическую репликацию. Это позволяет создать новый кластер на целевой версии и синхронизировать данные в реальном времени.

Основные шаги:

  1. Подготовка: Устанавливаю новую версию PostgreSQL на отдельном сервере или инстансе.
  2. Настройка публикации: На исходном сервере (мастере) настраиваю логическую репликацию, создавая публикацию для нужных таблиц или всей БД.
    -- На мастере (старая версия)
    CREATE PUBLICATION myapp_pub FOR ALL TABLES;
  3. Настройка подписки: На целевом сервере (новая версия) создаю подписку, указывая соединение с мастером.
    -- На реплике (новая версия)
    CREATE SUBSCRIPTION myapp_sub
    CONNECTION 'host=master_host port=5432 dbname=mydb'
    PUBLICATION myapp_pub;
  4. Синхронизация и проверка: После полной синхронизации данных проверяю целостность и корректность работы приложения на тестовой нагрузке, направляя часть трафика на новую версию.
  5. Переключение: В запланированное окно останавливаю приложение, дожидаюсь полной синхронизации, меняю строки подключения в конфигурации приложения и переключаю трафик на новый кластер.
  6. Откат: Старый кластер оставляю работающим на короткое время как горячую резервную копию на случай быстрого отката.

Ключевые моменты:

  • Тестирование: Всегда тестирую процедуру обновления и отката на staging-окружении, идентичном production.
  • Резервная копия: Перед началом обязательно создаю полный физический бэкап с помощью pg_basebackup.
  • Даунтайм: Финальное переключение связано с кратковременным даунтаймом (минуты), но основная синхронизация данных происходит онлайн.
  • Для Docker/K8s: В контейнеризованной среде разворачиваю новый StatefulSet с образом новой версии, настраиваю репликацию между подами, а затем обновляю сервис, указывающий на новый набор подов.