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:
- executar script via bash script (recomendado) -- basta executar
scripts/runDBMigrationScript.sh <VERSAO>.sql - acessar o DB direto e executar manualmente. Pra isso, o melhor jeito é:
- copiar momentaneamente o arquivo
private/adminer.phppara o diretóriopublic - 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
- copiar momentaneamente o arquivo
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.jsonpra 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).