Перейти к содержанию

Миграция PostgreSQL 16 до PostgreSQL 18

⚠️ Перед началом миграции остановите приложение (сервис 1f-core). Миграция требует полной остановки записи в базу данных.

Обзор процесса миграции

Стратегия миграции

Миграция выполняется методом dump-and-restore с параллельной работой обеих версий:

  • PostgreSQL 16 остаётся на порту 5432 (рабочая версия)

  • PostgreSQL 18 устанавливается на порту 5433 (новая версия)

После тестирования порты меняются местами.

Преимущества метода

  • Минимальное время простоя

  • Возможность быстрого отката

  • Параллельное тестирование

  • Безопасность данных

Временные затраты

Размер БД Время дампа Время восстановления Общее время
< 10 GB 5-10 мин 10-15 мин ~30 мин
10-50 GB 15-30 мин 30-60 мин ~2 часа
50-100 GB 30-60 мин 1-2 часа ~3-4 часа
> 100 GB 1-2 часа 3-5 часов ~6-8 часов

Подготовка к миграции

Шаг 1: Проверка текущей версии

Проверка версии PostgreSQL 16:

psql --version

Проверка статуса службы:

sudo systemctl status postgresql@16-main.service

Шаг 2: Резервное копирование конфигураций

Создание директории для бэкапов:

sudo mkdir -p /opt/migration-backup

cd /opt/migration-backup

Копирование конфигураций PostgreSQL 16

sudo cp /etc/postgresql/16/main/postgresql.conf ./postgresql-16.conf.backup

sudo cp /etc/postgresql/16/main/pg_hba.conf ./pg_hba-16.conf.backup

Шаг 3: Резервное копирование директории данных

Определение расположения data_directory:

sudo -u postgres psql -p 5432 -t -c "SHOW data_directory;"

Остановка PostgreSQL 16 перед копированием данных:

sudo systemctl stop postgresql@16-main.service

Копирование всей директории данных PostgreSQL 16 (путь может отличаться, проверьте вывод предыдущей команды):

sudo cp -a /pgdata/16-main /opt/migration-backup/pg16-data-backup

Запуск PostgreSQL 16:

sudo systemctl start postgresql@16-main.service

Проверка, что служба запустилась:

sudo systemctl status postgresql@16-main.service

Установка PostgreSQL 18

Шаг 1: Установка PostgreSQL 18

Выполните установку PostgreSQL 18 согласно документации.

Шаг 2: Инициализация кластера (если требуется)

После установки кластер может не создаться автоматически. В этом случае инициализируйте его вручную:

Проверка существующих кластеров:

pg_lsclusters

Если кластер 18/main отсутствует — создайте его:

sudo pg_createcluster 18 main --start --port=5433

Шаг 3: Изменение порта на 5433 (если кластер создан автоматически)

Если кластер был создан автоматически на порту 5432, измените порт чтобы избежать конфликта с PostgreSQL 16:

sudo vim /etc/postgresql/18/main/postgresql.conf

Найдите и измените параметр port:

port = 5433

Шаг 4: Запуск PostgreSQL 18

sudo systemctl start postgresql@18-main.service

sudo systemctl status postgresql@18-main.service

Создание дампа базы данных

⚠️ Перед созданием дампа необходимо удалить расширения из базы данных (шаги ниже). Выполните DROP EXTENSION до запуска pg_dump.

Шаг 1: Создание директории для дампов

sudo mkdir -p /opt/migration-backup/dumps

cd /opt/migration-backup/dumps

Шаг 2: Проверка версии клиента

Важно: Используйте клиент PostgreSQL 18 для создания дампа!

Проверка версии клиента:

pg_dump --version

Ожидаемый результат: pg_dump (PostgreSQL) 18.x

Если версия клиента 16.x, обновите путь:

export PATH=/usr/lib/postgresql/18/bin:$PATH

pg_dump --version

Шаг 3: Создание дампа базы d10task

pg_dump -h localhost \

       -p 5432 \

       -U dbo \

       -Fc \

       -v \
       --exclude-extension=* \

       -f /opt/migration-backup/dumps/d10task_no_ext.dump

       d10task

