Содержание
План переноса данных
Краткое описание
- Исправить код МС на Postgres
- Создать БД
- Сделать чистую миграцию - только схема
- Остановить МС
- Запустить pgloader, который перенесет данные
- Переключить конфиг МС на Postgres и запустить МС
Подробное описание на примере переезда одного микросервиса us-mortgage
Исправить код МС на Postgres
Локально: переключить проект на Postgres, запустить тесты, сделать смоук-тест.
План перевода
Если проект был форкнут от us-template, тогда достаточно
git remote add template git@******:usbsite/services/us-template.git git fetch template laravel-10.x-latest git merge --no-commit --no-ff template/laravel-10.x-latest # Исправление конфликтов и измененных значений
Если это не так, то можно копировать из us-template готовые участки кода по плану:
[ ] .env.dist: подключения, порты
[ ] docker-compose.yml: поправить секции laravel-app, postgres, удалить mysql
[ ] docker/laravel-app/Dockerfile: добавлена секция для postgresql-client
[ ] docker/mysql: удалить
[ ] docker/postgres: добавить
[ ] docker/workspace/home/.my.cnf.dist: удалить
[ ] docker/workspace/home/Xzibit/.zshrc: поправить (там было прописывание конфига .my.cnf.dist)
[ ] src/laravel-app/config/database.php: удалить mysql, добавить pgsql, в том числе CI-подключения
[ ] src/laravel-app/config: найти 'mysql', заменить на 'pgsql'
[ ] src/laravel-app/phpunit.xml.dist: заменить на ci_test_pgsql
[ ] поправить миграцию 'jwt_public_keys', в ней исправлена строка 'key'. Внимание! При миграции данных следует исключить таблицу jwt_public_keys, иначе будут будут перенесены данные, которые приведут к ошибкам
[ ] /src/laravel-app/.env, .env.dist: - поправить DB_*, а лучше сделать пустыми файлами, чтобы не было перезатирания env
[ ] миграции: добавить индексы для FK
[ ] миграции: изменить тип поля json => jsonb, binary => longText/jsonb
[ ] Laravel-query-builder: поправить фильтры ('members.uuid' => AllowedFilter::exact('members.uuid'))
Более тщательные проверки можно делать после переезда на develop/test окружениях.
MySQL по-дефолту при создании FK также создает индекс на это поле. Однако Postgres этого не делает по-умолчанию. Но индексы нужны. Поэтому необходимо проверить, и при необходимости сделать миграцию для их создания.
Создать БД
Можно воспользоваться скриптом для генерации SQL, либо использовать сниппет ниже.
-- Создание БД для тестов на сервере develop CREATE DATABASE "ci-us-template"; CREATE DATABASE "ci-us-template-develop"; CREATE DATABASE "ci-us-template-test"; CREATE DATABASE "ci-us-template-pre-production"; CREATE DATABASE "ci-us-template-production"; ALTER DATABASE "ci-us-template" OWNER TO "ci-test"; ALTER DATABASE "ci-us-template-develop" OWNER TO "ci-test"; ALTER DATABASE "ci-us-template-test" OWNER TO "ci-test"; ALTER DATABASE "ci-us-template-pre-production" OWNER TO "ci-test"; ALTER DATABASE "ci-us-template-production" OWNER TO "ci-test"; -- На сервере develop CREATE USER "svc-us-template-develop" WITH PASSWORD '*****'; CREATE USER "svc-us-template-test" WITH PASSWORD '*****'; CREATE DATABASE "us-template-develop"; CREATE DATABASE "us-template-test"; GRANT "svc-us-template-develop" TO site_admin; GRANT "svc-us-template-test" TO site_admin; ALTER DATABASE "us-template-develop" OWNER TO "svc-us-template-develop"; ALTER DATABASE "us-template-test" OWNER TO "svc-us-template-test"; \c "us-template-develop"; GRANT ALL PRIVILEGES ON DATABASE "us-template-develop" TO "svc-us-template-develop"; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "svc-us-template-develop"; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO "svc-us-template-develop"; GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO "svc-us-template-develop"; \c "us-template-test"; GRANT ALL PRIVILEGES ON DATABASE "us-template-test" TO "svc-us-template-test"; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "svc-us-template-test"; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO "svc-us-template-test"; GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO "svc-us-template-test"; -- На сервере prod CREATE USER "svc-us-template-pre-production" WITH PASSWORD '****************'; CREATE USER "svc-us-template-production" WITH PASSWORD '****************'; CREATE DATABASE "us-template-pre-production"; CREATE DATABASE "us-template-production"; GRANT "svc-us-template-pre-production" TO site_admin; GRANT "svc-us-template-production" TO site_admin; ALTER DATABASE "us-template-pre-production" OWNER TO "svc-us-template-pre-production"; ALTER DATABASE "us-template-production" OWNER TO "svc-us-template-production"; \c "us-template-pre-production"; GRANT ALL PRIVILEGES ON DATABASE "us-template-pre-production" TO "svc-us-template-pre-production"; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "svc-us-template-pre-production"; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO "svc-us-template-pre-production"; GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO "svc-us-template-pre-production"; \c "us-template-production"; GRANT ALL PRIVILEGES ON DATABASE "us-template-production" TO "svc-us-template-production"; GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "svc-us-template-production"; GRANT ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public TO "svc-us-template-production"; GRANT ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public TO "svc-us-template-production";
Сделать чистую миграцию - только схема
На локальной машине разработчика проверить, что везде используется подключение «pgsql» (databases.php, queue.php и telescope.php).
Временно добавить следующие строки в подключение «pgsql»:
'host' => '******', 'port' => '5432', 'database' => 'us-template-develop', 'username' => 'svc-us-template-develop', 'password' => '******',
Запустить миграцию: в результате появится чистая база данных.
art migrate
В некоторых проектах туда добавляются первоначальные данные, но это не важно - они будут снесены далее.
Зачем это делать? Утилита pgloader может самостоятельно мигрировать схему, однако это потребует много времени по ее настройке. Например, будет проблема с unsigned. Проще сделать миграцию и перенести только данные.
Остановить МС
Делается через GitLab. Нужно, чтобы не была нарушена ссылочная целостность.
Запустить pgloader, который перенесет данные
Создать файл migrate-mortgage-data.load на сервере Postgres.
Его примерное содержимое:
LOAD DATABASE FROM mysql://USER:PASSWORD@mysqlhost/us-mortgage-develop INTO postgresql://USER:PASSWORD@localhost/us-mortgage-develop WITH data only, truncate, reset sequences SET maintenance_work_mem to '128MB', work_mem to '12MB', search_path to 'public' BEFORE LOAD DO $$ ALTER SCHEMA public RENAME TO "us-mortgage-develop"; $$ AFTER LOAD DO $$ ALTER SCHEMA "us-mortgage-develop" RENAME TO "public"; $$ EXCLUDING TABLE NAMES MATCHING ~/telescope_/, ~/failed_jobs/, ~/jwt_public_keys/ ;
pgloader работает со схемой, которая должна совпадать с названием БД, поэтому вначале схема переименовывается, а затем возвращается назад в public.
Также происходит truncate, иначе при миграции могут быть ошибки - если artisan migrate делает первоначальное наполнение данными.
Запуск миграции:
pgloader migrate-mortgage-data.load
Необязательно, но желательно прописать search_path для базы данных. Делается это после переноса данных:
ALTER DATABASE "us-template-develop" SET search_path TO "public";
Более подробная информация о самой утилите приведена тут.
Переключить конфиг МС на Postgres и запустить МС
Список переменных, которые следует исправить на dev/test:
app:
dev_mysql_credential: false
db_host: "******"
env:
- name: DB_DATABASE
value: us-template-develop
- name: DB_USERNAME
value: svc-us-template-develop
- name: DB_PASSWORD
value: "******"
Список переменных, которые следует исправить на pre-prod/prod:
app:
dev_mysql_credential: false
db_host: "******"
env:
- name: DB_DATABASE
value: us-template-production
- name: DB_USERNAME
value: svc-us-template-production
- name: DB_PASSWORD
value: "*********"
- name: DB_CONNECTION
value: "pgsql"
- name: DB_PORT
value: "5432"