Configure a VM de banco de dados no Proxmox: VirtIO SCSI, IO thread, cache, volblocksize do ZFS, por que evitar sync=disabled e teste com fio.

Para que serve

Rodar banco de dados em VM no Proxmox é o cenário mais comum entre os clientes de servidor dedicado: MySQL, PostgreSQL ou SQL Server em uma VM sobre os NVMe espelhados com ZFS. O desempenho e a segurança dos dados dependem de alguns detalhes da VM e do storage que o assistente de criação não pergunta. Este artigo reúne as configurações recomendadas e explica o que não fazer, como desligar o sync do ZFS.

Este artigo parte de um pool ZFS espelhado já criado. Se ainda não tem, veja Armazenamento no Proxmox: ZFS espelhado nos NVMe ou LVM-thin? na categoria Virtualização.

Pré-requisitos

  • Proxmox VE 8.x ou 9.x com um pool ZFS nos NVMe (nos exemplos, chamado nvme).
  • Acesso root ao shell do Proxmox.
  • Para VMs existentes: janela para desligar a VM e backup recente.

1. Hardware virtual do banco de dados em VM no Proxmox

OpçãoRecomendado para bancoPor quê
Controladora SCSIVirtIO SCSI singleUma controladora por disco, permitindo uma thread de I/O dedicada para cada.
Disco: BusSCSISuporta discard e IO thread com bom desempenho.
Disco: IO threadLigadoTira o I/O do disco da thread principal da VM.
Disco: CacheDefault (No cache)Escritas confirmadas pelo guest chegam de fato ao storage; não duplica cache com o ARC.
Disco: Discard / SSD emulationLigadosLibera espaço no ZFS quando o guest apaga dados (TRIM).
CPU: Typehost (se não houver migração entre CPUs diferentes)Expõe todas as instruções do processador (AES, AVX).
Memória: BallooningDesligadoBanco dimensiona cache pela RAM vista no boot; tirar memória dele causa swap.
NUMALigado em servidores com 2 soquetes e VMs grandesPermite ao guest e ao banco respeitar a localidade de memória.

Pelo shell (exemplo com VM 110):

qm set 110 --scsihw virtio-scsi-single --cpu host --balloon 0 --numa 1
qm set 110 --scsi1 nvme-db:200,iothread=1,discard=on,ssd=1

Para VM Windows (SQL Server), instale os drivers virtio-win antes de mudar o barramento do disco do sistema.

Evite o cache "unsafe" e pense bem antes de usar "writeback": nesses modos o host confirma a escrita antes de gravá-la, e uma queda de energia ou travamento do host pode corromper o banco. Para dados que importam, mantenha o padrão.

2. Escolha o tamanho de bloco do ZFS (volblocksize)

Os discos das VMs em ZFS são zvols, e o tamanho de bloco deles (volblocksize) é definido na criação e não pode ser mudado depois. O Proxmox VE 8 passou a usar 16K como padrão. Comparação com as páginas dos bancos:

  • MySQL/MariaDB (InnoDB): página de 16K. O padrão 16K combina bem.
  • PostgreSQL: página de 8K. 16K funciona e comprime melhor; 8K reduz amplificação em escrita aleatória pequena. Teste com sua carga.
  • SQL Server: páginas de 8K agrupadas em extents de 64K; 16K a 64K são usados na prática.

Para ter discos com bloco específico, crie um storage separado apontando para um dataset próprio:

zfs create nvme/db
zfs set compression=lz4 nvme/db
pvesm add zfspool nvme-db --pool nvme/db --blocksize 16k --content images --sparse 1
# confira um disco criado nele
zfs get volblocksize nvme/db/vm-110-disk-1

Para mudar o bloco de um disco existente, crie um disco novo no storage certo e mova os dados (pela opção Move disk da VM para outro storage, que recria o zvol com o bloco do destino).

3. recordsize: só para dados direto em dataset

recordsize vale para datasets (arquivos), não para zvols. Ele importa quando o banco roda em container LXC ou direto no host, com os arquivos em um dataset ZFS:

zfs create -o recordsize=16k -o compression=lz4 -o atime=off -o xattr=sa nvme/mysql-data
zfs create -o recordsize=16k -o compression=lz4 -o atime=off -o xattr=sa nvme/pg-data

