Migração de banco de dados: conceitos e princípios (parte 1)

Neste documento, apresentamos conceitos, princípios, terminologia e arquitetura de migração de banco de dados com inatividade próxima de zero para arquitetos de nuvem que estão migrando bancos de dados para o Google Cloud no local ou em outros ambientes de nuvem.

Esta é a Parte 1 de duas. Na Parte 2, discutimos a configuração e a execução do processo de migração, incluindo casos de falha.

Migração de banco de dados é o uso de um serviço de migração de banco de dados para migrar dados de um banco de origem para um ou mais bancos de destino. Quando uma migração é concluída, o conjunto de dados nos bancos de dados de origem passa a residir totalmente no banco de destino, embora possivelmente de maneira reestruturada. Os clientes que acessaram os bancos de dados de origem são transferidos para os bancos de destino e os bancos de origem são desativados.

O processo de migração de banco de dados é mostrado no diagrama a seguir.

Fluxo de dados do banco de origem para o de destino pelo serviço de migração.

Neste documento, descrevemos a migração do banco de dados do ponto de vista da arquitetura:

  • Serviços e tecnologias envolvidos na migração do banco de dados
  • Diferenças entre migração homogênea e hierárquica de banco de dados
  • Desvantagens e seleção de tolerância de tempo de inatividade da migração
  • Arquitetura de configuração compatível com um substituto caso ocorram erros inesperados durante a migração

Neste documento, não descrevemos como configurar uma determinada tecnologia de migração de banco de dados. Em vez disso, apresentamos os fundamentos, conceitos e princípios da migração do banco de dados.

No diagrama abaixo, temos uma arquitetura de migração de banco de dados genérica.

Arquitetura de um serviço de migração que acessa bancos de dados de origem e destino.

Um serviço de migração de banco de dados é executado no Google Cloud e acessa bancos de origem e destino. Há duas variantes representadas: (a) a migração de um banco de dados de origem em um data center local ou uma nuvem remota para um banco de dados gerenciado, como o Cloud Spanner, e (b) uma migração para um banco de dados no Compute Engine.

Mesmo que os bancos de dados de destino tenham configurações e tipos diferentes (gerenciado e não gerenciado), a arquitetura e a configuração da migração são iguais nos dois casos.

Terminologia

Veja a seguir a definição dos principais termos de migração de dados:

banco de dados de origem: um banco com dados a serem migrados para um ou mais bancos de destino.

banco de dados de destino: um banco que recebe dados migrados de um ou mais bancos de origem.

migração de banco de dados: uma migração de dados de bancos de origem para bancos de destino, com o objetivo de desativar os sistemas de banco de dados de origem após concluir a migração. A migração pode incluir todo o conjunto de dados ou um subconjunto.

migração homogênea: uma migração de bancos de dados de origem para bancos de destino em que os bancos de origem e destino fazem parte do mesmo sistema de gerenciamento de banco de dados e do mesmo provedor.

migração heterogênea: uma migração de bancos de dados de origem para bancos de destino em que os bancos de origem e destino fazem parte de provedores diferentes.

sistema de migração de banco de dados: um serviço ou sistema de software que se conecta a bancos de dados de origem e destino para realizar migrações do banco de origem para o de destino.

processo de migração de dados: um processo configurado ou implementado que é executado pelo sistema de migração de dados para transferir dados do banco de origem para o de destino, possivelmente transformando os dados durante a transferência.

replicação de banco de dados: uma transferência contínua de dados de bancos de origem para bancos de destino, sem o objetivo de desativá-los. A replicação de banco de dados (às vezes chamada de streaming de banco de dados) é um processo contínuo.

Classificação de migrações de banco de dados

Há diferentes tipos de migrações de banco de dados, que pertencem a diferentes classes. Nesta seção, descrevemos os critérios que definem essas classes.

Diferenças entre replicação e migração

Em uma migração de banco de dados, os dados vão dos bancos de origem para os de destino. Após a migração completa dos dados, os bancos de origem são excluídos e o acesso do cliente é redirecionado aos bancos de destino. Às vezes, os bancos de dados de origem são mantidos como uma medida substituta caso haja problemas inesperados nos bancos de dados de destino. No entanto, depois que os bancos de dados de destino estiverem operando de maneira confiável, os bancos de origem serão excluídos.

Por outro lado, com a replicação de banco de dados, os dados são transferidos continuamente dos bancos de origem para os de destino, sem excluí-los. Às vezes, a replicação de banco de dados é chamada de streaming de banco de dados. Embora haja um horário de início definido, normalmente o horário de conclusão não é determinado. A replicação pode ser interrompida ou se tornar uma migração.

Neste documento, discutimos apenas a migração de banco de dados.

Diferenças entre migração parcial e completa

A migração do banco de dados é entendida como uma transferência completa e consistente de dados. Você define se o conjunto de dados inicial deve ser transferido como um banco de dados completo ou parcial (um subconjunto dos dados), assim como todas as alterações confirmadas no sistema de banco de dados de origem a partir desse momento.

Diferenças entre migração heterogênea e homogênea

