- O Postgres 18, atualmente em beta1, introduz suporte a I/O assíncrono (Asynchronous I/O), melhorando bastante especialmente o desempenho de leitura em ambientes de nuvem
- Com a nova configuração
io_method, agora é possível escolher além do modo sync tradicional, os modos worker e io_uring
- Segundo benchmarks na AWS, com
io_uring o desempenho de leitura em disco melhora em até 3 vezes
- Porém, com a assincronicidade, fica mais difícil interpretar os tempos de I/O na análise de consultas existente (
EXPLAIN ANALYZE)
- É necessário otimizar o desempenho com a nova view de monitoramento (
pg_aios) e o parâmetro de tuning effective_io_concurrency
Introdução de I/O assíncrono no Postgres 18
- Tradicionalmente, o Postgres usa um modelo de I/O bloqueante, esperando cada leitura de disco ser concluída
- A alta latência em storages baseados em rede (como EBS) causa gargalos em ambientes de nuvem
- O I/O assíncrono permite processar várias leituras de disco em paralelo, aumentando o uso de CPU e o throughput geral
Trabalho preparatório no Postgres 17: Read Stream API
- No Postgres 17, a API
read_stream foi introduzida para padronizar a abstração das operações de leitura
- Porém, ela ainda depende do cache de páginas do SO e não é refletida diretamente no shared buffer do próprio Postgres
- No Postgres 18, passa a ser possível fazer leituras assíncronas diretas, em vez de apenas hints ao kernel
Nova configuração: io_method
- O Postgres 18 adiciona a configuração
io_method ao postgresql.conf, oferecendo as 3 opções a seguir:
io_method = sync
- Mesmo modo síncrono do Postgres atual
- Usa um método de solicitação antecipada de leitura baseado em
posix_fadvise()
io_method = worker (padrão)
- Processos worker dedicados a I/O leem dados de forma assíncrona e os entregam ao shared buffer
- O processo principal pode continuar executando sem interromper a operação de leitura
- O número padrão de workers é 3, e pode ser ajustado com
io_workers
io_method = io_uring
- Interface de I/O de alto desempenho disponível no kernel Linux 5.1 ou superior
- Executa leituras assíncronas diretamente por meio de um ring buffer compartilhado com o kernel, sem processos worker
- Requer kernel, filesystem e configurações mais recentes
Benchmark de desempenho de I/O assíncrono (na AWS)
- Ambiente de teste:
- AWS c7i.8xlarge (32 vCPU, 64GB RAM)
- EBS io2 de 100GB, 20.000 IOPS
- Execução de
SELECT COUNT(*) em uma tabela de 3,5GB
Comparação de desempenho com cold cache:
| Versão/configuração |
Tempo de execução (ms) |
| Postgres 17 (sync) |
15,831 |
| Postgres 18 (sync) |
15,071 |
| Postgres 18 (worker) |
10,052 |
| Postgres 18 (io_uring) |
5,723 |
io_uring entrega ganho de desempenho de 2,8x em relação a sync
- É especialmente eficaz para reduzir a latência de disco na nuvem
Ajuste de effective_io_concurrency
- No Postgres 18, esse parâmetro influencia o número interno de requisições assíncronas de read-ahead
- O valor padrão foi elevado de 1 para 16, e multiplicado por
io_combine_limit define o alcance máximo de leitura
- Em ambientes de nuvem com alta latência, valores maiores podem ser vantajosos, mas é preciso benchmark por workload
Nova ferramenta de monitoramento: pg_aios
- Em
pg_stat_activity, durante operações assíncronas, isso aparece como evento AioIoCompletion, o que dificulta analisar a espera do backend
- No caso de
io_uring, como o kernel processa diretamente, o estado de I/O não fica visível no Postgres
- Pela view
pg_aios, é possível verificar detalhes das requisições assíncronas em andamento
SELECT * FROM pg_aios;
- É possível verificar estados como
SUBMITTED, COMPLETED_IO e informações sobre os blocos de destino
Atenção: mudança na interpretação das informações de tempo de I/O
- Os
I/O Timings mostrados em EXPLAIN ANALYZE só continuam confiáveis no modo síncrono
- Ao usar
worker ou io_uring com assincronicidade, a interpretação das informações de tempo fica distorcida por processamento paralelo e distribuição entre workers
- Para avaliar o esforço real de I/O, recomenda-se usar a contagem de buffers
shared read e o pg_aios
Conclusão
- O Postgres 18 traz ganhos reais de desempenho para workloads focadas em leitura
- Especialmente ao usar discos de alta latência em ambientes de nuvem, o benefício pode ser grande
- Ao mesmo tempo, será necessário reaprender a interpretar métricas, fazer tuning de desempenho e aplicar as configurações corretamente
- No futuro, o Postgres 19 também deve trazer suporte a escrita assíncrona
2 comentários
O Postgres é realmente o melhor, incrível.
Comentários do Hacker News
preadv2(..., RWF_NOWAIT)para realizar leituras assíncronas a partir do cache de páginas. Isso pode ser útil para reduzir a latência emio_method = workerNOWAITe só faz offload para uma thread de trabalho em caso de falhaaio(4)do FreeBSD, e seria interessante ver como ele funciona, já que não sofre das desvantagens doaiodo Linux/glibcio_uring, e foi levantada a questão de se muitos administradores ou distribuições Linux estão desativando esse recursoVACUUM ANALYZEcompgcronpgbouncer