# PostgreSQL с 10-й версии на 17-ю за одно окно
## Что было
SaaS-платформа документооборота: два публичных фронта, около двадцати пяти микросервисов, кластер Kubernetes старше четырёх лет. Под всем этим — PostgreSQL десятой версии, снятой с поддержки несколько лет назад.
Ситуация обычная для системы, которая выросла из стартапа: база работает, трогать страшно, а список причин перестать откладывать копится:
- версия давно без обновлений безопасности;
- новые возможности планировщика и мониторинга недоступны;
- инструменты вокруг базы постепенно перестают поддерживать старую ветку;
- разница между десятой и семнадцатой версиями — семь мажорных выпусков, то есть накопленные несовместимости в правах, ролях и умолчаниях.
Требование бизнеса: простой не дольше трёх часов, ночью, с гарантией возврата назад, если что-то пойдёт не так.
## Как делали
**Метод — логическая репликация.** Новый сервер поднимается рядом на семнадцатой версии, данные едут на него заранее и держатся в актуальном состоянии. В окно остаётся только догнать последние изменения и переключить приложения на новый адрес. Обновление на месте отпадало сразу: оно требует остановки на всё время конвертации и не оставляет пути назад.
**Сверка структуры до окна.** Пересчитали и сравнили таблицы, колонки, ограничения, счётчики идентификаторов, права и роли. Разница между версиями вылезает именно здесь: то, что в десятой было умолчанием, в семнадцатой требует явной выдачи прав.
**Репетиция на тестовом контуре.** Прогнали окно целиком, по командам, как в бою. Репетиция вскрыла три ошибки в готовых командах, каждая из которых сорвала бы работы: не срабатывал разрыв пользовательских соединений, команда остановки сервисов не работала в оболочке инженера, а критерий готовности приложений давал ложное «готово». Все три исправлены и перепроверены до боевого окна.
**Заранее написанные команды.** К окну готовится файл, где каждый шаг — готовая строка с проверкой результата. В три часа ночи никто ничего не сочиняет и не вспоминает синтаксис.
**Точка принятия решения.** Перед самим переключением — формальная проверка «идём или не идём»: лаг подписки, состояние копий, готовность отката. Не сошлось — расходимся и переносим, потери минимальные.

## Результат
| Что | Итог |
|---|---|
| Окно работ | **1 час 47 минут** при заявленных бизнесу трёх часах |
| Данные | перенесены полностью, подписчик дошёл до финальной LSN |
| Структура | 199 таблиц, 1 593 колонки, 189 счётчиков, 409 ограничений — сошлось до единицы |
| Счётчики идентификаторов | 168 расхождений найдено и исправлено до открытия |
| Сервисы | все 16 подняты в штатном числе копий |
| Проверка действием | чтение и запись боевых данных прошли до открытия входа |
| Ошибки в журнале после открытия | ноль за четыре часа наблюдения |
| Откат | не потребовался |
Три сбоя в окне всё-таки случились: подвисшие приложения на одном узле, отказ того же узла запускать новые копии и заглушка технических работ, мешавшая внутренним вызовам при приёмке. Все три разобраны на месте и уложились в окно — именно на такие случаи в плане и закладывается запас.
## Что было после
Работы не заканчиваются переключением. Дальше — пересборка резервной реплики уже на новой версии, первая полная копия новой базы, настройка сбора метрик под новый сервер и наблюдение за первыми сутками.
## Что забрал заказчик
Базу, которая снова получает обновления безопасности, и описанную процедуру: как готовились, как переключали, что проверяли и по каким признакам решали, что можно открывать пользователей. Следующее такое обновление будет уже не приключением, а рутиной по инструкции. btop
No problems have been detected in the workspace.
No forwarded ports. Forward a port to access your locally running services over the internet.