Uma migração homogênea de banco de dados é uma migração entre os bancos de origem e destino com a mesma tecnologia de banco de dados, por exemplo, migrar de um banco MySQL para outro desse tipo ou de um para outro banco da Oracle®. Migrações homogêneas também incluem migrações entre um sistema de banco de dados auto-hospedado, como o PostgreSQL, para uma versão gerenciada dele, como o Cloud SQL (uma variante do PostgreSQL).

Em uma migração homogênea de banco de dados, os esquemas dos bancos de origem e destino costumam ser idênticos. Se os esquemas forem diferentes, os dados dos bancos de origem precisarão ser transformados durante a migração.

A migração heterogênea de banco de dados é uma migração entre bancos de origem e destino com diferentes tecnologias de banco de dados, por exemplo, de um banco do Oracle para o Spanner. A migração heterogênea do banco de dados pode ser entre os mesmos modelos de dados (por exemplo, de relacional para relacional) ou entre modelos diferentes (por exemplo, de relacional para chave-valor).

A migração entre diferentes tecnologias de banco de dados não envolve necessariamente modelos de dados diferentes. Por exemplo, Oracle, MySQL, PostgreSQL e Spanner são compatíveis com o modelo relacional de dados. No entanto, bancos de dados de vários modelos, como Oracle, MySQL ou PostgreSQL, são compatíveis com diferentes modelos de dados. Dados armazenados como documentos JSON em um banco de dados com vários modelos podem ser migrados para o MongoDB com pouca ou nenhuma transformação, já que o modelo de dados é o mesmo nos bancos de origem e destino.

Embora a diferença entre migração homogênea e hierárquica seja baseada nas tecnologias de banco de dados, também é possível categorizar de acordo com os modelos de banco de dados envolvidos. Por exemplo, uma migração de um banco de dados Oracle para o Spanner é homogênea quando ambos usam o modelo relacional de dados. Por exemplo, se dados armazenados como objetos JSON no Oracle forem migrados para um modelo relacional no Spanner, a migração será heterogênea,

A categorização de migrações por modelo de dados expressa com mais precisão a complexidade e o esforço necessários para migrar dados do que a categorização por sistema de banco de dados. No entanto, como a categorização mais usada no setor é baseada nos sistemas de banco de dados envolvidos, as seções restantes serão baseadas nessa distinção.

Inatividade da migração: zero, mínima ou significativa

Depois de migrar um conjunto de dados do banco de origem para o de destino, altere o acesso do cliente para o banco de destino e exclua o de origem.

A transferência de clientes dos bancos de dados de origem para os de destino envolve vários processos:

  • Para continuar o processamento, os clientes precisam encerrar as conexões atuais com os bancos de dados de origem e criar novas conexões com os de destino. O ideal é encerrar as conexões, o que significa que você não reverterá desnecessariamente as transações em andamento.
  • Depois de encerrar as conexões nos bancos de dados de origem, você precisa migrar as alterações restantes dos bancos de dados de origem para os de destino (processo chamado de diminuição) para garantir que todas as alterações sejam capturadas.
  • Talvez seja necessário testar bancos de dados de destino para garantir que eles estejam funcionando e que os clientes também estejam funcionando dentro dos objetivos de nível de serviço (SLOs) definidos.

É impossível atingir um tempo de inatividade zero em uma migração para os clientes, porque há momentos em que eles não podem processar solicitações. No entanto, há várias maneiras de minimizar o período em que os clientes não conseguem processar solicitações (tempo de inatividade próximo de zero):

  • Inicie seus clientes de teste no modo somente leitura para os bancos de dados de destino muito antes de transferir os clientes. Nessa abordagem, os testes são simultâneos à migração.
  • É possível configurar a quantidade de dados que estão sendo migrados (ou seja, em trânsito entre os bancos de dados de origem e destino) para que seja a menor possível quando a transferência estiver mais próxima. Essa etapa reduz o tempo de diminuição porque há menos diferenças entre os bancos de dados de origem e destino.
  • Quando novos clientes que operam nos bancos de dados de destino são iniciados simultaneamente com clientes atuais que operam nos bancos de origem, o tempo de transferência é reduzido porque os novos clientes estarão prontos para a execução assim que todos os dados forem diminuídos.

Embora não seja realista atingir zero inatividade durante uma transferência, é possível minimizá-la iniciando atividades simultaneamente com a migração de dados em andamento, quando possível.

Em alguns cenários de migração de banco de dados, um tempo de inatividade significativo é aceitável. Normalmente, isso é resultado de requisitos comerciais. Nesses casos, a abordagem pode ser simplificada. Por exemplo, com uma migração homogênea de banco de dados, talvez não seja necessário modificar os dados. Exportar/importar ou fazer backup/restaurar são abordagens perfeitas. Com migrações hierárquicas, o sistema de migração de banco de dados não precisa lidar com atualizações de sistemas de banco de dados de origem durante a migração.

No entanto, você precisa estabelecer que a inatividade aceitável seja longa o suficiente para realizar a migração do banco de dados e o teste de acompanhamento. Se essa inatividade não puder ser estabelecida claramente ou for longa demais, você precisará planejar uma migração que envolva uma inatividade mínima.

