Nos últimos dias eu trabalhei na otimização parcial do site QualifiCAD, o melhor site em português de tutoriais sobre AutoCAD, Revit e SketchUp. Tive a oportunidade de passar por vários desafios e de aprender bastante. A fim de preservar esse conhecimento adquirido para outras ocasiões semelhantes, além de eventualmente ajudar algum visitante, registro nesta publicação um resumo do que aconteceu.
Situação inicial
O site é bem visitado, com aproximadamente 100.000 visualizações de páginas por mês. Ele está hospedado em um servidor na DigitalOcean com a seguinte configuração:
- 1 CPU Intel com 1 GB RAM;
- 25 GB de memória SSD NVMe;
- 1 TB de transferência.
Já havíamos trabalhado anteriormente na mudança do tema e da lista de plugins, optando pelo GeneratePress com um design bem leve. Contudo, não havíamos definido nenhum plugin de otimização.
E apesar do resultado medido no GTMetrix estar razoável, o servidor encontrava-se sempre no limite da memória e com picos de uso na CPU. Ao longo do dia o site tratava algumas vezes e o WordPress lançava a mensagem de erro:
Error establishing a database connection
Cloudflare e uma falha no processo
Meu primeiro erro foi não ter solicitado o backup imediato do site, pois a primeira ação sugerida – a utilização do CDN da Cloudflare – quebrou o layout…
O objetivo dessa ação foi diminuir as requisições ao servidor da DigitalOcean, uma vez que os arquivos estáticos do site passaram a ser disponibilizados pelos servidores da Cloudflare. Deu certo, a taxa de transferência na DigitalOcean, que tinha vários picos de 2 MB/s, caiu para menos de 25% disso, mas não sei por que cargas d’água o layout foi afetado. Comecei então a investigação para tentar encontrar a causa raiz do problema…
Debug do Banco de Dados
Para começar, instalei três plugins:
- WP Debugging: ativa o modo debug do WordPress inserindo as seguintes linhas no arquivo
wp-config.
php:
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_LOG', true );
define( 'SCRIPT_DEBUG', true );
define( 'SAVEQUERIES', true );
- Query Monitor: plugin com várias ferramentas de monitoramento como verificação das queries ao banco de dados, erros de PHP, etc. Apesar do nome fazer referência à banco de dados, esse plugin tem funções que tocam vários outros aspectos de uma instalação WordPress.
- Debug Bar: como diz sua descrição: “Adiciona um menu de depuração à barra de administração, permite mostrar informações de depuração sobre consultas, cache e outras informações úteis”. A sua instalação é sugerida pelo WP Debugging, mas acho que ele é totalmente dispensável quando o Query Monitor está instalado.
Usando o Query Monitor, o debug log do WordPress exibiu a seguinte mensagem de erro:
Table './[nome-do-banco-de-dados]/wp_postmeta' is marked as crashed and last (automatic?) repair failed
A tabela wp_postmeta
guarda todas as informações extras de posts que são geradas por plugins de custom fields, SEO, marketing, etc. Já as informações básicas são salvas na tabela wp_posts
.
Reparação do Banco de Dados
Sem buscar mais informações sobre a tabela wp_postmeta
, decidi utilizar o plugin Advanced Database Cleaner PRO para otimizá-la e repará-la. Contudo, mesmo depois de executar o reparo, o plugin continuava a indicar que a tabela tinha problemas.
Sem desanimar, tentei outra solução: a ferramenta de reparação nativa do WordPress. Para utilizá-la, você deve inserir a seguinte linha no arquivo wp-config.php
:
define( ‘WP_ALLOW_REPAIR’, true );
Em seguida, deve acessar a página de reparação do banco de dados – https://seu-dominio.com/wp-admin/maint/repair.php. Vai aparecer a seguinte mensagem:

