Do PostgreSQL para o MariaDB: por que (e como) cada vez mais times estão fazendo essa troca
Vantagens reais de sair do PostgreSQL para o MariaDB e o passo a passo: mapa de tipos, conversão de schema, exportação em CSV, carga com LOAD DATA, validação e virada. Com o MariaDB olhando mais para o Brasil.

Vou ser honesto logo de cara: PostgreSQL é um banco excelente, e não vou fingir o contrário. Mas "excelente" não quer dizer "o melhor para o seu caso". Já vi muito time com PostgreSQL sofrendo com VACUUM, réplicas que exigem ferramenta de terceiros para virar cluster e pouca gente no mercado para operar. Para esses times, o MariaDB costuma ser uma troca que alivia. Bora ver por quê e, principalmente, como.
Por que considerar o MariaDB
- Sem VACUUM no seu caminho: o InnoDB guarda versões antigas no undo log e faz a limpeza (purge) em segundo plano. Não existe aquele bloat de tabela que pede manutenção agendada.
- Alta disponibilidade que vem na caixa: replicação nativa, semi-síncrona e o Galera Cluster multi-master, sem precisar montar Patroni, etcd e companhia.
- Vários motores na mesma instância: transacional, colunar, distribuído. Explico em os motores do MariaDB.
- IA nativa: tipo VECTOR e índice HNSW no próprio servidor. Veja MariaDB e IA.
- Recursos que você vai sentir falta… e que existem:
SEQUENCE,RETURNING, CTEs recursivas, window functions, tabelas temporais e tiposUUIDeINET6. - Mão de obra: quem conhece MySQL opera MariaDB. É, de longe, o perfil mais fácil de contratar no Brasil.
- O Brasil no radar: a MariaDB tem dado mais visibilidade e atenção ao mercado brasileiro, com presença de parceiros locais e um Ambassador no Brasil (esse que vos escreve) para encurtar a distância entre o seu problema e quem resolve.
Quando eu NÃO migraria
Se sua aplicação depende pesado de PostGIS avançado, extensões específicas, tipos ARRAY em todo canto ou PL/pgSQL gigante, a conta muda. Faça o inventário antes de se apaixonar.
O mapa da migração
1. Inventário → tabelas, tipos, funções, triggers, extensões
2. Schema → converter DDL (tabela de tipos abaixo)
3. Dados → COPY para CSV → LOAD DATA no MariaDB
4. Lógica → funções/triggers/procedures reescritas
5. Aplicação → driver, SQL específico, testes
6. Virada → janela curta ou carga incremental + corte
Passo 1: inventário no PostgreSQL
-- tipos usados
SELECT data_type, COUNT(*) FROM information_schema.columns
WHERE table_schema = 'public' GROUP BY data_type ORDER BY 2 DESC;
-- funções e triggers
SELECT proname FROM pg_proc p JOIN pg_namespace n ON n.oid = p.pronamespace
WHERE n.nspname = 'public';
-- extensões
SELECT extname FROM pg_extension;
Passo 2: tabela de tradução de tipos
| PostgreSQL | MariaDB | Observação |
|---|---|---|
| SERIAL / IDENTITY | INT AUTO_INCREMENT ou SEQUENCE | BIGSERIAL → BIGINT |
| BOOLEAN | BOOLEAN | Vira TINYINT(1); true/false funcionam |
| TEXT | TEXT / LONGTEXT | Para indexar, use VARCHAR ou prefixo |
| JSONB | JSON | No MariaDB é LONGTEXT validado |
| UUID | UUID | Tipo nativo desde 10.7 |
| INET | INET4 / INET6 | Nativos |
| TIMESTAMPTZ | TIMESTAMP / DATETIME | Padronize em UTC na aplicação |
| BYTEA | LONGBLOB | |
| ARRAY | JSON ou tabela filha | Tabela filha costuma ser melhor |
| NUMERIC(p,s) | DECIMAL(p,s) | Máx. 65 dígitos |
Passo 3: converter o schema
-- PostgreSQL
CREATE TABLE clientes (
id BIGSERIAL PRIMARY KEY,
uuid UUID NOT NULL DEFAULT gen_random_uuid(),
email TEXT UNIQUE NOT NULL,
ativo BOOLEAN DEFAULT true,
dados JSONB,
criado_em TIMESTAMPTZ DEFAULT now()
);
-- MariaDB
CREATE TABLE clientes (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
uuid UUID NOT NULL DEFAULT UUID(),
email VARCHAR(255) NOT NULL UNIQUE,
ativo BOOLEAN DEFAULT TRUE,
dados JSON CHECK (JSON_VALID(dados)),
criado_em TIMESTAMP DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
Dica: gere o DDL com pg_dump --schema-only e converta tabela por tabela. Ferramentas automáticas ajudam, mas sempre revise à mão.
Passo 4: mover os dados
# PostgreSQL → CSV
psql -d loja -c "\copy clientes TO 'clientes.csv' WITH (FORMAT csv, HEADER false, NULL '\N')"
-- CSV → MariaDB
LOAD DATA LOCAL INFILE 'clientes.csv'
INTO TABLE clientes
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
(id, uuid, email, @ativo, dados, criado_em)
SET ativo = (@ativo = 't');
Repare no truque do @ativo: o PostgreSQL exporta booleano como t/f. Datas com fuso também merecem atenção: exporte em UTC (SET TIME ZONE 'UTC' antes do \copy).
Depois de carregar, acerte o contador do AUTO_INCREMENT:
ALTER TABLE clientes AUTO_INCREMENT = 1000001; -- maior id + 1
Passo 5: lógica no banco
- Funções PL/pgSQL viram procedures/funções em SQL/PSM. Lógica simples, reescreva; lógica pesada, considere levar para a aplicação.
INSERT ... RETURNINGexiste no MariaDB. Veja RETURNING no MariaDB.ON CONFLICT DO UPDATEviraINSERT ... ON DUPLICATE KEY UPDATE.ILIKEviraLIKEcom collation_ci(já ignora maiúsculas).- Aspas duplas em identificadores: use crase, ou ative
SQL_MODE=ANSI_QUOTES.
Passo 6: validar
-- nos dois bancos
SELECT COUNT(*), MIN(id), MAX(id) FROM clientes;
SELECT SUM(LENGTH(email)) FROM clientes;
Rode os testes da aplicação e as consultas mais pesadas com EXPLAIN antes da virada. Planos de execução mudam, e índices que eram ótimos no PostgreSQL podem precisar de ajuste.
Resumo de bolso
- Migração lógica: schema convertido + CSV + LOAD DATA.
- Booleanos, fuso horário, JSONB e ARRAY são os pontos de atenção.
- O ganho: operação mais simples, HA nativa, mão de obra farta e suporte cada vez mais próximo do Brasil.
Para decidir com cabeça de CTO, leia até onde o MariaDB aguenta. Vindo do MySQL? Tem o guia de migração do MySQL. Tudo em /mariadb.
Sobre o autor: Alexandre Almeida é MariaDB Ambassador no Brasil, autor do livro Aprendendo MySQL e trabalha com bancos de dados há mais de 30 anos.
Fontes: MariaDB Knowledge Base: Data Types, UUID, INET6, LOAD DATA INFILE, SEQUENCE e InnoDB Purge (mariadb.com/kb). Documentação do PostgreSQL: COPY e Routine Vacuuming. Imagem: ilustração gerada por IA.