Важно: перед созданием дампа необходимо удалить расширения, если они установлены в БД

drop extension tds_fdw cascade;

drop extension http cascade;

drop extension postgres_fdw cascade;

Параметры команды:

-h localhost — хост PostgreSQL 16

-p 5432 — порт PostgreSQL 16

-U dbo — пользователь с правами на базу

-Fc — формат custom (сжатый)

-v — verbose режим (показывать прогресс)

--exclude-extension=* — исключить расширения из дампа

-f — путь к файлу дампа

Шаг 4: Создание дампа базы d10task_file

pg_dump -h localhost \

       -p 5432 \

       -U dbo \

       -Fc \

       -v \
       --exclude-extension=* \

       -f /opt/migration-backup/dumps/d10task_file_no_ext.dump

       d10task_file

Восстановление в PostgreSQL 18

Шаг 1: Создание пользователей

Подключитесь к PostgreSQL 18:

sudo -u postgres psql -p 5433

Создайте пользователей:

CREATE USER dbo WITH SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN PASSWORD 'CHANGE_ME_pass1';

CREATE USER d10taskuser WITH INHERIT LOGIN PASSWORD 'CHANGE_ME_pass2';

CREATE USER migrationsdaemon WITH INHERIT LOGIN PASSWORD 'CHANGE_ME_pass3';

CREATE USER rebus WITH INHERIT LOGIN PASSWORD 'CHANGE_ME_pass4';

CREATE USER implementer WITH INHERIT LOGIN PASSWORD 'CHANGE_ME_pass5';

-- Роль для SMART тестирования

CREATE ROLE role_D10TaskReader WITH INHERIT;

CREATE USER D10TaskReader WITH INHERIT LOGIN PASSWORD 'CHANGE_ME_pass6';

GRANT role_D10TaskReader TO D10TaskReader;

ALTER USER D10TaskReader SET search_path = "dbo", "public";

\q

Важно: используйте те же пароли, что и в PostgreSQL 16.

Шаг 2: Создание базы данных d10task

sudo -u postgres psql -p 5433
CREATE DATABASE d10task

   TEMPLATE template0

   OWNER dbo

   ENCODING 'utf8'

   LC_COLLATE 'ru_RU.utf8'

   LC_CTYPE 'ru_RU.utf8';

\q

Шаг 3: Активация расширений в d10task

sudo -u postgres psql -p 5433 -d d10task
-- Загрузка pg_hint_plan

LOAD 'pg_hint_plan';

-- Создание расширений

CREATE EXTENSION IF NOT EXISTS plpgsql SCHEMA pg_catalog;

CREATE EXTENSION IF NOT EXISTS rum SCHEMA public;

CREATE EXTENSION IF NOT EXISTS pgcrypto SCHEMA public;

CREATE EXTENSION IF NOT EXISTS pg_buffercache SCHEMA public;

CREATE EXTENSION IF NOT EXISTS btree_gin SCHEMA public;

CREATE EXTENSION IF NOT EXISTS pg_stat_statements SCHEMA public;

CREATE EXTENSION IF NOT EXISTS pg_trgm SCHEMA public;

CREATE EXTENSION IF NOT EXISTS pg_qualstats SCHEMA public;

CREATE EXTENSION IF NOT EXISTS vector SCHEMA public;

CREATE EXTENSION IF NOT EXISTS pg_background SCHEMA public;

\q

Шаг 4: Восстановление дампа d10task

pg_restore -p 5433 \

          -U dbo \

          -d d10task \

          -v \

          /opt/migration-backup/dumps/d10task_no_ext.dump

Шаг 5: Создание базы данных d10task_file

sudo -u postgres psql -p 5433
CREATE DATABASE d10task_file

   TEMPLATE template0

   OWNER dbo

   ENCODING 'utf8'

   LC_COLLATE 'ru_RU.utf8'

   LC_CTYPE 'ru_RU.utf8';

\q

Шаг 6: Восстановление дампа d10task_file

pg_restore -p 5433 \

          -U dbo \

          -d d10task_file \

          -v \

          /opt/migration-backup/dumps/d10task_file_no_ext.dump

