После обновления системы на Arch Linux столкнулся с проблемой запуска PostgreSQL. Сервер не стартовал из-за несовместимости формата базы данных. В этой статье напишу, что делал и как решилось. Админам баз данных (DBA), вряд ли будет полезно, но тем кто неожиданно впоролся может и помочь решить проблему миграции данных с PostgreSQL 16 на PostgreSQL 17.
После обновления системы и PostgreSQL, сервер не запускался:
```bash
$ sudo systemctl status postgresql
× postgresql.service - PostgreSQL database server
Active: failed (Result: exit-code)
...
мая 29 18:16:08 turbo postgres[753]: An old version of the database format was found.
мая 29 18:16:08 turbo postgres[753]: See https://wiki.archlinux.org/index.php/PostgreSQL#Upgrading_Po...
```
Первая мысль была откатить пока базу данных на старую версию и потом искать решение, так как в кэше пакмана(пакетный менеджер ArchLinux) остаются пакеты из прошлых обновлений. Именно на такие случаи не удаляю их из кэша. Установил предыдущую версию postgesql и получил ошибку при его старте - оказалось новая версия libxml2 не работает со старым pg16. Тогда подумалось откатить и его, но от этого пакета зависит пакет для работы с архивами и если я его откачу, и система перестанет распаковывать архивы, то ситуация рискует стать похуже до такой степени, что не будет работать даже пакман.
Тогда заглянул в AUR и там оказался пакет postgresql16, которым можно попытаться собрать pg16 из исходников под текущую систему, но... короче не собралось. Насел на Сlaude 3.5 Haiku(у меня оставалось еще 50 бесплатных запросов в курсоре и если использовать haiku то получается в 3 раза больше) - пытались с ним и так и сяк починить сборку используя разные ключи компиляции и компиляторы, но не помогло.
Ну пишу ему "спасай тогда, чё". Выдает 3 способа как решить исходную проблему неработы БД:
Все сводятся к миграции данных с pg16 на pg17. Для этого нужны бинарники от pg16 - иначе никак:
1. Запустить в докере через образ archlinux-base. Есть специальный пакет именно для миграции. Попробовал, но в том образе докера этот пакет поддерживал только миграцию с pg15 на pg16.
2. Взять образ докера postgres17, скачать туда бинарники pg16 и выполнить миграцию. Не нашел архив с нужными бинарниками (хотя можно было взять из кэша, но не догадался в тот момент)
3. Использовать архивы пакетов прошлых версий, включая зависимые библиотеки, подключить их через LD_LIBRARY_PATH и запустить миграцию данных в текущей системе - это сработало! Напишу подробнее как именно.
Решение
Сначала надо сделать резервную копию базы данных:
cp /var/lib/postgres/data /var/lib/postgres/data.bak
2. Подготовка окружения для миграции
Вернулся к последней версии PosgreSQL чтобы она была в системе основной, при этом нужно временно использовать старые бинарники и библиотеки. Распаковал старые пакеты из кэша pacman:
# Создаем директории для распаковки
sudo mkdir -p /tmp/postgres-migration/{libxml2,icu,postgresql}
# Распаковываем необходимые пакеты
sudo tar -xvf /var/cache/pacman/pkg/libxml2-2.13.1-1-x86_64.pkg.tar.zst -C /tmp/postgres-migration/libxml2
sudo tar -xvf /var/cache/pacman/pkg/icu-75.<версия>.pkg.tar.zst -C /tmp/postgres-migration/icu
sudo tar -xvf /var/cache/pacman/pkg/postgresql-16.3-4-x86_64.pkg.tar.zst -C /tmp/postgres-migration/postgresql
3. Инициализация нового кластера
# Создаем новый каталог для базы данных
sudo mkdir -p /var/lib/postgres/data.new
sudo chown postgres:postgres /var/lib/postgres/data.new
# Инициализируем новый кластер
sudo -iu postgres
initdb -D /var/lib/postgres/data.new
# Запускаем pg_upgrade с указанием путей к старым библиотекам
LD_LIBRARY_PATH=/tmp/postgres-migration/libxml2/usr/lib/:/tmp/postgres-migration/icu/usr/lib/ \
pg_upgrade \
-d /var/lib/postgres/data \
-D /var/lib/postgres/data.new \
-b /tmp/postgres-migration/postgresql/usr/bin/ \
-B /usr/bin/
# Останавливаем PostgreSQL
sudo systemctl stop postgresql
# Заменяем старый кластер новым
sudo rm -rf /var/lib/postgres/data
sudo mv /var/lib/postgres/data.new /var/lib/postgres/data
sudo chown -R postgres:postgres /var/lib/postgres/data
sudo chmod 700 /var/lib/postgres/data
# Перезагружаем systemd и запускаем PostgreSQL
sudo systemctl daemon-reload
sudo systemctl start postgresql
После миграции, приложение использующее базу данных дает предупреждение о несовпадении версий правил сортировки:
ПРЕДУПРЕЖДЕНИЕ: несовпадение версии для правила сортировки в базе данных "kreagenium"
DETAIL: База данных была создана с версией правила сортировки 2.39, но операционная система предоставляет версию 2.41.
Решил проблему обновлением коллаций:
ALTER DATABASE kreagenium REFRESH COLLATION VERSION;
Важные моменты
1. Резервное копирование — всегда делайте полный дамп базы данных перед миграцией
2. Права доступа — следите за правильными правами на каталоги и файлы
3. Версии библиотек — убедитесь, что все необходимые библиотеки доступны
4. Коллации — после миграции может потребоваться обновление правил сортировки
Заключение
Миграция PostgreSQL на Arch Linux требует внимательного подхода к версиям библиотек. Использование временных каталогов для старых версий библиотек и бинарников позволяет безопасно выполнить миграцию без необходимости отката системных пакетов.
Полезные ссылки