PostgreSQL e o Controle de Concorrência por Multiversão (MVCC)
Introdução
A arquitetura de concorrência de banco de dados é um dos pilares para garantir consistência, desempenho e escalabilidade. No PostgreSQL, o mecanismo responsável por isso é o chamado Multiversion Concurrency Control (MVCC) — “Controle de Concorrência por Multiversão”. Em linhas gerais, ele permite que múltiplas transações leiam e escrevam dados simultaneamente, de forma isolada, com o mínimo de bloqueios entre leitores e escritores.
Neste blog vamos destrinchar como o PostgreSQL implementa o MVCC, os componentes internos, os gatilhos de visibilidade e limpeza (garbage collection), além dos aspectos que o DBA sênior precisa conhecer para performance e tuning.
1. O que é MVCC e por que o PostgreSQL o usa
No modelo clássico de controle de concorrência baseado em bloqueios (“locks”), leituras podem travar escritas ou vice-versa, gerando contenção. Em contrapartida, o MVCC adota a ideia de que cada transação vê uma versão “snapshot” (instantâneo) do banco, isolada dos efeitos de transações concorrentes.
No PostgreSQL, isso significa:
- Quando uma transação inicia, ela “amarra” uma versão dos dados — ela verá apenas os registros válidos àquele ponto no tempo.
- Atualizações e deleções não sobrescrevem diretamente os dados existentes; em vez disso, criam-se novas versões (tuplas) enquanto as versões antigas continuam potencialmente visíveis para outras transações que as “herdaram”.
- Leitores não param escritores, escritores não bloqueiam leitores — esse é o grande ganho de concorrência.
2. Componentes internos essenciais do MVCC no PostgreSQL
Para entender como o PostgreSQL efetivamente implementa MVCC, precisamos conhecer os principais elementos envolvidos.
2.1 Colunas “ocultas” nas tuplas
Cada linha da tabela (tupla) no PostgreSQL carrega metadados internos que permitem determinar a visibilidade da versão daquela linha para cada transação:
xmin: ID da transação que inseriu ou modificou a tupla pela primeira vez.xmax: ID da transação que marcou a tupla para exclusão (ou atualização, via mecanismo de versão).- Além disso, há campos como
ctid, e em versões mais recentes, sistemas de congelamento (freeze) para IDs de transação grandes.
Com esses IDs, o PostgreSQL pode, ao satisfazer uma consulta, verificar se uma tupla é visível àquela transação ou se deve ser ignorada.
2.2 Snapshots e visibilidade de tuplas
Quando uma transação começa (por exemplo, sob o nível de isolamento Read Committed ou Repeatable Read/Serializable), o PostgreSQL registra um snapshot do banco: quais transações estão ativas, quais foram concluídas, etc. A partir daí, ao ler uma linha, o banco aplica regras de visibilidade para decidir se a tupla é válida para aquela transação. Exemplos de regra:
- Uma tupla com
xminmenor ou igual ao ID da transação corrente (ou dentro do snapshot permitido) pode ser visível. - Uma tupla cujo
xmaxseja zero ou maior que o limite de visibilidade também pode ser visível, dependendo do estado. - Versões “mortas” ou versões criadas por transações ainda não confirmadas ficam ocultas.
Por exemplo, se a transação T1 inseriu uma linha e ainda não fez COMMIT, a transação T2 não verá essa linha. Após T1 fazer COMMIT, futuras transações poderão ver essa linha. Isso evita leituras “sujas” (dirty reads) e resultantes de undo incerto.
2.3 Versão de linha com atualização (tuple versioning)
Quando uma linha é atualizada no PostgreSQL:
- A nova versão da tupla é inserida com um novo
xmin(ID da transação que faz o UPDATE). - A tupla antiga permanece, com seu
xmaxmarcado como o ID que “matou” a versão antiga. - Dependendo da visibilidade, transações que estavam ativas antes da atualização podem ainda ver a versão antiga; outras, que começam depois, verão a nova.
Portanto, multiversão é essencial para o MVCC funcionar.
3. Exemplos práticos / Diagnóstico para DBAs
Aqui vão alguns exemplos que ajudam a visualizar o que está rolando “por baixo”.
3.1 Inspeção de xmin/xmax
SELECT ctid, xmin, xmax, *
FROM minha_tabela
LIMIT 10;Você verá colunas ocultas, como xmin (ID da transação que criou a tupla) e xmax (ID que removeu ou invalidou) — isso confirma visualmente como o MVCC está funcionando.
3.2 Identificar bloat por versões mortas
Em ambientes com muitas atualizações/deleções, você pode ver:
- Muitas páginas parcialmente vazias
- Índices muito maiores do que deveriam
- Tabelas com muitos registros “mortos” (dead tuples), o que reduz eficiência de I/O e aumenta tempos de acesso
3.3 Tuning e manutenção
O que observar:
- Frequência e eficácia do autovacuum: se autovacuum não está mantendo o backlog de dead tuples, bloat cresce
- Tempo de leitura e leitura de páginas vazias ou não utilizadas
- Uso de índices e se eles estão sendo escaneados eficientemente ou contêm muitas versões obsoletas
- Em servidores de alta escrita (big OLTP), considerar ajustes de vacuum, checkpoints e parâmetros como
max_fsm_pages,maintenance_work_mem, etc.
Conclusão
O MVCC no PostgreSQL é um elemento fundamental da arquitetura que possibilita alta concorrência, consistência transacional (ACID) e performance em ambientes multiusuário. Compreender como funciona — desde a criação de tuplas, passando por snapshots e visibilidade, até o ciclo de limpeza — é essencial para qualquer DBA sênior que precise operar bancos de dados PostgreSQL em produção e em escala.
Contudo, não basta “saber que existe”: é preciso monitorar, tunar e manter para que o MVCC não se torne um gargalo (por exemplo, via bloat ou manutenção atrasada).
Quer conhecer mais sobre o PostgreSQL?
Acesse plataforma de cursos da 4Linux e veja nosso treinamento de banco de dados focado em PostgreSQL. Ele aborda diversos temas focado nas melhores práticas desde instalação, backup, replicação e alta disponibilidade.
About author
Você pode gostar também
E agora, o que fazer com os índices que não são usados?
Encontrar o índice ideal para sua nem sempre é tarefa fácil. Normalmente envolve tentativa e erro para encontrar uma boa combinação de índices. Existem diversas ferramentas que podem “salvar o
Acesso a dados SQL Server através do PostgreSQL: um guia prático
Tenho um PostgreSQL e preciso acessar dados que estão no SQL Server! E agora?! Não! Não precisa entrar em pânico! Existe uma solução para isso. Digamos que em um determinado
Monitoramento de Banco de Dados com o PMM da Percona
O que é o PMM? O Percona Monitoring and Management (PMM) é uma solução open source para observabilidade, monitoramento e gerenciamento de bancos de dados, com suporte a MySQL/MariaDB, PostgreSQL