Cardinalidade da migração de banco de dados

Em muitas situações, a migração de banco de dados ocorre entre um banco de origem e um de destino. Nessas situações, a cardinalidade é 1:1 (mapeamento direto). Ou seja, um banco de dados de origem é migrado sem alterações para um de destino.

No entanto, o mapeamento direto não é a única possibilidade. Veja outras cardinalidades:

  • Consolidação (n:1). Em uma consolidação, você migra dados de vários bancos de origem para um número menor de bancos de destino (ou até mesmo um destino). Use essa abordagem para simplificar o gerenciamento de bancos de dados ou usar um banco de dados de destino que possa ser escalonado.
  • Distribuição (1:n). Em uma distribuição, você migra dados de um banco de origem para vários bancos de destino. Por exemplo, é possível usar essa abordagem ao migrar um banco de dados centralizado grande com dados regionais para vários bancos de destino regionais.
  • Redistribuição (n:m). Em uma redistribuição, você migra dados de vários bancos de origem para vários bancos de destino. Use essa abordagem quando tiver bancos de dados de origem com fragmentos de tamanhos muito diferentes. A redistribuição divide uniformemente os dados fragmentados em vários bancos de dados de destino que representam os fragmentos.

A migração do banco de dados oferece uma oportunidade de reformular e implementar a arquitetura do banco, além de simplesmente migrar dados.

Consistência da migração

A expectativa é que a migração de banco de dados seja consistente. No contexto da migração, consistente significa o seguinte:

  • Completa. Todos os dados que deveriam ser migrados, foram. Esses dados podem incluir todos os dados de um banco de origem ou um subconjunto deles.
  • Sem duplicatas. Cada dado é migrado somente uma vez. Nenhum dado duplicado é introduzido no banco de dados de destino.
  • Ordenada. As alterações de dados no banco de origem são aplicadas ao banco de destino na mesma ordem em que ocorreram no de origem. Esse aspecto é essencial para garantir a consistência dos dados.

Uma alternativa para descrever a consistência da migração é que, após a conclusão do processo, o estado de dados entre os bancos de origem e destino é equivalente. Por exemplo, em uma migração homogênea que envolve o mapeamento direto de um banco de dados relacional, as mesmas tabelas e linhas precisam existir nos bancos de dados de origem e destino.

Essa maneira alternativa de descrever a consistência da migração é importante porque nem todas as migrações de dados são baseadas na aplicação sequencial de transações no banco de dados de origem. Por exemplo, é possível fazer backup do banco de dados de origem e usá-lo para restaurar o conteúdo do banco de origem no banco de destino (quando o tempo de inatividade for significativo).

Diferenças entre migração "ativo-passivo" e "ativo-ativo"

Uma distinção importante é se os bancos de dados de origem e destino estão aptos a modificar o processamento de consultas. Em uma migração de banco de dados "ativo-passivo", os bancos de origem podem ser modificados durante a migração, enquanto os de destino permitem apenas acesso somente leitura.

Uma migração "ativo-ativo" é compatível com clientes que gravam no banco de dados de origem e destino durante a migração. Nesse tipo de migração, podem ocorrer conflitos. Por exemplo, se o mesmo item de dados do banco de origem e de destino for modificado de modo a entrarem em conflito semanticamente, talvez seja necessário executar regras de resolução de conflitos.

Em uma migração "ativo-ativo", é necessário resolver todos os conflitos de dados usando regras de resolução de conflitos. Se isso não for possível, talvez haja inconsistência de dados.

Arquitetura de migração de banco de dados

Uma arquitetura de migração de banco de dados descreve os vários componentes necessários para executar uma migração de banco de dados. Nesta seção, apresentamos uma arquitetura de implantação genérica e trata o sistema de migração de banco de dados como um componente separado. Também discutimos os recursos de um sistema de gerenciamento de banco de dados compatível com a migração de dados, bem como propriedades não funcionais que são importantes para muitos casos de uso.

Arquitetura de implantação

Uma migração de banco de dados pode ocorrer entre bancos de origem e destino localizados em qualquer ambiente, como nuvens locais ou diferentes. Cada banco de dados de origem e destino pode estar em um ambiente diferente, não sendo necessário que todos estejam no mesmo ambiente.

O diagrama a seguir mostra um exemplo de arquitetura de implantação que envolve vários ambientes.

Arquitetura de migração que envolve data centers locais e na nuvem.

O DB1 e o DB2 são dois bancos de dados de origem, e o DB3 e o Spanner são os bancos de destino. Duas nuvens e dois data centers locais estão envolvidos nessa migração de banco de dados. As setas representam as relações de invocação: o serviço de migração de banco de dados invoca interfaces de todos os bancos de origem e destino.

Um caso especial não discutido aqui é a migração de dados de um banco para o mesmo banco. Esse caso especial usa o sistema de migração de banco de dados apenas para transformação de dados, não para migrar dados entre sistemas diferentes em ambientes diferentes.

Basicamente, há três abordagens para a migração de banco de dados discutidas nesta seção:

