Skip to main content

O PROBLEMA

Quando é feito upgrade de versão do Accelero, pode ser necessário fazer alguns updates/ajustes que não acontecem "no nível do GIT", como migração de DB.

O Accelero está preparado pra resolver isso "meio que automaticamente" (com raríssimas exceções).

DB MIGRATION

As migrações de banco de dados são executadas automaticamente durante o processo de upgrade (nível do Docker).

Existe um script chamado scripts/runAllDBMigrationScripts.sh cuja responsabilidade é:

  • descobrir quais scripts de migração devem ser executados (mais sobre isso adiante);
  • executar esses scripts ANTES do sistema "subir".

Pra descobrir quais scripts devem ser executados, existe um script PHP (jobs/get_migration_scripts_to_run) que é executado "do lado de dentro do container".

Esse script faz o seguinte procedimento:

  • busca no banco de dados qual a versão atual do schema (configuracoes > cfgAlias = dbversion);
  • lista todos os arquivos de migration disponíveis (dbmigration/*.sql);
  • com uma regra baseada em semver, descobre quais scripts estão "à frente do schema atual".

O script bash pega o retorno desse script PHP e executa (de dentro do container do DB) os scripts de migração.

Como regra geral, o script de migração deve, ele próprio, atualizar a versão do schema na tabela configuracoes.

Exceção rara de migration

O script PHP "descobridor de migrations" executa o bootstrap do sistema.

É tecnicamente possível que haja alguma alteração na aplicação que impeça o próprio bootstrap de "subir" (bootstrap depende de algo que está no DB, mas o DB está desatualizado e para atualizar precisa do bootstrap... deadlock...). Se isso acontecer, é necessário executar o script de migração manualmente.

Existem duas formas de se fazer isso:

  1. executar script via bash script (recomendado) -- basta executar scripts/runDBMigrationScript.sh <VERSAO>.sql
  2. acessar o DB direto e executar manualmente. Pra isso, o melhor jeito é:
    • copiar momentaneamente o arquivo private/adminer.php para o diretório public
    • subir os containers do webserver + php + db (docker compose up webserver accelero_mariadb accelero_php)
    • acessar https://deploy.accelerobr.com.br/adminer.php
    • executar os scripts necessários
    • excluir o public/adminer.php

Formato de arquivos de migration SQL

Devem ser criados arquivos com nome VERSAO.sql (2.9.4.sql ou 2.16.0-HF4, por exemplo) com a seguinte estrutura básica:

USE `accelero`;
SET NAMES utf8mb4;

/* scripts necessários... */

UPDATE `configuracoes`
SET `cfgData`='2.16.0'
WHERE `cfgAlias` = 'dbversion';

Deve-se tomar bastante cuidado pra que os scripts "não quebrem" caso executado em duplicidade. Pra isso, buscar sempre usar cláusulas tipo IF NOT EXIST e INSERT IGNORE. Por exemplo:

ALTER TABLE `tabela`
ADD COLUMN IF NOT EXISTS `novaColuna` tinyint(1) NULL DEFAULT 0;

INSERT IGNORE INTO `tabela` (`id`, `value`) VALUES
(19, 'abc');

ALTER TABLE `tabela`
ADD INDEX IF NOT EXISTS `column` (`column`);

ALTER TABLE `tabela`
ADD CONSTRAINT `tabela_fk` FOREIGN KEY IF NOT EXISTS (`id`) REFERENCES `tabela2` (`idexterno`) ON DELETE SET NULL;

Para branches de desenvolvimento, é melhor criar arquivos com nomenclatura BRANCH.sql. Ao fazer o merge do branch para um branch principal, daí faz-se o merge desse arquivo manualmente (copiar manualmente o conteúdo do BRANCH.sql para o dev.sql, fazendo os ajustes necessários).

Na hora de lançar uma versão, daí toma-se o cuidado de renomear o arquivo para VERSAO.sql.

PHP MIGRATION

Em algumas situações, não é possível (ou eficiente) fazer todas as migrações com scripts SQL. Às vezes é simplesmente mais fácil executar um script PHP pra fazer o serviço, geralmente pra fazer algum tipo de migração de dados (tirar dados de um lugar e jogar pra outro, por exemplo).

Pra isso, existe uma estrutura chamada PHP Migrations.

Todas as vezes que o asyncprocessor entra no ar, ele executa de forma síncrona o script run_php_migrations.php.

Esse script faz o seguinte procedimento:

  • lista todos os arquivos de migration disponíveis (phpmigration/*.php);
  • busca um arquivo phpmigration/history.json pra descobrir o que já foi executado;
  • o que ainda não foi executado, executa e atualiza o arquivo phpmigration/history.json.

Como esse arquivo history.json em teoria pode ser apagado, é bom sempre tentar garantir que esses scripts sejam seguros (que podem ser executados duas vezes, inclusive depois de muito tempo de operação, sem risco de mexer aonde não deve).