Настройка прав и разрешений

Шаг 1: Настройка схем и базовых разрешений

sudo -u postgres psql -p 5433 -d d10task
-- Настройка search_path

ALTER ROLE D10TaskUser SET search_path = "dbo", "public";

ALTER ROLE dbo SET search_path = "dbo", "public";

ALTER USER MigrationsDaemon SET search_path = "dbo", "public";

ALTER USER rebus SET search_path = "rebus", "public";

-- Права USAGE на схемы для d10taskuser

GRANT USAGE ON SCHEMA dbo, sys TO d10taskuser;

GRANT USAGE ON SCHEMA SignalR TO d10taskuser;

-- Назначение ролей

GRANT dbo, rebus TO MigrationsDaemon;

-- Разрешения для dbo и MigrationsDaemon

GRANT ALL ON ALL TABLES IN SCHEMA dbo, sys TO dbo, MigrationsDaemon;

GRANT ALL ON ALL SEQUENCES IN SCHEMA dbo, sys TO dbo, MigrationsDaemon;

GRANT ALL ON ALL FUNCTIONS IN SCHEMA dbo, sys TO dbo, MigrationsDaemon;

GRANT ALL ON SCHEMA dbo, sys TO dbo, MigrationsDaemon;

-- Разрешения по умолчанию

ALTER DEFAULT PRIVILEGES IN SCHEMA dbo, sys, SignalR GRANT ALL ON TABLES TO dbo, MigrationsDaemon;

ALTER DEFAULT PRIVILEGES IN SCHEMA dbo, sys, SignalR GRANT ALL ON SEQUENCES TO dbo, MigrationsDaemon;

ALTER DEFAULT PRIVILEGES IN SCHEMA dbo, sys, SignalR GRANT ALL ON FUNCTIONS TO dbo, MigrationsDaemon;

ALTER DEFAULT PRIVILEGES IN SCHEMA dbo, sys, SignalR GRANT ALL ON TYPES TO dbo, MigrationsDaemon;

Шаг 2: Настройка для SMART тестирования

-- Права для role_D10TaskReader на основные схемы

GRANT USAGE ON SCHEMA dbo, sys, SignalR TO role_D10TaskReader;

GRANT SELECT ON ALL TABLES IN SCHEMA dbo, sys, SignalR TO role_D10TaskReader;

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA dbo, sys, SignalR TO role_D10TaskReader;

GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA dbo, sys, SignalR TO role_D10TaskReader;

-- Разрешения по умолчанию

ALTER DEFAULT PRIVILEGES IN SCHEMA dbo, sys, SignalR GRANT SELECT ON TABLES TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA dbo, sys, SignalR GRANT EXECUTE ON FUNCTIONS TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA dbo, sys, SignalR GRANT USAGE, SELECT ON SEQUENCES TO role_D10TaskReader;

-- Права на схему custom

GRANT ALL ON ALL TABLES IN SCHEMA custom TO role_D10TaskReader;

GRANT ALL ON ALL SEQUENCES IN SCHEMA custom TO role_D10TaskReader;

GRANT ALL ON ALL FUNCTIONS IN SCHEMA custom TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA custom GRANT ALL ON TABLES TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA custom GRANT ALL ON SEQUENCES TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA custom GRANT ALL ON FUNCTIONS TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA custom GRANT ALL ON TYPES TO role_D10TaskReader;

GRANT ALL ON SCHEMA custom TO role_D10TaskReader;

-- Права на схему rebus

GRANT ALL ON ALL TABLES IN SCHEMA rebus TO role_D10TaskReader;

GRANT ALL ON ALL SEQUENCES IN SCHEMA rebus TO role_D10TaskReader;

GRANT ALL ON ALL FUNCTIONS IN SCHEMA rebus TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA rebus GRANT ALL ON TABLES TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA rebus GRANT ALL ON SEQUENCES TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA rebus GRANT ALL ON FUNCTIONS TO role_D10TaskReader;

ALTER DEFAULT PRIVILEGES IN SCHEMA rebus GRANT ALL ON TYPES TO role_D10TaskReader;

GRANT ALL ON SCHEMA rebus TO role_D10TaskReader;