Sistema de migração de banco de dados

Um sistema adequado é a base da migração de banco de dados. O sistema executa a extração de dados real dos bancos de dados de origem, transporta os dados para os bancos de destino e, opcionalmente, modifica os dados durante a transferência. Nesta seção, discutimos a funcionalidade básica do sistema de migração de banco de dados em geral. Exemplos de sistemas de migração de banco de dados incluem Striim, tcVision e Cloud Data Fusion.

Processo de migração de dados

O principal elemento técnico de um sistema de migração de banco de dados é o processo de migração de dados. O processo de migração de dados é especificado por um desenvolvedor e define os bancos de dados de origem de onde os dados são extraídos, os bancos de destino para onde os dados são migrados e qualquer lógica de modificação de dados aplicada aos dados durante a migração.

É possível especificar um ou mais processos de migração de dados e executá-los sequencialmente ou simultaneamente, dependendo das necessidades da migração. Por exemplo, se você migrar bancos de dados independentes, os processos de migração de dados correspondentes poderão ser executados em paralelo.

Extração e inserção de dados

Há duas formas de identificar alterações (inserções, atualizações, exclusões) em um sistema de banco de dados: a captura de dados alterados (CDC) compatível com banco de dados e baseada no registro de transações e a consulta diferencial de dados usando a interface de consulta de um sistema de gerenciamento de banco de dados.

CDC baseada no registro de transações

A CDC compatível com banco de dados é baseada em recursos de gerenciamento de banco de dados separados da interface de consulta. Uma abordagem é baseada em registros de transações (por exemplo, o registro binário no MySQL). Um registro de transações contém as alterações feitas nos dados na ordem correta. O registro de transações é lido continuamente e, portanto, todas as alterações podem ser observadas. Essa geração de registros é extremamente útil para a migração do banco de dados, porque a CDC garante que cada alteração seja visível e, posteriormente, migrada para o banco de dados de destino sem perda e na ordem correta.

A CDC é a abordagem preferida para capturar alterações em um sistema de gerenciamento de banco de dados. A CDC é integrada ao próprio banco de dados e tem o menor impacto de carga no sistema.

Consultas diferenciais

Se não houver um recurso do sistema de gerenciamento de banco de dados compatível com a observação de todas as alterações na ordem correta, use a consulta diferenciada. Nessa abordagem, cada item de dados em um banco de dados recebe um atributo extra que contém um carimbo de data/hora ou um número sequencial. Sempre que o item de dados é alterado, o carimbo de data/hora da alteração é adicionado ou o número sequencial aumenta. Um algoritmo de pesquisa lê todos os itens de dados desde a última vez em que foi executado ou desde o último número sequencial usado. Depois que o algoritmo de pesquisa determina as alterações, ele registra o horário ou o número sequencial atual no estado interno e passa as alterações para o banco de dados de destino.

Embora essa abordagem funcione sem problemas para inserções e atualizações, você precisa projetar exclusões com cuidado, porque a exclusão remove um item de dados do banco de dados. Depois que os dados são excluídos, é impossível que o aplicativo de pesquisa detecte a exclusão. Você implementa uma exclusão usando um campo extra de status (uma sinalização lógica de exclusão) que indica que os dados foram excluídos. Como alternativa, os itens de dados excluídos podem ser coletados em uma ou mais tabelas, e o aplicativo de pesquisa acessa essas tabelas para determinar se ocorreu uma exclusão.

Para variantes em consultas diferenciais, consulte Captura de dados alterados.

Consultas diferenciais são a abordagem menos preferida porque envolvem alterações de esquema e funcionalidade. A consulta ao banco de dados também adiciona uma carga de consulta que não está relacionada à execução da lógica do cliente.

Adaptador e agente

O sistema de migração de banco de dados requer acesso à origem e aos sistemas de banco de dados. Adaptadores são a abstração que encapsula a funcionalidade de acesso. Na forma mais simples, um adaptador pode ser um driver JDBC para inserir dados em um banco de dados de destino compatível com JDBC. Em um caso mais complexo, um adaptador em execução no ambiente do destino (às vezes chamado de agente), acessando uma interface de banco de dados integrada, como arquivos de registro. Em um caso ainda mais complexo, um adaptador ou agente interage com outro sistema de software, que por sua vez acessa o banco de dados. Por exemplo, um agente acessa o Oracle GoldenGate, que por sua vez acessa um banco de dados Oracle.

O adaptador ou o agente que acessa um banco de dados de origem implementa a interface da CDC ou de consulta diferenciada, dependendo do design do sistema de banco de dados. Nos dois casos, o adaptador ou agente fornece alterações no sistema de migração de banco de dados e o sistema de migração de banco de dados não sabe se as alterações foram capturadas pela CDC ou pela consulta diferenciada.

Modificação dos dados

Em alguns casos de uso, os dados são migrados de bancos de origem para bancos de destino sem alterações. Essas migrações diretas geralmente são homogêneas.

No entanto, muitos casos de uso exigem que os dados sejam modificados durante o processo de migração. Normalmente, a alteração é necessária quando há diferenças no esquema ou nos valores de dados, ou oportunidades de limpar os dados durante a transição.

