Gargalo de banco de dados MySQL na VPS: como saber que o aperto da loja está no banco e por que subir mais servidor não resolve
Como saber se o gargalo é o banco de dados MySQL e não falta de servidor. Por que subir réplica pode piorar e o que realmente resolve.
2026-09-18 · Equipe · 14 min de leitura
Se o carrinho e o checkout travam enquanto as páginas de catálogo ainda abrem, o recurso que acabou provavelmente é o banco de dados — e o MySQL é um servidor só, compartilhado por todo mundo, então acrescentar máquina de aplicação abre mais conexões contra o mesmo gargalo em vez de aliviá-lo.
Como saber se o gargalo é o banco de dados MySQL e não falta de servidor
O gargalo de banco de dados MySQL numa VPS costuma se anunciar assim: as páginas que executam consulta degradam primeiro — carrinho, checkout, busca, minha-conta — enquanto home e categoria, que saem de cache, continuam abrindo normalmente. Falta de servidor de aplicação derruba tudo junto; banco apertado derruba primeiro exatamente as páginas que vendem.
Banco de dados, aqui, é o programa que guarda o estado da loja — MySQL ou MariaDB, que são da mesma família e, para efeito deste diagnóstico, se comportam da mesma forma. Produto, preço, estoque, pedido, cliente e configuração ficam nele. A aplicação tem arquivos em disco (imagem enviada, código do tema), mas não guarda o estado: ela pergunta ao banco a cada requisição.
Quatro sintomas apontam para esse lado:
- A mensagem error establishing a database connection na tela do cliente — é o texto que o WordPress exibe quando não consegue falar com o banco.
- O erro too many connections no log da aplicação ou do próprio banco.
- Lentidão que piora quando o dev sobe mais réplica da aplicação.
- Loja respondendo 504 com a CPU da aplicação tranquila.
O terceiro é o que mais confunde, e é o mais informativo: a loja ficar pior depois de uma medida que deveria melhorar. Isso é assinatura de gargalo compartilhado. Falta de máquina não se comporta assim — falta de máquina melhora quando entra máquina, seja aumentando o plano da hospedagem ou pagando reforço só no pico.
Este artigo não é o roteiro de emergência da queda, que está em site fora do ar: o que fazer nos primeiros minutos, nem o checklist geral de caça ao gargalo, que está em WooCommerce lento com muito acesso. É o recorte de um caso só: quando o recurso que acabou é o banco.
Por que banco é recurso único e aplicação é recurso replicável
A aplicação — PHP-FPM, Node, o processo que executa o código da loja — é replicável por natureza. Cada cópia atende um pedido inteiro sozinha e não precisa combinar nada com as outras. Acrescentar cópia acrescenta atendimento em paralelo, e é por isso que subir réplica funciona quando o teto é de aplicação.
O banco é o oposto. O pedido do cliente e o saldo de estoque precisam existir em um lugar só. Duas cópias aceitando gravação ao mesmo tempo teriam de combinar cada alteração entre si para não vender a mesma unidade duas vezes. Existe banco distribuído que faz isso, ao custo de uma complexidade que loja em VPS não carrega — na prática, estado não se duplica de graça.
A consequência é desconfortável: multiplicar a aplicação multiplica também o número de clientes que batem no mesmo banco. Cada réplica nova abre seu próprio conjunto de conexões. O banco é o funil onde todas as cópias se encontram.
Em linguagem de dono de loja: você pode contratar mais atendentes de balcão, e eles atendem mais gente ao mesmo tempo. Mas se todos precisam consultar o mesmo depósito, que tem uma porta, a fila só muda de lugar — sai da frente do balcão e aparece na frente do depósito.
A diferença entre escalar réplica e escalar máquina está detalhada em auto scaling em VPS. O que este artigo acrescenta é o terceiro caso: quando nenhuma das duas resolve, porque o recurso que acabou não é replicável.
‘Error establishing a database connection’ e ‘too many connections’: o que cada mensagem está dizendo
Error establishing a database connection significa que a aplicação pediu uma conexão ao banco e não conseguiu. São três causas possíveis, e vale verificar nesta ordem:
- Serviço de banco parado. Caiu, foi morto por falta de memória ou não subiu depois de um reboot.
- Limite de conexões estourado. O banco está de pé, mas não aceita mais ninguém.
- Disco cheio. Sem espaço para gravar log e arquivo temporário, o banco passa a falhar em operações comuns e pode nem subir — e é a causa que ninguém procura primeiro.
Too many connections é mais específico: o limite configurado de conexões simultâneas foi atingido. Esse limite é um número na configuração do banco (max_connections), não a capacidade física da máquina. O valor que vem no pacote instalado não tem relação nenhuma com o tamanho da sua loja — pode estar folgado ou apertado por acidente. Confira o valor real antes de mexer em qualquer coisa.
E subir esse limite às cegas troca um erro por outro. Cada conexão aberta reserva memória para os buffers dela. Limite alto demais para a RAM disponível leva a máquina a usar swap — disco emprestado como memória — e swap é mais lento que a fila que você estava tentando evitar. Em vez de recusar conexão, o banco aceita todas e atende todas mal.
Existe um terceiro sintoma, com outra causa: lock wait timeout, a consulta que só demora quando há gente no site. Aí não falta conexão — há disputa pela mesma linha da tabela. Duas requisições querem atualizar o mesmo registro e uma espera a outra. É típico de baixa de estoque e de gravação de pedido no checkout, exatamente o momento em que o cliente está com o cartão na mão.
Nada disso se confunde com o 502 e o 504 puros, que são fila da aplicação. A leitura completa dos códigos está em erro 502 bad gateway na loja virtual.
O que olhar na VPS para confirmar que o teto é do banco
- Processos ativos no banco. A lista de consultas em execução naquele instante mostra quantas estão rodando e há quanto tempo cada uma está lá. Muitas consultas antigas em execução simultânea é o retrato do banco no teto.
- Conexões abertas contra o limite configurado. Comparar o número em uso com o máximo permitido. Essa leitura só vale se for feita durante o movimento; fora do pico, o banco guarda o pico de conexões já atingido desde que o serviço subiu, e esse número serve de substituto quando não deu para medir na hora.
- Slow query log. É o registro das consultas que passaram de um tempo definido por você. Ativar antes do pico, ler depois. E procurar a consulta que mais repete, não a mais lenta isolada: uma consulta de alguns segundos que roda em toda visita pesa mais que uma consulta lenta que roda uma vez por dia.
- Espera de disco (I/O wait). É o tempo em que o processador fica parado esperando o disco responder. Banco que precisa ler do disco em vez da memória vira gargalo com CPU sobrando — e painel que só mostra CPU não acusa nada.
- Qual processo está consumindo a máquina. Esta é a leitura que separa os dois casos: se o processo do banco está no topo e a aplicação tem processo livre, o teto é do banco; se os workers da aplicação estão todos ocupados e o banco está tranquilo, é o contrário.
Todas essas leituras têm o mesmo defeito: sem linha de base, nenhum número significa nada. O mesmo total de consultas em execução pode ser rotina na sua loja e crítico em outra. Medir durante o pico, guardar a evidência e comparar com o dia comum é o que transforma número em diagnóstico — e é assunto de monitoramento de VPS.
Servidor de aplicação no teto x banco no teto: a comparação lado a lado
| Sinal observado | Aplicação no teto | Banco no teto |
|---|---|---|
| Quais páginas degradam primeiro | Todas juntas, home e categoria incluídas | Carrinho, checkout, busca e minha-conta; catálogo ainda abre |
| O que acontece ao subir mais réplica | Melhora | Piora, ou antecipa o erro de conexão |
| Qual processo consome a máquina | Vários processos da aplicação | Um processo só, o do banco, às vezes com espera de disco |
| Mensagem de erro típica | 502 e 504 no horário de pico | Error establishing a database connection, too many connections, lock wait timeout |
| O que a fila de processos mostra | Workers todos ocupados e fila cheia | Consultas antigas em execução ao mesmo tempo |
| Cache de página alivia? | Sim, tira requisição da aplicação | Alivia o catálogo; carrinho e checkout seguem iguais |
De todos esses sinais, piorar ao subir réplica é o único que aponta para banco de forma quase inequívoca. É por isso que este artigo existe: esse sintoma costuma ser interpretado como “ainda falta máquina”, e a leitura correta é oposta.
Sendo honesto: os dois casos coexistem com frequência. Banco apertado segura as requisições, a fila da aplicação enche por consequência, e o dono vê os dois sintomas ao mesmo tempo. A ordem de trabalho não muda — resolver o banco primeiro, porque ele é o recurso que não se multiplica.
E um atalho de diagnóstico: teste de carga que derruba a loja com pouquíssima gente virtual costuma estar batendo no banco, não na máquina.
O que alivia banco de verdade — e o que cada medida não resolve
- Cache de página. Tira do banco toda visita de catálogo, que é o volume maior. Não resolve carrinho, checkout e minha-conta, que nunca podem ser servidos de cache compartilhado — justamente as páginas que travam.
- Cache de objeto (Redis ou Memcached). Guarda em memória o resultado de consultas que se repetem a cada requisição, em vez de perguntar ao banco de novo. Alivia loja com muito produto e muito atributo. Não conserta consulta mal escrita nem tabela sem índice.
- Limpeza de tabelas inchadas. Em WooCommerce, os suspeitos de sempre: transientes acumulados, opções com autoload gigante carregadas em toda página, metadados antigos de pedido, log de plugin que ninguém lê. Alivia leitura e encurta backup. Não muda nada se o gargalo for gravação no checkout.
- Índice faltando. Índice é o atalho que o banco usa para achar a linha sem varrer a tabela inteira. Quando o slow query log aponta uma consulta repetida, costuma ser a medida com a melhor relação entre esforço e efeito. Exige mão de dev e teste antes: índice a mais encarece cada gravação.
- Separar o banco em máquina própria. Ele para de disputar CPU, memória e disco com PHP, backup e tarefa agendada. Continua sendo um banco só — resolve disputa de recurso, não resolve limite de conexão nem consulta ruim, e acrescenta a rede entre aplicação e banco no caminho de cada consulta.
- Réplica de leitura. Uma cópia do banco que só responde consulta de leitura. Ajuda relatório, busca e catálogo dinâmico. Não ajuda checkout, que é escrita, e exige que a aplicação saiba para onde mandar cada consulta — em WooCommerce isso não vem pronto.
Cada uma dessas medidas compra fôlego em uma dimensão específica. Nenhuma delas transforma o banco em recurso replicável.
Por que o burst pode piorar se o gargalo for o banco — e quando ele volta a fazer sentido
Sem rodeio: burst multiplica a aplicação. Se o banco já está no teto, mais nós de aplicação abrem mais conexões contra o mesmo servidor de banco e podem antecipar o too many connections. O remédio agrava o sintoma.
Para quem chegou por este artigo: burst é subir máquinas extras na nuvem pública só durante o pico e removê-las quando a demanda cai, mantendo a operação normal na VPS fixa. O conceito inteiro está em o que é cloud bursting.
A regra de aplicação do SwarmBurst é essa: ele não se aplica enquanto o banco estiver no teto. O trabalho anterior é tirar o banco do teto com as medidas da seção acima — o mesmo tipo de preparo descrito em preparar a loja para a Black Friday sem trocar de servidor — e esse trabalho não é vendido como burst.
O arranjo em que o burst volta a fazer sentido tem quatro condições, todas verificáveis antes de instalar qualquer coisa: aplicação sem estado, sem nada gravado no disco do nó temporário; banco fixo na VPS, com folga medida durante o pico e não no dia comum; número de conexões por réplica definido no pool da aplicação, em vez de cada nó abrindo quantas quiser; e teto de conexões do banco dimensionado para o número máximo de nós que o burst pode subir.
É o mesmo desenho do produto, visto por outro ângulo, e aparece no passo a passo de configuração do burst no Docker Swarm: a VPS continua dona do estado — banco, arquivos enviados e painel não saem de lá. Os nós temporários só atendem requisição.
E a postura de diagnóstico, que vale dizer antes de qualquer proposta: se ao olhar os números o caso for banco, isso é dito na hora, em vez de vender instalação de agente.
Quero o piloto do primeiro pico
Se você já tem o slow query log e o número de conexões do último pico em mãos, é uma conversa no WhatsApp para ler isso junto antes da próxima data de pico.
Perguntas frequentes
Como verificar as conexões ativas e o limite configurado no MySQL?
Você precisa comparar o número de conexões em uso com o máximo permitido. Essa leitura é mais útil durante o pico de acesso; fora do horário de movimento, o banco guarda o pico de conexões já atingido desde que o serviço subiu, e esse número serve como substituto quando não deu para medir durante o pico.
Cache de página e cache de objeto resolvem banco de dados lento?
Cache de página tira do banco toda visita de catálogo, que é o maior volume, mas não resolve carrinho, checkout e minha-conta — justamente as páginas que travam, porque nunca podem ser servidas de cache compartilhado.
Cache de objeto (Redis ou Memcached) guarda em memória o resultado de consultas repetidas em vez de perguntar ao banco de novo, aliviando lojas com muito produto. Mas não conserta uma consulta mal escrita nem uma tabela sem índice, que são problemas estruturais.
Vale a pena usar réplica de leitura na minha loja?
Réplica de leitura ajuda em relatório, busca e catálogo dinâmico, porque esses usos são só de leitura de dados. Mas não ajuda checkout — que é operação de escrita (gravação de pedido) — e exige que a aplicação saiba para onde mandar cada tipo de consulta, algo que WooCommerce não faz automaticamente.
Separar o banco em máquina própria resolve o gargalo?
Separar o banco em servidor próprio resolve a disputa de CPU, memória e disco com a aplicação, dando mais recursos para ele. Mas o banco continua sendo um servidor só — não resolve limite de conexão, não resolve consulta ruim, e acrescenta a rede entre aplicação e banco no caminho de cada consulta, que pode anular ganhos.
O SwarmBurst pode piorar a situação se o gargalo for o banco de dados?
Sim. SwarmBurst multiplica a aplicação — sobe máquinas extras na nuvem pública durante o pico. Se o banco já está no teto, mais nós de aplicação abrem mais conexões contra o mesmo servidor de banco e podem antecipar o erro ‘too many connections’. O remédio agrava o sintoma. Trabalhe o banco primeiro antes de usar burst.