Gerenciamento de esquema com Skeema

Publicados: 2019-04-26

Nota: Este post vem da equipe de engenharia do SendGrid. Para mais postagens de engenharia técnica como esta, confira nosso blogroll técnico.

O gerenciamento de esquema de banco de dados varia de um oeste selvagem que qualquer um pode “fazer ao vivo” no processo de produção a um processo de revisão de várias etapas e várias equipes em cascata, onde apenas um indivíduo ungido pode tocar no banco de dados de produção.

À medida que os dados contidos em bancos de dados relacionais se tornam mais valiosos para uma empresa e a disponibilidade do banco de dados se torna mais importante para os negócios, surgem barreiras para possíveis alterações de esquema de ruptura.

No início, os Administradores de Banco de Dados (DBAs) tornaram-se os guardiões do banco de dados para proteger o banco de dados de coisas ruins acontecendo. Mas ter um DBA da velha guarda entre os desenvolvedores e o banco de dados de seus aplicativos pode causar uma desaceleração significativa no ciclo de vida de desenvolvimento de um aplicativo, criar silos de desenvolvimento e operações e gerar atrito entre as equipes.

No mundo atual orientado para o desenvolvimento de micro serviços, os desenvolvedores precisam ser capazes de gerenciar as alterações do esquema do banco de dados por conta própria, porque são seus dados e eles são os responsáveis ​​pelo desempenho e pelo tempo de atividade do aplicativo. As equipes de DBAs e Operações precisam fornecer ferramentas e conselhos adequados para ajudar as equipes de desenvolvimento a se tornarem donas de seus bancos de dados.

Como gerenciamos o esquema

Nosso processo de gerenciamento de esquema atual usa um único repositório Git para armazenar o esquema inicial para todos os nossos clusters de banco de dados e contém todas as alterações subsequentes a esse esquema à medida que as alterações/criações e eliminações de tabelas individuais são aplicadas:

  • Um desenvolvedor faz uma alteração de esquema localmente e gera uma instrução alter/create/drop e a adiciona como um pull-request a um branch de integração.
  • Um conjunto de tickets do Jira para a equipe de operações de dados é criado para revisar e aplicar as alterações de esquema em nossos ambientes de teste/preparação e produção.
  • Um membro da equipe de operações de dados analisa a alteração solicitada e aplica a alteração ao ambiente de teste/preparação e mescla o PR com a ramificação de integração.
  • O desenvolvedor solicitante testa a mudança em nossos ambientes de teste/preparação e aprova a mudança para ser enviada para produção.
  • Por fim, o Data Operations mescla o branch de integração ao master e aplica a alteração de esquema ao ambiente de produção.

Dado o valor dos dados armazenados em nossos bancos de dados e o desejo de ter esses bancos de dados funcionando bem o tempo todo, optamos por essa sequência bizantina de eventos para nos protegermos de nós mesmos.

Proteger o banco de dados é uma coisa, mas esse processo apresenta vários obstáculos para fazer alterações no esquema de maneira confiável e eficiente:

  • Revisar e fazer alterações de esquema acontece duas vezes por semana e pode ser facilmente prejudicado, pois várias equipes trabalham em bancos de dados diferentes, todos no mesmo repositório Git, e todos dependem de alguém da equipe de operações de dados para revisar e fazer alterações em vários ambientes.
  • Ter um repositório para todos os esquemas de banco de dados relacional pode levar a processos de lançamento desafiadores. Uma alteração em um esquema que está pronto para produção não pode ir para produção se houver outras alterações de esquema que não estão prontas para serem enviadas para produção, mas aguardando testes adicionais.
  • A equipe de operações de dados, que é uma equipe pequena, torna-se um gargalo ao tentar gerenciar quais mudanças podem ou não ir para produção e quando. Conflitos de agendamento e disponibilidade de pessoal podem realmente retardar o lançamento de novos recursos ou correções para aplicativos atuais.
  • Estamos aplicando manualmente essas alterações aos sistemas de produção usando comentários em pull requests e tickets do Jira; às vezes, copiar e colar pode dar terrivelmente errado.

Digite Skeema (e alguns ajudantes)

Para remover esses obstáculos de processo, tornar as alterações de esquema menos propensas a erros humanos, permitir que os desenvolvedores gerenciem o esquema de seu próprio aplicativo e potencialmente aumentar a velocidade de desenvolvimento, a equipe de operações de dados fez um grande esforço para automatizar e simplificar o gerenciamento de esquema de banco de dados.

Automatizamos a aplicação de alterações de esquema do desenvolvimento local à produção usando nossas ferramentas existentes, Git, Buildkite CI e pt-online-schema-change, com a adição de mais uma, Skeema.

A ideia é dividir nosso repositório de esquema de banco de dados monolítico em repositórios de esquema individuais, um por cluster de banco de dados, e permitir que os desenvolvedores façam suas próprias alterações de esquema em um ambiente que lhes seja familiar. Também queremos ter proteções sensatas para ajudar os desenvolvedores a buscar assistência adicional para fazer alterações de esquema grandes, complexas ou potencialmente destrutivas.

Skeema é uma ferramenta CLI que gerencia o esquema MySQL de forma declarativa usando SQL.

Ele pode gerar a linguagem de definição de dados (DDL) para cada tabela em um banco de dados e exportar o DDL para um sistema de arquivos local para integração com um repositório de rastreamento via Git. O Skeema pode comparar os arquivos SQL em um repositório Git com um banco de dados MySQL ativo e gerar essas diferenças como instruções DDL.