Nas seções a seguir, discutimos vários tipos de modificações que podem ser necessárias em uma migração de dados: transformação, enriquecimento ou correlação de dados e redução ou filtragem de dados.

Transformação de dados

A transformação de dados transforma alguns ou todos os valores de dados do banco de dados de origem. Veja alguns exemplos:

  • Transformação do tipo de dados. Às vezes, os tipos de dados entre bancos de dados de origem e destino não são equivalentes. Nesses casos, a transformação do tipo de dados converte o valor de origem no de destino de acordo com regras de transformação de tipo. Por exemplo, um tipo de carimbo de data/hora da origem pode ser transformado em uma string no destino.
  • Transformação da estrutura de dados. A transformação da estrutura de dados modifica a estrutura no mesmo modelo de banco de dados ou entre diferentes modelos de banco de dados. Por exemplo, em um sistema relacional, uma tabela de origem pode ser dividida em duas tabelas de destino ou várias tabelas de origem podem ser desnormalizadas em uma tabela de destino usando uma junção. Uma relação de 1:n no banco de dados de origem pode ser transformada em uma relação de pai/filho no Spanner. Os documentos de um sistema de banco de dados de origem podem ser divididos em um conjunto de linhas relacionais em um sistema de destino.
  • Transformação do valor de dados. A transformação do valor de dados é separada da transformação do tipo de dados. A transformação de valor de dados altera o valor sem alterar o tipo de dados. Por exemplo, um fuso horário local é convertido para o Horário Universal Coordenado (UTC). Ou um CEP curto (cinco dígitos) representado como uma string é convertido em um CEP longo (cinco dígitos seguidos por um traço e quatro dígitos, também conhecido como CEP+4).
Enriquecimento e correlação de dados

A transformação de dados é aplicada aos dados atuais sem referência a dados extras de referência relacionados. Com o enriquecimento de dados, os dados extras são consultados para enriquecer os dados de origem antes de serem armazenados no banco de destino.

  • Correlação de dados. Dados de origem podem ser correlacionados. Por exemplo, é possível combinar dados de duas tabelas em dois bancos de dados de origem. Em um banco de dados de destino, por exemplo, é possível relacionar um cliente a todos os pedidos abertos, atendidos e cancelados em que os dados do cliente e os do pedido se originam de dois bancos de dados diferentes.
  • Enriquecimento de dados. O enriquecimento de dados adiciona dados de referência. Por exemplo, é possível enriquecer registros que tenham apenas um CEP adicionando o nome da cidade correspondente a esse CEP. Uma tabela de referência com códigos postais e os nomes de cidade correspondentes é um conjunto de dados estático acessado para esse caso de uso. Os dados de referência também podem ser dinâmicos. Por exemplo, é possível usar uma lista de todos os clientes conhecidos como dados de referência.
Redução e filtragem de dados

Outro tipo de transformação de dados é a redução ou filtragem de dados de origem antes de migrá-los para um banco de dados de destino.

  • Redução de dados. A redução de dados remove atributos de um item de dados. Por exemplo, se o item de dados contiver um CEP, é possível que o nome da cidade correspondente não seja obrigatório e acabe descartado, seja porque ele pode ser recalculado ou porque não é mais necessário. Às vezes, essas informações são mantidas por motivos históricos para registrar o nome da cidade conforme inserido pelo usuário, mesmo que o nome da cidade seja alterado ao longo do tempo.
  • Filtragem de dados. A filtragem de dados remove completamente um item de dados. Por exemplo, todos os pedidos cancelados podem ser removidos e não transferidos para o banco de dados de destino.
Combinação ou recombinação de dados

Se os dados forem migrados de bancos de origem diferentes para bancos de destino diferentes, talvez seja necessário combinar dados de outra maneira entre os bancos de origem e destino.

Suponha que clientes e pedidos sejam armazenados em dois bancos de dados de origem diferentes. Um banco de dados de origem contém todos os pedidos e um segundo contém todos os clientes. Após a migração, os clientes e os respectivos pedidos são armazenados em uma relação 1:n em um esquema único de banco de dados de destino, mas não em um único banco de dados de destino, mas cada um contém uma partição dos dados. Cada banco de dados de destino representa uma região e contém todos os clientes e seus pedidos localizados nessa região.

Endereçamento do banco de dados de destino

A menos que haja apenas um banco de dados de destino, cada item de dados migrado precisa ser enviado para o banco de dados de destino correto. Algumas abordagens para abordar o banco de dados de destino incluem:

  • Endereçamento baseado em esquema. O endereçamento baseado em esquema determina o banco de dados de destino de acordo com o esquema. Por exemplo, todos os itens de dados de um conjunto de clientes ou todas as linhas de uma tabela de clientes são migrados para o mesmo banco de dados de destino que armazena informações dos clientes, mesmo que essas informações tenham sido distribuídas em vários bancos de dados de origem.
  • Roteamento baseado no conteúdo. O roteamento baseado em conteúdo (usando um roteador adequado a essa função, por exemplo) determina o banco de dados de destino com base em valores de dados. Por exemplo, todos os clientes localizados na região da América Latina são migrados para um banco de dados de destino específico que representa essa região.

