MariaDB
 sql >> Base de Dados >  >> RDS >> MariaDB

Como executar alterações de esquema no MySQL e MariaDB de maneira segura


Antes de tentar realizar qualquer alteração de esquema em seus bancos de dados de produção, você deve certificar-se de ter um plano de reversão sólido; e que seu procedimento de mudança foi testado e validado com sucesso em um ambiente separado. Ao mesmo tempo, é sua responsabilidade garantir que a mudança não cause nenhum ou o menor impacto possível aceitável para o negócio. Definitivamente não é uma tarefa fácil.

Neste artigo, veremos como realizar alterações de banco de dados no MySQL e no MariaDB de maneira controlada. Vamos falar sobre alguns bons hábitos no seu dia-a-dia de trabalho de DBA. Vamos nos concentrar em pré-requisitos e tarefas durante as operações reais e problemas que você pode enfrentar ao lidar com alterações de esquema de banco de dados. Também falaremos sobre ferramentas de código aberto que podem ajudá-lo no processo.

Cenários de teste e reversão

Backup


Há muitas maneiras de perder seus dados. A falha de atualização do esquema é uma delas. Ao contrário do código do aplicativo, você não pode descartar um pacote de arquivos e declarar que uma nova versão foi implantada com sucesso. Você também não pode simplesmente colocar de volta um conjunto mais antigo de arquivos para reverter suas alterações. Claro, você pode executar outro script SQL para alterar o banco de dados novamente, mas há casos em que a única maneira precisa de reverter as alterações é restaurando todo o banco de dados do backup.

No entanto, e se você não puder reverter seu banco de dados para o backup mais recente ou se sua janela de manutenção não for grande o suficiente (considerando o desempenho do sistema), então você não pode realizar um backup completo do banco de dados antes da alteração?

Pode-se ter um ambiente sofisticado e redundante, mas contanto que os dados sejam modificados em locais primários e de espera, não há muito o que fazer a respeito. Muitos scripts podem ser executados apenas uma vez, ou as alterações são impossíveis de desfazer. A maior parte do código de alteração SQL se enquadra em dois grupos:
  • Executar uma vez – você não pode adicionar a mesma coluna à tabela duas vezes.
  • Impossível desfazer – uma vez que você derrubou aquela coluna, ela se foi. Sem dúvida, você pode restaurar seu banco de dados, mas isso não é exatamente um desfazer.

Você pode resolver esse problema de pelo menos duas maneiras possíveis. Uma seria habilitar o log binário e fazer um backup, que é compatível com PITR. Esse backup deve ser completo, completo e consistente. Para xtrabackup, desde que contenha um conjunto de dados completo, ele será compatível com PITR. Para mysqldump, existe uma opção para torná-lo compatível com PITR também. Para alterações menores, uma variação do backup do mysqldump seria levar apenas um subconjunto de dados para alterar. Isso pode ser feito com a opção --where. O backup deve fazer parte da manutenção planejada.
mysqldump -u -p --lock-all-tables --where="WHERE employee_id=100" mydb employees> backup_table_tmp_change_07132018.sql

Outra possibilidade é usar CREATE TABLE AS SELECT.

Você pode armazenar dados ou alterações de estrutura simples na forma de uma tabela temporária fixa. Com essa abordagem, você obterá uma fonte se precisar reverter suas alterações. Pode ser bastante útil se você não alterar muitos dados. A reversão pode ser feita retirando dados dele. Se ocorrer alguma falha ao copiar os dados para a tabela, ela será automaticamente descartada e não criada, portanto, certifique-se de que sua instrução crie uma cópia necessária.

Obviamente, existem algumas limitações também.

Como a ordem das linhas nas instruções SELECT subjacentes nem sempre pode ser determinada, CREATE TABLE ... IGNORE SELECT e CREATE TABLE ... REPLACE SELECT são sinalizados como não seguros para replicação baseada em instrução. Essas instruções produzem um aviso no log de erros ao usar o modo baseado em instrução e são gravadas no log binário usando o formato baseado em linha ao usar o modo MIXED.

Um exemplo muito simples de tal método poderia ser:
CREATE TABLE tmp_employees_change_07132018 AS SELECT * FROM employees where employee_id=100;
UPDATE employees SET salary=120000 WHERE employee_id=100;
COMMMIT;

Outra opção interessante pode ser o banco de dados flashback MariaDB. Quando uma atualização ou exclusão incorreta ocorre e você deseja reverter para um estado do banco de dados (ou apenas uma tabela) em um determinado momento, você pode usar o recurso de flashback.

