Feito com Chinaski

Atualizações & Migrações

Upgrades e migrações: como o schema e o código do Chinaski avançam. Esta página se apoia na mecânica real do repositório: sessenta e dois arquivos de migração numerados como a história da evolução do schema, e dois caminhos concretos de upgrade, o script de deploy on-line e o script de bundle assinado para ambientes air-gapped.

A história das migrações (evolução do schema)

  • migrations/ carrega 62 arquivos SQL numerados, de 001_phase2_database_foundation.sql a 062_form_submissions_read_at.sql. Cada um é autodocumentado: um cabeçalho lista o que muda, e o comando de aplicação (sqlite3 chinaski.db < migrations/…) consta em todos os arquivos. Os nomes dos arquivos funcionam como um changelog: leia o diretório de baixo para cima e você lê a história do produto: a fundação da fase 2 (constraints CHECK, índices de deduplicação, colunas mortas removidas), documentos (fase 45), toda a família stacks (da 020 até a herança na 043), o reforço de formulários (tokens de referência, atribuição, cotas, validação de consentimento, read-at), o registro de eventos, hierarquia/slots/renumeração da navegação, versões do promotion guard, parâmetros de durabilidade do build e o render cache.
  • schema.sql é o ponto final de instalação nova da mesma história: uma instalação nova é inicializada diretamente a partir de schema.sql, então os dois caminhos precisam chegar ao mesmo formato. Isso é garantido, não presumido: bin/check-schema-sync.pl compara um banco de dados ativo com schema.sql e sai com código diferente de zero, com uma nota "Fix: add the missing tables/columns to schema.sql", quando eles divergem. O memorando de correção é o contrato do próprio projeto: instalações novas precisam corresponder às ativas.
  • A ordem das migrações é determinante: o comentário do script de execução observa "Must run before phase41: pages/posts rebuild SELECTs og_image_url from existing rows, so a DB predating the column would fail that rebuild." Um grande bloco de funções auxiliares de escrita no código executa cada uma apenas quando chega a sua vez.
  • Toda migração é escrita para ser idempotente: há notas no estilo IF NOT EXISTS em todo o conjunto de migrações (a linguagem já rodou duas vezes em um caminho de instalação nova/boot muitas vezes), de modo que uma varredura de migrações na inicialização nunca explode em reexecuções.

Executando migrações: automático

As migrações rodam na inicialização da aplicação: run_all() de Chinaski::Migrations encadeia os auxiliares _apply_* em uma ordem fixa (_apply_perf_indexes primeiro, depois as famílias de conteúdo/stacks/formulários/navegação/documentos em ordem de dependência). Um operador nunca executa uma migração manualmente; a aplicação converge seu próprio banco de dados para o schema atual do código.

Carimbos de versão existem onde uma migração é ignorada por detecção de banco de dados antigo: uma alteração do PRAGMA user_version do SQLite dentro de um dos auxiliares _apply_* da cadeia (observado: a condição que leva uma entrada anterior à 53 diretamente à 53, para pular o trabalho anterior em um banco de dados recente). O mapeamento para os números da versão atual está no código, não em uma tabela: nenhuma lista de versões voltada ao operador é distribuída.

Fazendo upgrade de uma instância em execução

On-line (em um host conectado)

deploy/deploy.sh <N>: a receita padrão: 1. O git atualiza a árvore de instalação e instala as dependências. 2. perl -c cms.pl verifica a sintaxe da aplicação (uma quebra de sintaxe aborta antes de tocar em qualquer coisa). 3. Reconstrua o site estático com CHINASKI_DB/CHINASKI_OUTPUT definidos explicitamente. 4. Reinicie o serviço, a menos que o builder tenha falhado; nesse caso o deploy é abortado e o serviço mantém a árvore servida anteriormente (reiniciar sobre uma saída pela metade publicaria uma corrupção do serviço).

Air-gapped

scripts/apply_update.sh: o script de upgrade offline: 1. Em uma máquina conectada, obtenha o bundle da release a partir do seu manifesto (um .tar.gz) e sua assinatura Ed25519. 2. Transfira ambos para o destino e forneça a sua chave pública de release. 3. O script verifica primeiro a assinatura, faz backup da árvore atual da aplicação e então aplica a atualização, mantendo a versão anterior recuperável.

Notificação de atualizações: defina uma URL de manifesto de atualização quando as atualizações devem ser verificadas; instalações air-gapped sem CHINASKI_UPDATE_MANIFEST_URL nunca se conectam.

Restaurando entre limites de versão

A restauração de um backup recusa uma incompatibilidade de versão de schema: um backup antigo só é restaurado em um schema correspondente, ou seja, na versão correspondente da aplicação. Portanto, fazer upgrade da aplicação para corresponder à versão de schema do backup faz parte de um procedimento de restauração (a página de recuperação de desastres percorre esse caminho).

Quando um upgrade traz mudanças de schema, o mecanismo de restauração de backup as reflete na condição de schema (a condição de restauração da ferramenta): não é uma migração automática; a aplicação aplica a mudança na próxima inicialização.

A fixação: testes

A higiene das migrações é garantida na suíte de testes, além dos scripts:

  • O lint de migrações (migrations_lint.t) verifica se os arquivos de migração seguem a higiene do projeto (ids limpos, reexecução segura).
  • Os testes de migração/suíte de código exercitam o fluxo real de run-all contra bancos de dados fixture; migrations_helpers executa o mecanismo com handlers de banco de dados simulados/dry (CHINASKI_DB apontado para qualquer caminho; ignorado nos testes).

Checklist para um upgrade

  1. Faça backup primeiro (banco de dados + arquivos que lhe interessam, seja o backup do sistema ou um arquivo dentro da aplicação).
  2. deploy.sh <N> em hosts conectados (que faz verificação de sintaxe, rebuild e reinício) ou apply_update.sh com um bundle assinado em um ambiente air-gapped.
  3. Se o deploy.sh falhou no nível de schema (por exemplo, as migrações não rodaram), verifique o journal: as migrações rodam na inicialização, não durante o próprio script de deploy.
  4. Divergência em instalação nova: execute bin/check-schema-sync.pl para comparar schema.sql com o banco de dados ativo; sua saída diferente de zero sinaliza imediatamente a edição que as instalações novas precisarão adicionar.
  5. Verifique se o site renderiza (páginas mais /health) e verifique a completude do build pelo histórico de builds.
Leia este site em