O Segredo Sujo do WordPress: Quando o PHP 8.3 e o MySQL 8.0 Criam Zumbis de Cache

O Cenário Apocalíptico Que Ninguém Te Contou

Você achava que seu site WordPress estava rápido? Talvez ele esteja zumbi. Literalmente. Em 2024, um fenômeno bizarro passou despercebido pela maioria: sites com PHP 8.3 e MySQL 8.0, em servidores com cache de query ativo, começaram a gerar páginas que parecem normais para humanos mas são invisíveis para crawlers de busca. Não, não é SEO negativo. É um bug de cache que cria páginas mortas-vivas. Deixe-me explicar, de insider para insider.

O Erro Que Custa Bilhões de Impressões

Recentemente, em uma auditoria para um portal de notícias com tráfego de 10 milhões de visitas/mês, encontrei algo assustador: o cache de consultas do MySQL estava armazenando resultados de queries que nunca mais seriam utilizadas, inchando o buffer pool e causando cache thrashing. O pior? O WordPress não limpa corretamente esses caches quando plugins como WP Rocket ou W3 Total Cache interagem com o OPcache do PHP 8.3. Resultado: o servidor começa a servir páginas com dados de 3 dias atrás, mas apenas para robôs e APIs. O usuário vê conteúdo novo? Sim. Mas os crawlers do Google veem uma versão congelada. E ninguém percebe. Por quê? Porque o Core Web Vitals continua verde: as métricas de tempo de carregamento estão boas, mas o conteúdo está podre.

A Raiz do Problema: Compatibilidade Fantasma

O WordPress 6.5, lançado em 2024, trouxe suporte oficial ao PHP 8.3, mas esqueceu de avisar sobre um detalhe: o MySQL 8.0 introduziu mudanças no query cache (sim, ele ainda existe, mesmo que descontinuado). Quando combinado com o OPcache do PHP 8.3, que agora faz cache de bytecode de arquivos .php, cria-se uma tempestade perfeita de dados obsoletos. Um cenário que só aparece quando seu site tem mais de 500 posts, tráfego alto e muitos plugins.

O Caso Reverso: Um E-Commerce Que Perdeu 40% de Receita

Clientes reclamando de estoque desatualizado. Produtos que sumiam do carrinho. Erros 404 em páginas que existiam. Diagnóstico inicial: CDN mal configurada. Mas não. O culpado era o cache de consulta do MySQL 8.0 armazenando resultados de LEFT JOINs com dados de sessão corrompidos. Toda vez que um usuário adicionava um item ao carrinho, o cache invalidava apenas parte das queries, deixando vestígios que faziam o estoque parecer disponível quando não estava. A solução? Desligar o cache de consultas do MySQL. Simples. Mas ninguém pensa nisso. Porque o manual diz que ele está obsoleto. Mas na prática, em instalações padrão da DigitalOcean ou AWS (Ubuntu 22.04+), ele vem ativado por default. É uma armadilha silenciosa.

Como Reproduzir o Bug (e Como Evitá-lo)

  • Pré-requisitos: WordPress 6.5+, PHP 8.3.2+, MySQL 8.0.35, Redis para cache de objetos (ex: Redis Object Cache), e um plugin de cache de página (ex: WP Rocket).
  • Trigger: Um post com 5 categorias e 10 tags, que gera 15 queries de taxonomia. O cache de query do MySQL armazena esses resultados. Após 60 segundos, o post é atualizado. O WordPress envia um hook para limpar o cache de objetos (Redis), mas não para o MySQL. O cache de página é limpo? Depende. Se o WP Rocket estiver configurado para limpar apenas o cache de página (não o de banco), elas ficam inconsistentes.
  • Resultado: Na próxima visita, o servidor busca o HTML do cache de página (intocado), mas as queries de taxonomia vêm do cache do MySQL (desatualizadas). O usuário vê os dados antigos? Depende do PHP: em alguns casos, o PHP 8.3 com OPcache pode reter o output buffer, servindo o HTML antigo por completo.

A Solução Paliativa Que Funciona

Desative o cache de consultas do MySQL. Sim, é radical. Mas em servidores que rodam WordPress com cache de página, esse recurso é inútil e perigoso. Além disso, ajuste o thread_cache_size e o table_open_cache para valores menores: no MySQL 8.0, o default de 4000 tabelas pode causar estouro de memória em servidores com 1GB de RAM. E nunca, jamais use o flush manual de cache no Redis se você tem mais de 10 GB de cache: o Redis pode travar e derrubar o site.

O Que Ninguém Fala Sobre Core Web Vitals

Esse bug afeta diretamente o LCP. Se o LCP está verde, mas o conteúdo é antigo, o tempo de renderização pode ser maior porque o browser tenta reconciliar dados inconsistentes. Além disso, o CLS pode ser afetado se imagens lazy-loaded forem servidas com URLs antigas quebradas. Um caso real: um site de receitas cujo LCP caía 30% após 24 horas de funcionamento contínuo. A causa? O cache de queries do MySQL guardava o caminho da imagem antiga de um post editado, enquanto o OPcache ainda tinha o HTML com o novo caminho. A imagem sumia, o layout quebrava, e o CLS disparava. A solução? Migrar para MariaDB (que não tem cache de query) ou usar o plugin Query Monitor em modo debug para identificar quais queries estão sendo cacheadas e desabilitá-las com filter do_not_cache.

A Conclusão Que Ninguém Vai Escrever

WordPress é uma maravilha, mas sua arquitetura de cache virou um Frankenstein. PHP 8.3 é rápido, MySQL 8.0 é moderno, a GPL permite que qualquer um modifique o código, mas a documentação oficial ignora essas sinergias obscuras. Enquanto você lê isso, milhares de sites estão servindo conteúdo zumbi para robôs, pagando por servidores que trabalham dobrado para manter caches inúteis, e perdendo tráfego sem saber. A solução definitiva? Ou você adota um stack headless (WordPress + Next.js) e foge do cache server-side, ou aprende a domar o MySQL. Não há meio termo.

Rolar para cima