Quando você clicar em reparar o banco de dados, o sistema vai analisar tabela por tabela e reparar aquelas que estiverem corrompidas.
No meu caso, infelizmente, me deparei com a seguinte mensagem de erro:
A tabela wp_postmeta não está bem. Está elatando o seguinte erro: Table is marked as crashed and last repair failed. O WordPress tentará consertar a tabela...
Erro ao corrigir a tabela wp_postmeta. Erro: Can't create new tempfile: './[nome-do-banco-de-dados]/wp_postmeta.TMD'
Pesquisando um pouco, descobri que esse erro estava sendo causado porque já havia um arquivo com o nome wp_postmeta.TMD
na pasta /var/lib/mysql/nome-do-banco-de-dados/ do servidor. Pedi então para o responsável pelo servidor deletar o arquivo (que tinha 1,5 GB!) e rodar o comando myisamchk
na pasta:
myisamchk -r -f wp_postmeta.MYI
E recebi mais um erro na cabeça:
myisamchk: error: 140 when opening MyISAM-table 'wp_postmeta.MYI'
Parece que para resolver isso basta rodar o comando sem a extensão MYI, mas neste ponto eu tinha recebido acesso ao MySQL Workbench (ferramenta visual de acesso à bancos de dados MySQL) e tentei resolver o problema com ele. Daria para fazer com o phpMyAdmin também, mas eu acho que na DigitalOcean não tem cPanel.
Com o MySQL Workbench eu fiz alguns pesquisas no banco e descobri que a tabela wp_postmeta
tinha mais de 1 milhão de linhas! Achei razoável supor que a impossibilidade de reparação da tabela estava ligada a esse número enorme de linhas.
Analisando as meta_keys da tabela, descobri que desses mais de 1 milhão de linhas, 951.916 começavam com o prefixo vw
e se referiam ao registro semanal e mensal de usuários em cada artigo do site. Por exclusão, descobri finalmente que o vilão da história era o plugin Post View Count, que registrava justamente esses dados. Deletei o plugin e voltei para o banco de dados.
Seguindo a batalha, ao tentar deletar essas linhas malditas da tabela, a conexão MySQL Workbench com o servidor estava caindo porque a query estava demorando mais do que 30 segundos. Para quem tentava acessar o site aparecia a seguinte mensagem:
Warning: mysqlirealconnect(): (HY000/2002): No such file or directory in /var/www/html/wp-includes/wp-db.php on line 1653
Mais uma pesquisa no Google mostrou que esse problema pode ser solucionado mudando o parâmetro DB_HOST
no arquivo wp-config.php
de localhost
para 127.0.0.1
ou para o IP do seu servidor, alterando a forma de conexão do WordPress com o banco de dados. Aparentemente essa solução é mais lenta, mas no meu caso resolveu o problema, o que é mais importante.
Depois disso, consegui limpar as linhas desnecessárias da tabela de 100.000 em 100.000 e, ufa!, repará-la (ficou com aproximadamente 92.000 linhas). Felizmente, o layout voltou ao normal e eu pude passar efetivamente para a otimização do banco de dados e do site.
Otimização do Banco de Dados
Aproveitei o momento e deletei todas as tabelas relacionadas a plugins desinstalados, assim como as linhas das tabelas remanescentes com relação a esses plugins.
Como ainda apareciam algumas slow queries no Query Monitor, eu instalei o plugin Index WP MySQL For Speed, que cria indexs para as tabelas mais importantes e muda o engine do banco de dados de MyISAM para InnoDB. A mudança surtiu efeito e sobrou apenas uma slow query referente a uma falha nativa e antiga no código-fonte do WordPress.
Otimização do Cron Jobs
Focado na diminuição dos recursos do servidor, eu passei para a otimização dos cron jobs. Instalei o plugin WP-Control para deletar jobs repetidos e aumentar o intervalo de execução de outros.
Também desabilitei o WP-Cron e ativei o cron job no servidor inserindo a seguinte linha no crontab
:
*/5 * * * * /usr/bin/wget -q -O - https://qualificad.com.br/wp-cron.php?doing_wp_cron >/dev/null 2>&1
Mais informações sobre essa modificação neste artigo do site WP Speed Matters e neste outro do WPJohnny.
O único processo que eu não consegui apagar de jeito nenhum foi o Action Scheduler, que ficou como resquício de uma instalação antiga do Woocommerce. Não achei solução para sua completa desativação em nenhum site. O paliativo foi instalar o plugin Action Scheduler – Disable Default Queue Runner, que remove o executor do Action Scheduler de dentro do hook action_scheduler_run_queue
.

Cache e outras otimizações
Instalei e configurei o bom e velho WP Fastest Cache. E para lidar com o lazy loading das imagens enquanto não fecho com o proprietário do site um pacote para otimizar todas as imagens, instalei e configurei o plugin Flying Images.
Por fim, aumentei o limite de memória do PHP de 64 MB para 128 MB com o seguinte comando no arquivo wp-config.php
:
define( 'WP_MEMORY_LIMIT', '128M' );
Resultados
No fim das contas não descobri a relação do Cloudflare com a quebra do layout, mas os resultados no servidor foram significativos:
- CPU: redução do número de picos de uso e diminuição dos limites dos picos de 100% para 60% da capacidade;
- Taxa de transferência: redução de mais de quatro vezes nas requisições e transferências;
- Memória: a otimização não surtiu efeito na memória. A solução adotada foi aumentar a memória de 1 GB para 2 GB.



O que ainda seria possível fazer para melhorar a nota do GTMetrix?
- Testar a combinação dos arquivos CSS;
- Otimizar a entrega do CSS com geradores de caminho crítico do CSS;
- Testar o preload das páginas;
- Adiar o carregamento dos arquivos em javascript;
- Alterar o heartbeat;
Mas vamos deixar essas tarefas para outro momento porque a demanda cresceu muito além do previsto inicialmente.
Gostou do artigo? Ficou alguma dúvida? Tem alguma sugestão ou correção a fazer? Deixe seu comentário a seguir.
Share Your Thoughts