A reversão pontual permite que os DBAs recuperem dados mais rapidamente, revertendo transações para um momento anterior, em vez de realizar uma restauração de um backup. Com base em eventos DML baseados em ROW, o flashback pode transformar o log binário e reverter os propósitos. Isso significa que pode ajudar a desfazer as alterações de linha rapidamente. Por exemplo, ele pode alterar os eventos DELETE para INSERTs e vice-versa, e trocará as partes WHERE e SET dos eventos UPDATE. Essa ideia simples pode acelerar drasticamente a recuperação de certos tipos de erros ou desastres. Para quem está familiarizado com o banco de dados Oracle, é um recurso bem conhecido. A limitação do flashback do MariaDB é a falta de suporte a DDL.

Criar um escravo de replicação atrasada


Desde a versão 5.6, o MySQL suporta replicação atrasada. Um servidor escravo pode ficar atrás do mestre por pelo menos um determinado período de tempo. O atraso padrão é 0 segundos. Use a opção MASTER_DELAY para CHANGE MASTER TO para definir o atraso para N segundos:
CHANGE MASTER TO MASTER_DELAY = N;

Seria uma boa opção se você não tivesse tempo para preparar um cenário de recuperação adequado. Você precisa ter atraso suficiente para perceber a mudança problemática. A vantagem dessa abordagem é que você não precisa restaurar seu banco de dados para remover os dados necessários para corrigir sua alteração. O banco de dados em espera está funcionando, pronto para coletar dados, o que minimiza o tempo necessário.

Criar um escravo assíncrono que não faz parte do cluster


Quando se trata do cluster Galera, testar as alterações não é fácil. Todos os nós executam os mesmos dados e a carga pesada pode prejudicar o controle de fluxo. Portanto, você não apenas precisa verificar se as alterações foram aplicadas com êxito, mas também qual foi o impacto no estado do cluster. Para tornar seu procedimento de teste o mais próximo possível da carga de trabalho de produção, você pode adicionar um escravo assíncrono ao cluster e executar seu teste lá. O teste não afetará a sincronização entre nós do cluster, porque tecnicamente não faz parte do cluster, mas você terá a opção de verificar com dados reais. Esse escravo pode ser facilmente adicionado do ClusterControl.
ClusterControl adicionar escravo assíncrono
Conforme mostrado na captura de tela acima, o ClusterControl pode automatizar o processo de adição de um escravo assíncrono de algumas maneiras. Você pode adicionar o nó ao cluster, atrasar o escravo. Para reduzir o impacto no mestre, você pode usar um backup existente em vez do mestre como fonte de dados ao construir o escravo.

Clonar banco de dados e medir o tempo


Um bom teste deve ser o mais próximo possível da mudança de produção. A melhor maneira de fazer isso é clonar seu ambiente existente.
ClusterControl Clone Cluster para teste

Realizar alterações por meio de replicação


Para ter um melhor controle sobre suas alterações, você pode aplicá-las em um servidor escravo com antecedência e depois fazer a transição. Para replicação baseada em instrução, isso funciona bem, mas para replicação baseada em linha, isso pode funcionar até certo ponto. A replicação baseada em linha permite a existência de colunas extras no final da tabela, portanto, desde que possa gravar as primeiras colunas, tudo ficará bem. Primeiro aplique essas configurações a todos os escravos, depois faça failover para um dos escravos e, em seguida, implemente a alteração no mestre e anexe-o como escravo. Se sua modificação envolver a inserção ou remoção de uma coluna no meio da tabela, ela funcionará com a replicação baseada em linha.

Operação


Durante a janela de manutenção, não queremos ter tráfego de aplicativos no banco de dados. Às vezes é difícil encerrar todos os aplicativos espalhados por toda a empresa. Alternativamente, queremos permitir que apenas alguns hosts específicos acessem o MySQL remotamente (por exemplo, o sistema de monitoramento ou o servidor de backup). Para isso, podemos usar a filtragem de pacotes do Linux. Para ver quais regras de filtragem de pacotes estão disponíveis, podemos executar o seguinte comando:
iptables -L INPUT -v

Para fechar a porta MySQL em todas as interfaces, usamos:
iptables -A INPUT -p tcp --dport mysql -j DROP

e para abrir a porta MySQL novamente após a janela de manutenção:
iptables -D INPUT -p tcp --dport mysql -j DROP

Para aqueles sem acesso root, você pode alterar max_connection para 1 ou 'pular rede'.

Registro


Para iniciar o processo de registro, use o comando tee no prompt do cliente MySQL, assim:
mysql> tee /tmp/my.out;

Esse comando diz ao MySQL para registrar tanto a entrada quanto a saída de sua sessão de login atual do MySQL em um arquivo chamado /tmp/my.out . Em seguida, execute seu arquivo de script com o comando source.

Para ter uma ideia melhor de seus tempos de execução, você pode combiná-lo com o recurso de criação de perfil. Inicie o criador de perfil com
SET profiling = 1;

Em seguida, execute sua consulta com
SHOW PROFILES;

