Migração de dados de MySQL e MariaDB para PostgreSQL, com sincronia até a virada

Migrate · · 8 min de leitura

Vai migrar de MySQL ou MariaDB para PostgreSQL? O dbSlice copia as tabelas por um app Windows ou pela linha de comando, e depois mantém o PostgreSQL sincronizado com o MySQL enquanto a aplicação antiga ainda está rodando, para a troca acontecer quando você estiver pronto, e não numa noite longa.

dbSlice ou pgloader?

O pgloader é um carregador de linha de comando gratuito e sólido, e para uma carga única feita por alguém à vontade com a linguagem de configuração dele é uma boa escolha. O dbSlice é para equipes que querem:

  • uma interface Windows com prévia dos dados, diferença chave a chave e conferências na tela antes de gravar;
  • execuções repetidas: sincronias Upsert ou só de linhas novas toda noite até a virada, e não uma carga única;
  • a mesma ferramenta para outros pares (SQL Server, Oracle, Firebird, SQLite, InterSystems IRIS);
  • mascaramento no caminho para cópias de desenvolvimento e teste.

Os dois movem dados. Nenhum converte stored procedures, triggers ou views.

Veja a comparação completa entre dbSlice e pgloader.

Comparando ferramentas? Veja as melhores ferramentas para migrar MySQL para PostgreSQL →

Aba Synchronize do dbSlice

Isso é replicação?

Não no sentido de replicação por log. O dbSlice roda sincronias agendadas: jobs Upsert ou só de linhas novas que deixam o PostgreSQL perto do MySQL toda noite (ou toda hora) até a virada. Se você precisa de replicação contínua, segundo a segundo, use uma ferramenta de CDC para essa parte; o dbSlice continua ajudando na carga inicial e nas conferências chave a chave. Mais em initial load + scheduled catch-up or CDC? (em inglês)

Fluxo da migração: planejar, levantar e desenhar com a sua equipe; carga inicial, atualização agendada e validação chave a chave com o dbSlice; virada depois que as conferências passam.
Onde o dbSlice entra numa migração de MySQL para PostgreSQL. Guia completo (em inglês): Data migration strategy.

O que o dbSlice faz

  • Conecta no MySQL e no MariaDB sem nada extra para instalar.
  • Lê em lotes pequenos, para o banco em uso continuar atendendo os usuários.
  • Grava no PostgreSQL em massa nas cargas iniciais e completas.
  • Mostra o DDL do destino. Se a tabela não existe no PostgreSQL, o dbSlice para antes de gravar e mostra um CREATE TABLE traduzido do MySQL para o seu DBA revisar e rodar. Ele não cria objetos nos seus bancos por conta própria.
  • Protege os ids. Depois que as linhas são copiadas com os ids AUTO_INCREMENT, a sequence do PostgreSQL pode ficar atrás do maior id. O dbSlice avisa e mostra o comando para avançá-la.
  • Exportar em vez de carregar: quando você só precisa de um arquivo, o mesmo app exporta uma tabela do MySQL ou do MariaDB para CSV, JSON, XML ou HTML.

Como os tipos de coluna são sugeridos

Quando a tabela não existe no PostgreSQL, o dbSlice mostra um CREATE TABLE para o seu DBA revisar. Esta é a tradução que ele sugere hoje:

MySQL / MariaDBSugerido no PostgreSQLRevise antes de rodar
TINYINT(1)BOOLEANUsado como número (valores 2, 3…)? Troque para SMALLINT
TINYINT, SMALLINTSMALLINT—
SMALLINT UNSIGNEDINTEGER—
INT, MEDIUMINTINTEGER—
INT UNSIGNED, MEDIUMINT UNSIGNEDBIGINT—
BIGINTBIGINT—
BIGINT UNSIGNEDNUMERIC(20,0)—
BIT, BOOLBOOLEAN—
DECIMAL(p,s)NUMERIC(p,s)—
FLOAT, DOUBLEDOUBLE PRECISION—
DATETIME, TIMESTAMPTIMESTAMPAcrescente WITH TIME ZONE se a sua aplicação espera isso
DATE, TIMEDATE, TIMEDatas zeradas: veja abaixo
CHAR(n), VARCHAR(n)VARCHAR(n)O preenchimento do CHAR não é mantido
TINYTEXT … LONGTEXTTEXT—
BINARY, VARBINARY, BLOBBYTEA—
JSONJSONBNo MariaDB chega como TEXT: veja abaixo
ENUM, SET, YEAR, tipos espaciaisTEXTAcrescente um CHECK, um tipo enum, ou SMALLINT para o YEAR