É possível usar os dois tipos de endereçamentos simultaneamente em uma migração de banco de dados. Independentemente do tipo de endereçamento usado, o banco de dados de destino precisa ter o esquema correto para que os itens de dados sejam armazenados.

Persistência de dados em trânsito

Os sistemas de migração de banco de dados ou os ambientes em que são executados podem falhar durante uma migração e os dados em trânsito podem ser perdidos. Quando ocorrem falhas, é necessário reiniciar o sistema de migração do banco de dados e garantir que os dados armazenados no banco de origem sejam migrados de maneira consistente e completa para os bancos de destino.

Como parte da recuperação, o sistema de migração de banco de dados precisa identificar o último item de dados migrado para determinar onde começar a extrair os bancos de dados de origem. Para retomar no ponto de falha, o sistema precisa manter um estado interno no progresso da migração.

É possível manter o estado de várias maneiras:

  • Armazene todos os itens de dados extraídos no sistema de migração de banco de dados antes de realizar qualquer modificação do banco e remova o item de dados assim que a versão modificada for armazenada no banco de dados de destino. Essa abordagem garante que o sistema de migração de banco de dados possa determinar exatamente o que é extraído e armazenado.
  • Mantenha uma lista de referências com os itens de dados em trânsito. Uma possibilidade é armazenar as chaves primárias ou outros identificadores exclusivos de cada item de dados com um atributo de status. Após uma falha, esse estado é a base para recuperar o sistema de forma consistente.
  • Consulte os bancos de dados de origem e destino após uma falha para determinar a diferença entre os sistemas desses bancos. O próximo item de dados a ser extraído é determinado de acordo com a diferença.

Outras abordagens para manter o estado podem depender dos bancos de dados de origem específicos. Por exemplo, um sistema de migração de banco de dados pode acompanhar quais entradas de registro de transação são buscadas no banco de origem e quais são inseridas no banco de destino. Se houver uma falha, a migração poderá ser reiniciada a partir da última entrada inserida.

A persistência de dados em trânsito também é importante por outros motivos que não sejam erros ou falhas. Por exemplo, talvez não seja possível consultar dados do banco de origem para determinar o estado dele. Se, por exemplo, o banco de dados de origem continha uma fila, as mensagens nessa fila podem ter sido removidas em algum momento.

No entanto, outro caso de uso para a persistência de dados em trânsito é o processamento de dados em grandes janelas. Durante a modificação de dados, os itens podem ser transformados independentemente um do outro. No entanto, às vezes a modificação de dados depende de vários itens (por exemplo, numerar os itens de dados processados por dia, começando do zero todos os dias).

Um caso de uso final relacionado à persistência de dados em trânsito é fornecer repetibilidade dos dados durante a modificação quando o sistema de banco de dados não puder acessar os bancos de origem novamente. Por exemplo, talvez seja necessário executar novamente as modificações de dados com regras diferentes e, em seguida, verificar e comparar os resultados com as modificações iniciais de dados. Essa abordagem poderá ser necessária se você precisar acompanhar inconsistências no banco de dados de destino devido a uma modificação incorreta de dados.

Verificação de integridade e consistência

Você precisa verificar se a migração do banco de dados está completa e consistente. Essa verificação garante que cada item de dados seja migrado apenas uma vez, que os conjuntos de dados nos bancos de origem e destino sejam idênticos e que a migração seja concluída.

Dependendo das regras de modificação de dados, é possível que um item de dados seja extraído, mas não inserido em um banco de dados de destino. Por esse motivo, comparar diretamente os bancos de dados de origem e destino não é uma abordagem sólida para verificar a integridade e a consistência. No entanto, se o sistema de migração de banco de dados rastrear os itens filtrados, será possível comparar os bancos de dados de origem e destino com os itens filtrados.

Funcionalidade de replicação do sistema de gerenciamento de banco de dados

Um caso de uso especial em uma migração homogênea é quando o banco de dados de destino é uma cópia do banco de origem. Mais especificamente, os esquemas nos bancos de dados de origem e destino são os mesmos, os valores de dados são iguais, e cada banco de dados de origem é mapeado diretamente (1:1) a um banco de dados de destino.

Nesse caso, use a funcionalidade no sistema de gerenciamento de banco de dados para replicar um banco para outro. A replicação cria apenas uma cópia exata, ela não realiza a modificação de dados. Exemplos: replicação do MySQL, replicação do PostgreSQL (consulte também pdlogical) ou replicação do Microsoft SQL Server.

No entanto, se a modificação de dados for necessária ou você tiver qualquer cardinalidade diferente do mapeamento direto, será necessária a funcionalidade de um sistema de migração de banco de dados para lidar com esse caso de uso.

Funcionalidade de migração de banco de dados personalizada

Alguns motivos para criar a funcionalidade de migração de banco de dados em vez de usar um sistema de migração de banco de dados ou de gerenciamento de banco de dados incluem:

  • Você precisa ter controle total sobre cada detalhe.
  • Você quer reutilizar a funcionalidade.
  • Você quer reduzir custos ou simplificar a pegada tecnológica.