-- Права на языки

GRANT USAGE ON LANGUAGE plpgsql, sql TO role_D10TaskReader;

Шаг 3: Права для новой админки

-- Если есть схема dbadmin

GRANT USAGE ON SCHEMA dbadmin TO d10taskuser;

GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA dbadmin TO d10taskuser;

GRANT EXECUTE ON ALL FUNCTIONS IN SCHEMA dbadmin TO d10taskuser;

GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA dbadmin TO d10taskuser;

Шаг 4: Права для pg_background

GRANT EXECUTE ON FUNCTION pg_background_launch(text, int4) TO dbo;

GRANT EXECUTE ON FUNCTION pg_background_result(int4) TO dbo;

GRANT EXECUTE ON FUNCTION pg_background_detach(int4) TO dbo;

\q

Переключение на PostgreSQL 18

Стратегия переключения

Существует два подхода:

Вариант A: Изменить порты (PostgreSQL 18 → 5432, PostgreSQL 16 → 5434) — рекомендуется

Вариант B: Остановить PostgreSQL 16 и использовать только PostgreSQL 18

Вариант A: Изменение портов (рекомендуется)

Шаг 1: Остановка обеих служб

Остановка PostgreSQL 16:

sudo systemctl stop postgresql@16-main.service

Остановка PostgreSQL 18:

sudo systemctl stop postgresql@18-main.service

Проверка:

sudo systemctl status postgresql

Шаг 2: Изменение порта PostgreSQL 16 на 5434

sudo vim /etc/postgresql/16/main/postgresql.conf

Измените:

port = 5434

Шаг 3: Изменение порта PostgreSQL 18 на 5432

sudo vim /etc/postgresql/18/main/postgresql.conf

Измените:

port = 5432

Шаг 4: Запуск служб в новой конфигурации

Запуск PostgreSQL 18 на порту 5432:

sudo systemctl start postgresql@18-main.service

sudo systemctl status postgresql@18-main.service

Запуск PostgreSQL 16 на порту 5434 (резервная копия):

sudo systemctl start postgresql@16-main.service

sudo systemctl status postgresql@16-main.service

Шаг 5: Проверка портов

PostgreSQL 18 на основном порту 5432:

sudo -u postgres psql -p 5432 -c "SELECT version();"

PostgreSQL 16 на резервном порту 5434:

sudo -u postgres psql -p 5434 -c "SELECT version();"

Вариант B: Отключение PostgreSQL 16

Если тестирование прошло успешно и откат не требуется:

Остановка PostgreSQL 16:

sudo systemctl stop postgresql@16-main.service

Отключение автозапуска PostgreSQL 16:

sudo systemctl disable postgresql@16-main.service

Изменение порта PostgreSQL 18 на 5432:

sudo vim /etc/postgresql/18/main/postgresql.conf

port = 5432

Перезапуск PostgreSQL 18

sudo systemctl restart postgresql@18-main.service

Проверка миграции

Шаг 1: Проверка версии

sudo -u postgres psql -p 5432 -c "SELECT version();"

Ожидаемый результат: PostgreSQL 18.x

Шаг 2: Проверка расширений

sudo -u postgres psql -p 5432 -d d10task -c "\dx"

Должны быть установлены:

plpgsql

rum

pgcrypto

pg_buffercache

btree_gin

pg_stat_statements

pg_trgm

pg_qualstats

vector

pg_background

Шаг 3: Проверка io_method

sudo -u postgres psql -p 5432 -c "SHOW io_method;"

Ожидаемый результат: io_uring

Шаг 4: Проверка данных

sudo -u postgres psql -p 5432 -d d10task
-- Проверка количества таблиц

SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'dbo';

-- Проверка количества записей в основных таблицах

SELECT

   schemaname,

   tablename,

   pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
FROM pg_tables

WHERE schemaname = 'dbo'

ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC

LIMIT 10;

\q

Откат на PostgreSQL 16

Если обнаружены критические проблемы:

Быстрый откат (если использовали Вариант A)

1. Остановка PostgreSQL 18

sudo systemctl stop postgresql@18-main.service

2. Изменение порта PostgreSQL 16 обратно на 5432

