Различия

Показаны различия между двумя версиями страницы.

Ссылка на это сравнение

sql:mysql-to-pg-plan [2024/08/13 21:07]
admin создано
sql:mysql-to-pg-plan [2024/08/13 21:24] (текущий)
admin
Строка 9: Строка 9:
   - Запустить pgloader, который перенесет данные   - Запустить pgloader, который перенесет данные
   - Переключить конфиг МС на Postgres и запустить МС   - Переключить конфиг МС на Postgres и запустить МС
 +
 +
 +Подробное описание на примере переезда одного микросервиса ''us-mortgage''
 +
 +===== Исправить код МС на Postgres =====
 +
 +Локально: переключить проект на Postgres, запустить тесты, сделать смоук-тест.
 +
 +==== План перевода ====
 +
 +Если проект был форкнут от us-template, тогда достаточно
 +
 +<code bash>
 +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
 +# Исправление конфликтов и измененных значений
 +</code>
 +
 +Если это не так, то можно копировать из ''us-template'' готовые участки кода по плану:
 +
 +<code>
 +[ ] .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'))
 +</code>
 +
 +Более тщательные проверки можно делать после переезда на develop/test окружениях.
 +
 +<note important>
 +**Foreign key**
 +
 +MySQL по-дефолту при создании FK также создает индекс на это поле. Однако Postgres этого не делает по-умолчанию. Но индексы нужны. Поэтому необходимо проверить, и при необходимости сделать миграцию для их создания.
 +</note>
 +
 +===== Создать БД =====
 +
 +Можно воспользоваться скриптом для генерации SQL, либо использовать сниппет ниже.
 +
 +<code 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";
 +</code>
 +
 +===== Сделать чистую миграцию - только схема =====
 +
 +На локальной машине разработчика проверить, что везде используется подключение "pgsql" (''databases.php'', ''queue.php'' и ''telescope.php'').
 +
 +Временно добавить следующие строки в подключение "pgsql":
 +
 +<code php>
 +'host' => '******',
 +'port' => '5432',
 +'database' => 'us-template-develop',
 +'username' => 'svc-us-template-develop',
 +'password' => '******',
 +</code>
 +
 +Запустить миграцию: в результате появится чистая база данных.
 +
 +<code bash>
 +art migrate
 +</code>
 +
 +В некоторых проектах туда добавляются первоначальные данные, но это не важно - они будут снесены далее.
 +
 +Зачем это делать? Утилита [[sql:pgloader|pgloader]] может самостоятельно мигрировать схему, однако это потребует много времени по ее настройке. Например, будет проблема с unsigned. Проще сделать миграцию и перенести только данные.
 +
 +
 +===== Остановить МС =====
 +
 +
 +Делается через GitLab. Нужно, чтобы не была нарушена ссылочная целостность.
 +
 +
 +Запустить pgloader, который перенесет данные
 +
 +Создать файл ''migrate-mortgage-data.load'' на сервере Postgres.
 +
 +Его примерное содержимое:
 +
 +<code>
 +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/
 +;
 +</code>
 +
 +pgloader работает со схемой, которая должна совпадать с названием БД, поэтому вначале схема переименовывается, а затем возвращается назад в public.
 +
 +Также происходит truncate, иначе при миграции могут быть ошибки - если ''artisan migrate'' делает первоначальное наполнение данными.
 +
 +Запуск миграции:
 +
 +<code bash>
 +pgloader migrate-mortgage-data.load
 +</code>
 +
 +Необязательно, но желательно прописать ''search_path'' для базы данных. Делается это после переноса данных:
 +
 +<code sql>
 +ALTER DATABASE "us-template-develop" SET search_path TO "public";
 +</code>
 +
 +Более подробная информация о самой утилите приведена [[sql:pgloader|тут]].
 +
 +===== Переключить конфиг МС на Postgres и запустить МС =====
 +
 +Список переменных, которые следует исправить на dev/test:
 +
 +<code>
 +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: "******"
 +</code>
 +
 +Список переменных, которые следует исправить на pre-prod/prod:
 +
 +<code>
 +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"
 +</code>
 +
 +<note important>
 +Не допускайте ошибок в прод-конфигурации. Нужно проверить, что нет дублей переменных DB_ ниже в файле, DB_CONNECTION=pgsql, DB_PORT=5432.
 +</note>
Печать/экспорт