Os elementos básicos da funcionalidade de migração incluem:

  • Exportar/Importar. Se o tempo de inatividade não for um fator, use a exportação e a importação do banco de dados em migrações de banco de dados homogêneas. No entanto, a exportação/importação exige que você interrompa o banco de dados de origem para evitar atualizações antes de exportar os dados. Caso contrário, as alterações podem não ser capturadas na exportação e o banco de dados de destino não será uma cópia exata do banco de dados de origem.
  • Fazer backup/restaurar. Assim como no caso da exportação/importação, o backup/restauração gera inatividade porque você precisa interromper o banco de dados de origem para que o backup contenha todos os dados e as alterações mais recentes. O tempo de inatividade continua até que a restauração seja concluída com sucesso no banco de dados de destino.
  • Consultas diferenciais. Caso seja viável alterar o esquema do banco de dados, estenda o esquema para que as alterações do banco de dados possam ser consultadas na interface de consulta. Um atributo de carimbo de data/hora é adicionado, indicando a hora da última alteração. Também é possível adicionar outra sinalização de exclusão, indicando se o item de dados foi excluído ou não (exclusão lógica). Com essas duas alterações, um aplicativo de pesquisa em execução em um intervalo regular pode consultar todas as alterações desde a última execução. As alterações são aplicadas ao banco de dados de destino. Outras abordagens são discutidas em Captura de dados alterados.

Essas são apenas algumas das opções disponíveis para criar uma migração de banco de dados personalizada. Embora uma solução personalizada forneça mais flexibilidade e controle sobre a implementação, ela também requer manutenção constante para resolver bugs, limitações de escalonamento e outros problemas que podem surgir durante uma migração de banco de dados.

Outras considerações sobre a migração do banco de dados

Nas seções a seguir, discutimos rapidamente aspectos não funcionais que são importantes no contexto de migração de banco de dados. Esses aspectos incluem solução de erros, alta disponibilidade e recuperação de desastres.

Tratamento de erros

As falhas durante a migração de banco de dados não podem causar perda de dados ou o processamento de alterações do banco de dados fora de ordem. A integridade dos dados precisa ser preservada, independentemente do que causou a falha (como um bug no sistema, uma interrupção de rede ou uma falha de VM ou zona).

Uma perda de dados ocorre quando um sistema de migração recupera os dados dos bancos de origem e não os armazena nos bancos de destino devido a algum erro. Quando os dados são perdidos, os bancos de destino não correspondem aos de origem e, portanto, ficam inconsistentes e incompletos. A funcionalidade de verificação de integridade e consistência sinaliza esse estado (Verificação de integridade e consistência).

Escalonabilidade

Em uma migração de banco de dados, o tempo de migração é uma métrica importante. Em uma migração sem tempo de inatividade (no sentido de tempo de inatividade mínimo), a migração dos dados ocorre enquanto os bancos de dados de origem continuam mudando. Para migrar em um período razoável, a taxa de transferência de dados precisa ser significativamente mais rápida do que a taxa de atualizações dos sistemas de banco de dados de origem, especialmente quando o sistema é grande. Quanto maior a taxa de transferência, mais rápida será a migração do banco de dados.

Quando os sistemas de banco de dados de origem são interrompidos e não estão sendo modificados, a migração pode ser mais rápida porque não há alterações para serem incorporadas. Em um banco de dados homogêneo, o tempo de migração pode ser bastante rápido porque é possível usar a funcionalidade de backup/restauração ou exportação/importação, e a transferência de arquivos é escalonável.

Alta disponibilidade e recuperação de desastres

Em geral, bancos de dados de origem e destino são configurados para alta disponibilidade. O banco de dados primário tem uma réplica de leitura correspondente que é promovida para ser o primário quando ocorre uma falha.

Quando uma zona falha, os bancos de dados de origem ou de destino fazem o failover para uma zona diferente para ficarem continuamente disponíveis. Se houver uma falha de zona durante uma migração de banco de dados, o próprio sistema de migração será afetado porque vários dos bancos de origem ou de destino acessados ficarão inacessíveis. O sistema de migração precisa se reconectar aos bancos de dados primários recém-promovidos que estão em execução após a falha. Depois que o sistema de migração de banco de dados é reconectado, ele precisa recuperar a migração em si para garantir a integridade e consistência dos dados nos bancos de destino. O sistema de migração precisa determinar a última transferência consistente para determinar o ponto de retomada.

Se o próprio sistema de migração de banco de dados falhar (por exemplo, a zona em que ele é executado se tornar inacessível), ele precisará ser recuperado. Uma abordagem de recuperação é uma reinicialização a frio. Nessa abordagem, o sistema de migração de banco de dados é instalado em uma zona operacional e reiniciado. O maior problema a ser resolvido é que o sistema de migração precisa determinar a última transferência de dados consistente antes da falha e continuar a partir desse ponto para garantir a integridade e consistência dos dados nos bancos de destino.