É um ponto de partida, não um esquema final: chaves, índices e constraints ficam por sua conta.

Migrar de MySQL para PostgreSQL: quatro detalhes para planejar

1. Inteiros sem sinal. O PostgreSQL não tem tipos sem sinal; por isso, o dbSlice lê o tipo declarado no MySQL e sugere um maior, em que o maior valor caiba: SMALLINT UNSIGNED → INTEGER, INT UNSIGNED e MEDIUMINT UNSIGNED → BIGINT, BIGINT UNSIGNED → NUMERIC(20,0).

2. Booleanos TINYINT(1). São sugeridos como BOOLEAN, e o dbSlice converte 0/1 em false/true. Um TINYINT(1) usado como número (valores 2, 3…) chegaria como true: troque essa coluna para SMALLINT no CREATE TABLE antes de rodar.

3. Datas zeradas. O MySQL aceita 0000-00-00, que o PostgreSQL rejeita. O dbSlice lê uma data zerada como NULL, sem mudar nada no MySQL; por isso, a coluna de destino precisa aceitar NULL.

4. ENUM, SET e YEAR. São sugeridos como TEXT. Mantenha assim, ou acrescente você mesmo uma constraint CHECK ou um tipo enum do PostgreSQL; YEAR costuma ficar melhor como SMALLINT.

Migrar de MariaDB para PostgreSQL: o que é diferente

O dbSlice conecta no MariaDB com os mesmos passos do MySQL, e a maioria dos tipos é traduzida do mesmo jeito. O MariaDB tem alguns tipos próprios que mudam o CREATE TABLE sugerido:

  • JSON chega como TEXT. No MariaDB, JSON é um apelido de LONGTEXT com verificação de validade, e o servidor informa a coluna como longtext. Por isso, o dbSlice sugere TEXT. Troque para JSONB no CREATE TABLE se quiser consultá-la como JSON no PostgreSQL.
  • UUID (MariaDB 10.7 em diante) vira sem surpresa o UUID do PostgreSQL.
  • INET4 e INET6 são sugeridos como TEXT. O PostgreSQL tem um tipo nativo INET; declare-o no CREATE TABLE se você filtra ou ordena por endereço.
  • Sequences. O MariaDB pode gerar ids a partir de um objeto SEQUENCE em vez de AUTO_INCREMENT. Nos dois casos, depois da cópia, a sequence do PostgreSQL precisa passar do maior id. Marque "Adjust the id generator afterwards", ou rode o comando que o dbSlice mostra.
  • Conjunto de caracteres. Tabelas antigas do MariaDB costumam usar utf8mb3 ou latin1. O PostgreSQL guarda tudo em UTF8; o erro de texto em "Erros comuns" vale do mesmo jeito.

Converter SQL e procedures do MySQL para PostgreSQL

O dbSlice move os dados; consultas, views e procedures precisam de uma passada própria. As mudanças de sempre:

MySQL / MariaDBPostgreSQL
`crases`"aspas duplas" (ou nada, em minúsculas)
IFNULL(a, b)COALESCE(a, b)
LIMIT 20, 10LIMIT 10 OFFSET 20
INSERT … ON DUPLICATE KEY UPDATEINSERT … ON CONFLICT (key) DO UPDATE
GROUP_CONCAT(x)string_agg(x, ',')
AUTO_INCREMENTGENERATED … AS IDENTITY (ou SERIAL)
NOW()now() (um timestamptz)
DATE_FORMAT(d, '%Y-%m')to_char(d, 'YYYY-MM')
Comparações sem diferenciar maiúsculas por padrãoDiferencia maiúsculas: use ILIKE ou lower()
Procedures na sintaxe do MySQLFunções/procedures em PL/pgSQL

Teste o código convertido no PostgreSQL com dados reais carregados pelo dbSlice antes de trocar a aplicação.