Ele também pode ser configurado para usar a ferramenta pt-online-schema-change do Percona e formatar o comando pt-online-schema-change necessário para corresponder o esquema do banco de dados MySQL em execução ao esquema definido no repositório Git.

O Skeema também é capaz de gerenciar esquemas em vários ambientes, como local, teste e produção com diferentes configurações em cada um. E, finalmente, pode ser facilmente adaptado a um fluxo de trabalho baseado em pull request.

A criação de repositórios individuais de esquema de banco de dados MySQL quebrará nosso repositório Git monolítico db-schema atual e permitirá que desenvolvedores em equipes separadas gerenciem o esquema MySQL de seu aplicativo em seu próprio repositório em vez de um repositório compartilhado (db-schema).

Ter um repositório separado para cada esquema de banco de dados permitirá maior autonomia à equipe de desenvolvimento de aplicativos. Isso elimina a necessidade de coordenar todas as alterações de esquema em um cronograma rígido e permite que as alterações sejam movidas para produção conforme a equipe de aplicativos desejar.

Um componente vital para automatizar esse processo é o pipeline de CI da Buildkite. Criamos um pipeline que:

  • Verifica se há erros de sintaxe SQL
  • Cria um servidor MySQL de teste usando o branch master atual do esquema do banco de dados e testa a aplicação das alterações no pull request (PR)
  • Verifique as diferenças e aplique as alterações de PR ao nosso ambiente MySQL de teste
  • Verifique as diferenças e aplique as alterações de PR ao nosso ambiente de teste e produza algumas estatísticas de tabela do ambiente de produção

As estatísticas de saída de produção são o tamanho da tabela no disco e as contagens de linhas estimadas. Essas estatísticas podem ajudar a determinar se a alteração do esquema pode causar algum nível de interrupção do serviço e pode exigir tratamento especial. Uma vez que o PR é mesclado ao master, o pipeline buildkite verifica as diferenças entre o branch master e o que está sendo executado na produção.

Se as diferenças forem as alterações esperadas do PR, o desenvolvedor pode desbloquear esta etapa final e o Skeema aplica as alterações ao cluster de banco de dados MySQL de produção. Cada uma dessas etapas é uma etapa de bloqueio que requer aprovação da equipe de engenharia responsável pela alteração solicitada antes de passar para a próxima etapa.

No que diz respeito às proteções, configuramos o Skeema para não permitir alterações destrutivas de esquema na produção como padrão.

Alterações destrutivas são permitidas em nossos ambientes de teste e preparação.

Também configuramos o Skeema para usar pt-online-schema-change para fazer alterações no esquema. Essa é a mesma ferramenta de alteração de esquema com a qual a equipe do DataOps está familiarizada e está em uso no SendGrid há muitos anos. Desenvolvemos um conjunto de opções razoáveis ​​para o pt-online-schema-change reverter suas alterações se a replicação ficar para trás ou os threads ativos no banco de dados se tornarem excessivos.

Ter o Skeema configurado dessa maneira remove os erros potenciais de ter etapas manuais para o aplicativo e codificação manual de comandos pt-online-schema-change por membros da equipe DataOps.

Com a adição de proteções programáticas, equipes individuais podem ser responsáveis ​​pelo gerenciamento de seus esquemas de banco de dados MySQL e pela aplicação dessas alterações em ambientes de pré-produção e produção com relativa segurança. Se as proteções forem atingidas, a alteração do esquema falhará e será revertida. Os motivos da falha na alteração do esquema são enviados para os logs de compilação para revisão adicional.

Permitir que os desenvolvedores conduzam suas alterações do teste local em um laptop para a produção aumenta muito a autonomia do desenvolvedor e a propriedade do banco de dados que oferece suporte ao aplicativo. A automação e integração do Skeema em nosso processo de gerenciamento de banco de dados MySQL cobre facilmente cerca de noventa por cento de nossas tarefas gerais de gerenciamento de mudança de esquema.

A maioria das alterações de esquema são para adicionar colunas, alterar campos de enumeração, alterar padrões e adicionar índices. Os dez por cento restantes das alterações de esquema lidam com casos especiais de tabelas grandes, bancos de dados muito ativos ou tabelas particionadas. A partir desta postagem, o Skeema ainda não lida com alterações de esquema em tabelas particionadas, mas ouvi dizer que é uma adição frequentemente solicitada e o desenvolvedor do Skeema está pedindo ajuda ativamente para implementar esse recurso.

A combinação de Git, pt-online-schema-change, Skeema e um pipeline Buildkite CI traz um processo programático confiável e repetível para alterações de esquema de banco de dados MySQL. Ele permite que os desenvolvedores gerenciem com segurança o esquema de seus bancos de dados e controlem a rapidez com que os recursos e as correções são implementados na produção.

A inclusão de proteções apropriadas nos arquivos de configuração para Skeema e alteração de esquema pt-online fornece uma medida de confiança para desenvolvedores que implementam alterações de esquema e fornece feedback valioso sobre possíveis maneiras de prosseguir com a alteração de esquema se essas proteções forem atingidas.

A equipe de operações de dados permanece disponível para ajudar os dez por cento restantes dos casos aos quais esse processo não pode ser aplicado e trabalhará em ferramentas adicionais para aprimorar esse processo no futuro.