Se o sistema de migração de banco de dados estiver ativado para alta disponibilidade, ele poderá fazer o failover e continuar o processamento. Caso seja importante limitar o tempo de inatividade do sistema de migração de banco de dados, selecione um banco de dados e implemente a alta disponibilidade.

Em termos de recuperação da migração de banco de dados, a recuperação de desastres é muito semelhante à alta disponibilidade. Em vez de se reconectar a bancos de dados primários recém-promovidos em uma zona diferente, o sistema de migração de banco de dados precisa se reconectar a bancos de dados em uma região diferente (uma região de failover). O mesmo vale para o próprio sistema de migração de banco de dados. Se a região em que o sistema de migração de banco de dados for executado se tornar inacessível, ele precisará fazer o failover para uma região diferente e continuar a partir da última transferência de dados consistente.

Armadilhas

Há várias armadilhas que podem causar dados inconsistentes nos bancos de dados de destino. Veja alguns exemplos comuns:

  • Violação da ordem. Se a escalonabilidade do sistema de migração for alcançada com o escalonamento horizontal, vários processos de transferência de dados serão executados simultaneamente (em paralelo). As alterações em um sistema de banco de dados de origem são ordenadas de acordo com as transações confirmadas. Se as alterações forem retiradas do registro de transações, a ordem precisará ser mantida durante a migração. A transferência de dados paralela pode alterar a ordem devido a variações de velocidade entre os processos subjacentes. É necessário garantir que os dados sejam inseridos nos bancos de dados de destino na mesma ordem em que são recebidos dos bancos de origem.
  • Violação de consistência. Com consultas diferenciais, os bancos de dados de origem têm atributos de dados extras que contêm, por exemplo, carimbos de data/hora de confirmação. Os bancos de dados de destino não terão carimbos de data/hora de confirmação porque esses carimbos são colocados apenas para estabelecer o gerenciamento de alterações nos bancos de dados de origem. É importante garantir que as inserções nos bancos de dados de destino sejam consistentes com o carimbo de data/hora, ou seja, todas as alterações com o mesmo carimbo de data/hora precisam estar na mesma inserção, atualização ou transação upsert. Caso contrário, o banco de dados de destino poderá ter um estado inconsistente (temporariamente) caso algumas alterações sejam inseridas e outras com o mesmo carimbo de data/hora não. Esse estado inconsistente temporário não importa se os bancos de dados de destino não forem acessados para processamento. No entanto, se eles forem usados para testes, a consistência será fundamental. Outro aspecto é a criação dos valores de carimbo de data/hora no banco de dados de origem e como eles se relacionam com o horário de confirmação da transação em que eles são definidos. Devido a dependências de confirmação de transação, uma transação com carimbo de data/hora anterior pode se tornar visível após uma transação com um carimbo de data/hora posterior. Se a consulta diferencial for executada entre as duas transações, ela não verá a transação com o carimbo de data/hora anterior, resultando em uma inconsistência no banco de dados de destino.
  • Dados ausentes ou duplicados. Quando ocorre um failover, é necessária uma recuperação cuidadosa caso alguns dados não sejam replicados entre o primário e a réplica de failover. Por exemplo, um banco de dados de origem faz failover e nem todos os dados são replicados para a réplica de failover. Ao mesmo tempo, os dados já foram migrados para o banco de dados de destino antes da falha. Após o failover, o banco de dados primário recém-promovido fica atrasado em termos de alterações no banco de dados de destino (chamado flashback). Um sistema de migração precisa reconhecer essa situação e se recuperar dela de forma que o banco de dados de destino e o de origem voltem a um estado consistente.
  • Transações locais. Para que os bancos de dados de origem e destino recebam as mesmas alterações, uma abordagem comum é fazer com que os clientes gravem nos bancos de dados de origem e destino em vez de usar um sistema de migração de dados. Essa abordagem tem várias armadilhas. Uma delas é que duas gravações de banco de dados são duas transações separadas. Talvez você encontre uma falha entre a conclusão da primeira e da segunda. Esse cenário causa uma inconsistência nos dados, que precisarão ser recuperados. Além disso, há vários clientes em geral e eles não são coordenados. Os clientes não sabem a ordem de confirmação da transação do banco de dados de origem e, portanto, não podem gravar nos bancos de destino que implementam essa ordem de transação. Os clientes podem alterar a ordem, o que pode levar à inconsistência de dados. A menos que todo acesso passe por clientes coordenados e todos os clientes garantam a ordem de transação de destino, essa abordagem pode levar a um estado inconsistente em relação ao banco de dados de destino.

Em geral, há outras armadilhas a serem observadas. A melhor maneira de encontrar problemas que possam levar à inconsistência de dados é fazer uma análise completa de falhas que itere todos os cenários de falha possíveis. Se a simultaneidade for implementada no sistema de migração de banco de dados, todas os pedidos de execução do processo de migração de dados precisarão ser examinados para garantir que a consistência dos dados seja preservada. Se a alta disponibilidade ou a recuperação de desastres (ou ambas) forem implementadas, todas as possíveis combinações de falhas precisarão ser examinadas.

A seguir