você vê uma lista de consultas para as quais o criador de perfil tem estatísticas. Então, finalmente, você escolhe qual consulta examinar com
SHOW PROFILE FOR QUERY 1;

Ferramentas de migração de esquema


Muitas vezes, um ALTER direto no mestre não é possível - na maioria dos casos causa lag no escravo, e isso pode não ser aceitável para as aplicações. O que pode ser feito, porém, é executar a mudança em modo de rolagem. Você pode começar com slaves e, uma vez que a alteração seja aplicada ao slave, migrar um dos slaves como um novo master, rebaixar o antigo master para slave e executar a alteração nele.

Uma ferramenta que pode ajudar nessa tarefa é o pt-online-schema-change da Percona. Pt-online-schema-change é direto - ele cria uma tabela temporária com o novo esquema desejado (por exemplo, se adicionamos um índice ou removemos uma coluna de uma tabela). Em seguida, ele cria gatilhos na tabela antiga. Esses gatilhos existem para espelhar as alterações que acontecem na tabela original para a nova tabela. As alterações são espelhadas durante o processo de alteração do esquema. Se uma linha for adicionada à tabela original, ela também será adicionada à nova. Ele emula a maneira como o MySQL altera as tabelas internamente, mas funciona em uma cópia da tabela que você deseja alterar. Isso significa que a tabela original não está bloqueada e os clientes podem continuar lendo e alterando dados nela.

Da mesma forma, se uma linha for modificada ou excluída na tabela antiga, ela também será aplicada na nova tabela. Em seguida, inicia-se um processo em segundo plano de cópia de dados (usando LOW_PRIORITY INSERT) entre a tabela antiga e a nova. Uma vez que os dados foram copiados, RENAME TABLE é executado.

Outra ferramenta interessante é o gh-ost. Gh-ost cria uma tabela temporária com o esquema alterado, assim como o pt-online-schema-change faz. Ele executa consultas INSERT, que usam o seguinte padrão para copiar dados da tabela antiga para a nova. No entanto, ele não usa gatilhos. Infelizmente, os gatilhos podem ser a fonte de muitas limitações. gh-ost usa o fluxo de log binário para capturar as alterações da tabela e as aplica de forma assíncrona na tabela fantasma. Uma vez que verificamos que gh-ost pode executar nossa mudança de esquema corretamente, é hora de realmente executá-la. Lembre-se de que pode ser necessário descartar manualmente as tabelas antigas que foram criadas pelo gh-ost durante o processo de teste da migração. Você também pode usar os sinalizadores --initially-drop-ghost-table e --initial-drop-old-table para pedir ao gh-ost para fazer isso por você. O comando final a ser executado é exatamente o mesmo que usamos para testar nossa mudança, apenas adicionamos --execute a ele.

pt-online-schema-change e gh-ost são muito populares entre os usuários do Galera. No entanto, o Galera tem algumas opções adicionais. Os dois métodos Total Order Isolation (TOI) e Rolling Schema Upgrade (RSU) têm seus prós e contras.

TOI - Este é o método de replicação DDL padrão. O nó que origina o conjunto de gravação detecta o DDL no momento da análise e envia um evento de replicação para a instrução SQL antes mesmo de iniciar o processamento do DDL. As atualizações de esquema são executadas em todos os nós do cluster na mesma sequência de ordem total, impedindo que outras transações sejam confirmadas durante a operação. Esse método é bom quando você deseja que suas atualizações de esquema online sejam replicadas por meio do cluster e não se importe de bloquear a tabela inteira (semelhante a como as alterações de esquema padrão ocorreram no MySQL).
SET GLOBAL wsrep_OSU_method='TOI';

RSU - executa as atualizações de esquema localmente. Nesse método, suas gravações afetam apenas o nó no qual são executadas. As alterações não são replicadas para o restante do cluster. Esse método é bom para operações não conflitantes e não desacelera o cluster.
SET GLOBAL wsrep_OSU_method='RSU';

Enquanto o nó processa a atualização do esquema, ele dessincroniza com o cluster. Ao concluir o processamento da atualização do esquema, ele aplica eventos de replicação atrasados ​​e se sincroniza com o cluster. Essa pode ser uma boa opção para executar criações de índice pesadas.

Conclusão


Apresentamos aqui vários métodos diferentes que podem ajudá-lo a planejar suas alterações de esquema. Claro que tudo depende da sua aplicação e dos requisitos de negócios. Você pode projetar seu plano de mudança, realizar os testes necessários, mas ainda há uma pequena chance de que algo dê errado. De acordo com a lei de Murphy - “as coisas vão dar errado em qualquer situação, se você lhes der uma chance”. Portanto, certifique-se de experimentar diferentes maneiras de realizar essas alterações e escolha aquela com a qual você se sente mais confortável.