sudo vim /etc/postgresql/16/main/postgresql.conf

port = 5432

3. Перезапуск PostgreSQL 16

sudo systemctl restart postgresql@16-main.service

4. Проверка

sudo -u postgres psql -p 5432 -c "SELECT version();"

Полный откат

Если PostgreSQL 16 был отключен:

1. Остановка PostgreSQL 18

sudo systemctl stop postgresql@18-main.service

sudo systemctl disable postgresql@18-main.service

2. Включение PostgreSQL 16

sudo systemctl enable postgresql@16-main.service

sudo systemctl start postgresql@16-main.service

3. Проверка

sudo systemctl status postgresql@16-main.service

Удаление PostgreSQL 16

Важно: выполняйте только после подтверждения стабильной работы PostgreSQL 18 (рекомендуется выдержать 1–2 недели).

Шаг 1: Проверка, что PostgreSQL 16 не используется

Убедитесь, что приложения подключаются к PostgreSQL 18

sudo -u postgres psql -p 5432 -c "SELECT version();"

Должен показать PostgreSQL 18.x

Проверка активных подключений к PostgreSQL 16

sudo -u postgres psql -p 5434 -c "SELECT count(*) FROM pg_stat_activity WHERE datname IS NOT NULL;"

Должно быть 0 (кроме служебных)

Шаг 2: Остановка и отключение PostgreSQL 16

sudo systemctl stop postgresql@16-main.service

sudo systemctl disable postgresql@16-main.service

Шаг 3: Удаление кластера PostgreSQL 16

Важно: выбор метода удаления зависит от расположения data_directory.

Сначала проверьте расположение данных:

cat /etc/postgresql/16/main/postgresql.conf | grep data_directory

Если data_directory = /pgdata/16-main (отдельная директория):

Можно использовать pg_dropcluster — это безопасно:

Удаление кластера (удаляет данные и конфиги)

sudo pg_dropcluster 16 main

Проверка:

pg_lsclusters

Если data_directory = /pgdata (родительская директория для PG18):

Важно: не используйте pg_dropcluster — он удалит /pgdata вместе с данными PostgreSQL 18.

Удаляйте вручную:

⚠️ Убедитесь, что сервис PostgreSQL 18 использует другую директорию данных (не /pgdata), прежде чем удалять содержимое. Проверьте параметр data_directory в конфигурации PostgreSQL 18.

1. Удалить конфиги PG16:

sudo rm -rf /etc/postgresql/16

2. Вручную удалить ТОЛЬКО файлы PG16 из /pgdata

Сначала посмотрите что там:

ls -la /pgdata/

Удалите только файлы/папки PG16, НЕ трогая 18-main:

sudo rm -rf /pgdata/base

sudo rm -rf /pgdata/global

sudo rm -rf /pgdata/pg_*

sudo rm -f /pgdata/PG_VERSION

sudo rm -f /pgdata/postgresql.auto.conf

sudo rm -f /pgdata/postmaster.*

Шаг 4: Удаление пакетов PostgreSQL 16

Удаление пакетов:

sudo apt remove postgresql-16 postgresql-client-16 postgresql-server-dev-16

Удаление неиспользуемых зависимостей:

sudo apt autoremove

Проверка оставшихся пакетов версии 16:

dpkg -l | grep postgresql | grep 16

Шаг 5: Удаление логов PostgreSQL 16

sudo rm -rf /var/log/postgresql/postgresql-16-main.log*

Шаг 6: Очистка временных файлов миграции

Удаление дампов (только после создания свежих бэкапов PG18!)

sudo rm -rf /opt/migration-backup/dumps/*.dump

Удаление бэкапа данных PG16

sudo rm -rf /opt/migration-backup/pg16-data-backup

Удаление бэкапов конфигураций (опционально, можно оставить для истории)

sudo rm -rf /opt/migration-backup/*.backup

Шаг 7: Финальная проверка

Проверка, что остался только PostgreSQL 18:

dpkg -l | grep postgresql

Проверка работающих кластеров:

pg_lsclusters

Проверка занятого места:

df -h /var/lib/postgresql

df -h /pgdata