Para PostgreSQL, muitos usam 8K a 16K; para logs e WAL, o padrão 128K serve. O recordsize só se aplica a arquivos gravados depois da mudança.

4. Não desligue o sync do ZFS

Bancos de dados chamam fsync a cada commit para garantir que a transação confirmada sobreviva a uma queda. Com zfs set sync=disabled, o ZFS ignora esse pedido: os benchmarks ficam lindos, mas em queda de energia, pânico do kernel ou reset pelo IPMI você perde os últimos segundos de transações que a aplicação já considerava gravadas. Réplicas e sistemas integrados ficam inconsistentes com o primário.

Recomendação: mantenha sync=standard (padrão). Em NVMe, o custo do sync costuma ser baixo. Se precisar trocar durabilidade por velocidade em dados descartáveis, faça isso dentro do banco e de forma consciente: synchronous_commit = off no PostgreSQL (por sessão ou por usuário) ou innodb_flush_log_at_trx_commit = 2 no MySQL. Nesses casos você pode perder transações recentes, mas o banco não fica corrompido.

Também mantenha os padrões de segurança dos bancos dentro da VM: innodb_doublewrite ligado e sync_binlog = 1 no MySQL, full_page_writes = on no PostgreSQL. Desligá-los por causa do ZFS só é discutível quando o banco grava direto em dataset com recordsize igual à página, e mesmo assim exige teste.

5. Cuide da memória: ARC versus cache do banco

O banco dentro da VM já faz seu próprio cache (buffer pool, shared_buffers). O ARC do ZFS no host guarda os mesmos blocos de novo. Limite o ARC no host (veja o artigo de armazenamento) e reserve a RAM principalmente para a VM. Opcionalmente, para o dataset dos discos do banco:

zfs set primarycache=metadata nvme/db

Isso evita o cache duplo, mas aumenta as leituras no NVMe quando o cache do banco não basta. Meça antes e depois.

Como saber se funcionou

  • qm config 110 mostra scsihw: virtio-scsi-single, iothread=1, discard=on e balloon: 0.
  • zfs get volblocksize,compression,sync nvme/db/vm-110-disk-1 mostra os valores esperados e sync como standard.
  • Teste de escrita com sync dentro da VM Linux (em um arquivo de teste, nunca no disco cru):
    apt install fio
    fio --name=commit --filename=/var/tmp/fio.test --size=2G --bs=16k \
        --rw=randwrite --ioengine=libaio --direct=1 --fsync=1 \
        --iodepth=1 --runtime=60 --time_based
    rm /var/tmp/fio.test
    Esse teste simula commits pequenos. Compare os valores de IOPS e latência antes e depois das mudanças.

Problemas comuns

A VM Windows não inicia depois de trocar para SCSI

Faltam os drivers VirtIO. Volte o barramento anterior, instale o virtio-win e adicione um disco SCSI pequeno temporário para o Windows carregar o driver antes da troca.

O pool ZFS está quase cheio e tudo ficou lento

Desempenho do ZFS cai com o pool acima de 80–90%. Libere espaço, ligue o discard nas VMs e confira snapshots antigos com zfs list -t snapshot.

Banco lento só em horários de backup

Backups do Proxmox (vzdump) leem o disco inteiro da VM. Agende fora do pico e use limite de banda no job.

Perguntas frequentes

ZFS ou LVM-thin para banco de dados?

Os dois funcionam. ZFS espelhado dá checksum, snapshots e replicação, com um pouco de overhead. LVM-thin fica mais perto do desempenho cru, sem essas proteções.

Container LXC ou VM para banco?

LXC tem menos overhead e permite recordsize no dataset. VM dá isolamento completo e é obrigatória para Windows/SQL Server.

Posso mudar o volblocksize de um disco existente?

Não. É preciso criar um disco novo com o bloco desejado e mover os dados.

Leitura complementar

Precisa de ajuda?

Se o zpool status mostrar erros ou um NVMe degradado, abra um ticket com a saída completa do comando para avaliarmos a troca do disco.

Esta resposta lhe foi útil? 0 Usuários acharam útil (0 Votos)

Leia também