Erros comuns e o que significam

  • null value in column … violates not-null constraint numa coluna de data — uma data zerada, lida como NULL, numa coluna NOT NULL. Aceite NULL nessa coluna, como acima.
  • value out of range for type integer — um valor acima de 2.147.483.647 numa coluna criada como INTEGER, por exemplo uma coluna INT UNSIGNED cujo tipo foi trocado à mão no CREATE TABLE. Aumente a coluna para BIGINT.
  • duplicate key value violates unique constraint … _pkey depois da cópia — a sequence está atrás do maior id. Rode o comando que o dbSlice mostra, ou marque "Adjust the id generator afterwards" antes da execução, se o seu usuário puder alterar a sequence.
  • invalid byte sequence for encoding UTF8 — a coluna do MySQL guarda texto em outro charset (muitas vezes latin1 guardado como utf8). O dbSlice copia o texto como o driver do MySQL o devolve; ele não conserta texto guardado no charset errado. Corrija a coluna de origem, ou leia por um SELECT com CONVERT.

Passo a passo: converter uma tabela de MySQL ou MariaDB para PostgreSQL

  1. Conecte no MySQL ou no MariaDB e no PostgreSQL.
  2. Escolha a tabela de origem (ou um SELECT) e a tabela de destino.
  3. Escolha a coluna-chave usada para casar as linhas.
  4. Escolha o modo: Initial load na primeira vez, depois Upsert ou Insert new.
  5. Confira antes de gravar: o Record Diff compara as chaves dos dois lados.
  6. Rode, ou salve como job e agende pela CLI. O Replicador copia uma lista de tabelas numa execução, as pais antes das filhas.

Mantenha os dois sincronizados até a virada

Agende um job Upsert toda noite. Com uma coluna que só cresce (updated_at ou o id AUTO_INCREMENT), cada execução lê só as linhas acima do último valor visto. Exclusões no MySQL não são detectadas pelas execuções incrementais; por isso, planeje uma comparação completa ou uma recarga antes da troca.

Vai migrar do MariaDB com sincronia contínua durante a virada? Rode a sincronia incremental (por uma coluna updated_at ou de sequence, com uma janela de releitura) num agendamento até a troca, e depois rode o Compare chave a chave antes da virada. É uma sincronia em lote repetida, não replicação em tempo real.

Perguntas frequentes

O dbSlice converte stored procedures, triggers ou views?

Não. Ele move dados. Converta o código à mão ou com um conversor, e use o dbSlice para os dados e a sincronia até a virada.

Posso manter o MySQL rodando enquanto migro?

Sim. O dbSlice lê em lotes pequenos, e execuções noturnas Upsert ou só de linhas novas mantêm o PostgreSQL perto do MySQL até você trocar.

Ele cria as tabelas no PostgreSQL?

Não por padrão. Ele para antes de gravar e mostra um CREATE TABLE para o seu DBA revisar e rodar.

E as linhas excluídas?

As execuções incrementais não enxergam exclusões. Planeje uma comparação completa (Record Diff) ou uma recarga antes da troca.

Posso testar antes de comprar?

Sim. A versão gratuita da Microsoft Store não precisa de chave de licença; gravar num banco de destino exige uma licença Desktop ou Server.

Existe ferramenta gratuita para migrar MySQL para PostgreSQL?

O pgloader é gratuito e open source e bom para uma carga única. A versão gratuita do dbSlice na Microsoft Store não precisa de chave de licença; gravar no PostgreSQL exige uma licença Desktop ou Server.

Funciona no Windows?

Sim. O dbSlice é um app Windows com linha de comando; a Linux Server Edition roda no Docker.

Funciona com MariaDB?

Sim, com os mesmos passos. As colunas JSON do MariaDB chegam como TEXT; veja "Migrar de MariaDB para PostgreSQL" acima.

Mover dados entre MySQL, MariaDB e PostgreSQL, com qualquer um deles como origem

Vai mover dados no outro sentido? PostgreSQL para MySQL e MariaDB.

MySQL ou MariaDB para SQL Server, Oracle, Firebird, SQLite ou InterSystems IRIS, e PostgreSQL de volta para o MySQL. Veja também SQL Server para MySQL, SQL Server para PostgreSQL, Firebird para PostgreSQL e Oracle para PostgreSQL. Vindo do SQLite? Veja SQLite para PostgreSQL.

Ainda não usa o dbSlice?
Experimente a versão gratuita da Microsoft Store: ela conecta, navega pelos dados, compara estruturas e exporta para CSV.

Experimente grátis Veja as demonstrações

Em produção há mais de 6 anos · Garantia de 14 dias · Roda na sua máquina