La página está en blanco. O peor: se carga al instante con esa línea que hace suspirar a cualquier ingeniero de guardia—“Error al establecer una conexión con la base de datos.” Su CEO está actualizando la página. Su equipo de marketing está “solo comprobando algo”. Su sistema de monitorización está chillando como una tetera.
Este error no es un diagnóstico. Es WordPress diciendo: “Le pregunté a la base de datos algo y obtuve silencio.” Su trabajo es averiguar si ese silencio es por una base de datos muerta, una dirección equivocada, un problema de credenciales, un servidor saturado o un subsistema de almacenamiento que se está degradando silenciosamente.
Qué significa realmente el error (y qué no significa)
WordPress muestra “Error al establecer una conexión con la base de datos” cuando no puede completar su protocolo inicial de conexión con MySQL/MariaDB (u otro servidor compatible con MySQL). La falla ocurre antes de que WordPress pueda ejecutar consultas para opciones, usuarios o entradas, por lo que no obtiene tema, ni contenido, solo el mensaje.
Técnicamente, WordPress hace algo así como:
- Leer la configuración de la BD desde
wp-config.php(DB_NAME, DB_USER, DB_PASSWORD, DB_HOST). - Inicializar el controlador cliente de base de datos (mysqli).
- Abrir una conexión TCP (típicamente puerto 3306) o un socket local.
- Autenticarse.
- Seleccionar el esquema de la base de datos.
Si cualquiera de esos pasos falla, la salida se ve igual. Por eso las recuperaciones más rápidas comienzan por acotar el dominio de la falla: red vs proceso vs credenciales vs saturación vs almacenamiento.
Lo que no es: normalmente no es un “bug de WordPress.” WordPress es solo el mensajero. A veces el mensajero es molesto, pero aún necesita entregar el mensaje.
Dos patrones comunes:
- Caída total: el servicio de base de datos está detenido, se ha bloqueado o es inalcanzable. La solución es operativa.
- Caída parcial: la base de datos está viva pero rechaza conexiones (demasiados clientes, almacenamiento lento, contención de bloqueos, problema de DNS, problema de autenticación). La solución suele ser de capacidad o configuración.
Una frase para grapar a su proceso de incidentes:
“La esperanza no es una estrategia.” — General Gordon R. Sullivan
Guion de diagnóstico rápido (primero/segundo/tercero)
Cuando su sitio está caído, “ser exhaustivo” es la forma de perder su SLA. Sea rápido, luego sea exhaustivo. Aquí está el orden que gana en producción.
Primero: confirme qué está roto desde el exterior
- Acceda al sitio desde una ruta de red limpia (no su VPN de oficina) y confirme que no es una capa de caché sirviendo páginas de error obsoletas.
- Compruebe si
/wp-admin/muestra el mismo error. Si sí, no es un problema del renderizado del tema; es la inicialización temprana de la BD. - Revise los paneles de salud del servidor (CPU, carga, memoria, latencia de disco). Si la latencia de disco está disparada, trate a la base de datos como sospechosa hasta que se demuestre lo contrario.
Segundo: aislar red vs servicio
- Si la BD es remota: pruebe la alcanzabilidad TCP al puerto 3306 desde el host web.
- Si la BD es local: compruebe que el socket Unix existe y que MySQL está escuchando.
- Valide la resolución DNS de DB_HOST si es un nombre de host y no una IP.
Tercero: credenciales y capacidad
- Verifique que
wp-config.phpcoincida con las credenciales y el host reales de la BD. - Compruebe MySQL en busca de “Too many connections”, consultas lentas o recuperación de InnoDB.
- Revise los registros: PHP-FPM, Nginx/Apache, registro de errores de MySQL y el journal del sistema.
Regla práctica: si puede conectarse con las mismas credenciales desde el servidor web, WordPress también puede. Si no puede, deje de editar WordPress y arregle la plataforma.
Broma #1: La base de datos no está “de baja,” solo se tomó un día personal—justo después de que usted empezara el suyo.
Tareas prácticas de recuperación (comandos, salidas, decisiones)
Abajo hay tareas prácticas que puede ejecutar durante un incidente. Cada una incluye: un comando, qué significa la salida y la decisión que debe tomar a continuación. Esto es lo que realmente hace a las 02:17.
Trabajo 1: Confirmar el estado del servicio MySQL/MariaDB
cr0x@server:~$ sudo systemctl status mariadb --no-pager
● mariadb.service - MariaDB 10.11.6 database server
Loaded: loaded (/lib/systemd/system/mariadb.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-12-26 01:58:12 UTC; 15min ago
Docs: man:mariadbd(8)
https://mariadb.com/kb/en/library/systemd/
Main PID: 2143 (mariadbd)
Status: "Taking your SQL requests now..."
Tasks: 37 (limit: 18956)
Memory: 1.2G
CPU: 2min 41.121s
CGroup: /system.slice/mariadb.service
└─2143 /usr/sbin/mariadbd
Significado: Si está active (running), el demonio de BD existe. Eso no significa que esté aceptando conexiones, pero está vivo.
Decisión: Si está inactive, failed o reiniciándose, vaya a los registros (Tarea 4) y a las comprobaciones de almacenamiento (Tarea 11/12) antes de reiniciar a ciegas.
Trabajo 2: Ver si MySQL está escuchando en la interfaz/puerto esperado
cr0x@server:~$ sudo ss -lntp | grep -E ':(3306|33060)\b'
LISTEN 0 151 127.0.0.1:3306 0.0.0.0:* users:(("mariadbd",pid=2143,fd=22))
Significado: Esta BD solo escucha en localhost. Si su WordPress está en otro host, fallará siempre.
Decisión: Si WordPress es remoto, arregle bind-address o use un listener en red privada. Si es local, asegúrese de que DB_HOST apunte a 127.0.0.1 o al socket correctamente.
Trabajo 3: Verificar resolución DNS de DB_HOST
cr0x@server:~$ getent hosts db.internal
10.10.2.15 db.internal
Significado: El nombre resuelve. Si cuelga o no devuelve nada, tiene un problema de DNS o resolutor (común durante incidentes de red).
Decisión: Si está roto, fije temporalmente con una entrada en /etc/hosts durante la mitigación del incidente, luego arregle DNS correctamente después.
Trabajo 4: Revisar el registro de errores de la base de datos por recuperación de crash, corrupción o problemas de disco
cr0x@server:~$ sudo tail -n 60 /var/log/mysql/error.log
2025-12-26 02:10:44 0 [Note] InnoDB: Starting crash recovery.
2025-12-26 02:10:44 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
2025-12-26 02:10:47 0 [Note] InnoDB: Crash recovery finished.
2025-12-26 02:10:47 0 [Warning] Aborted connection 431 to db: 'wpdb' user: 'wpuser' host: '10.10.3.21' (Got timeout reading communication packets)
Significado: Ocurrió recuperación tras un crash (por lo que hubo un fallo o un apagado no limpio). Las conexiones abortadas sugieren timeouts o bloqueos de red.
Decisión: Si la recuperación por crash se repite o muestra errores I/O, deje de culpar a WordPress. Revise la latencia de almacenamiento y la salud del sistema de archivos (Tareas 11–12).
Trabajo 5: Probar conectividad desde el servidor web usando las mismas credenciales que WordPress
cr0x@server:~$ grep -E "DB_(NAME|USER|PASSWORD|HOST)" /var/www/html/wp-config.php
define('DB_NAME', 'wpdb');
define('DB_USER', 'wpuser');
define('DB_PASSWORD', 'correcthorsebatterystaple');
define('DB_HOST', 'db.internal');
cr0x@server:~$ mysql -h db.internal -u wpuser -p -e "SELECT 1;"
Enter password:
1
1
Significado: Si esto tiene éxito, red + credenciales están bien. WordPress debería poder conectarse, por lo que el problema probablemente sea el runtime de PHP, desajuste de socket o saturación transitoria.
Decisión: Si falla, el mensaje de error de mysql es oro—actúe en consecuencia. “Access denied” significa credenciales/permisos. “Can’t connect” significa red/listener/firewall. “Unknown MySQL server host” significa DNS.
Trabajo 6: Comprobar si MySQL está rechazando por max_connections
cr0x@server:~$ mysql -h db.internal -u root -p -e "SHOW GLOBAL STATUS LIKE 'Threads_connected'; SHOW VARIABLES LIKE 'max_connections';"
Enter password:
+-------------------+-------+
| Variable_name | Value |
+-------------------+-------+
| Threads_connected | 498 |
+-------------------+-------+
+-----------------+-------+
| Variable_name | Value |
+-----------------+-------+
| max_connections | 500 |
+-----------------+-------+
Significado: Está al borde del abismo. Las nuevas conexiones serán rechazadas; WordPress lanzará el error genérico.
Decisión: Mitigación inmediata: detenga la tormenta de conexiones (cachear, limitar la tasa, matar clientes abusivos, reiniciar PHP-FPM con cuidado). Luego arregle la causa raíz: estrategia de conexiones persistentes, rendimiento de consultas, conteos de procesos PHP-FPM y pooling de conexiones (si aplica).
Trabajo 7: Identificar las principales fuentes de conexiones y qué están haciendo
cr0x@server:~$ mysql -h db.internal -u root -p -e "SHOW FULL PROCESSLIST\G" | sed -n '1,80p'
Enter password:
*************************** 1. row ***************************
Id: 91231
User: wpuser
Host: 10.10.3.21:51344
db: wpdb
Command: Query
Time: 24
State: Sending data
Info: SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes'
*************************** 2. row ***************************
Id: 91244
User: wpuser
Host: 10.10.3.21:51362
db: wpdb
Command: Query
Time: 29
State: Copying to tmp table
Info: SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts ...
Significado: Consultas de larga duración, tablas temporales y “Sending data” pueden indicar índices faltantes, conjuntos de resultados enormes o lentitud del almacenamiento.
Decisión: Si ve una consulta cara que se repite, puede matar temporalmente a los peores para restaurar el servicio, y luego añadir índices o arreglar el plugin/tema que la genera.
Trabajo 8: Matar una consulta desbocada (quirúrgico, no a lo bruto)
cr0x@server:~$ mysql -h db.internal -u root -p -e "KILL 91244;"
Enter password:
Significado: El hilo se termina. Si reaparece instantáneamente, algo está golpeando la BD (cron, tráfico, bot, plugin).
Decisión: Si matar ayuda brevemente, implemente controles de tráfico (reglas WAF, caché, bloqueo de administración) y busque la fuente.
Trabajo 9: Revisar la salud y backlog de PHP-FPM (la capa web puede ser la culpable)
cr0x@server:~$ sudo systemctl status php8.2-fpm --no-pager
● php8.2-fpm.service - The PHP 8.2 FastCGI Process Manager
Loaded: loaded (/lib/systemd/system/php8.2-fpm.service; enabled; preset: enabled)
Active: active (running) since Thu 2025-12-26 01:55:02 UTC; 18min ago
Main PID: 1887 (php-fpm8.2)
Status: "Processes active: 52, idle: 1, Requests: 10432, slow: 219, Traffic: 0.6req/sec"
Significado: Si tiene muchos trabajadores activos, pocos inactivos y las solicitudes lentas aumentan, PHP está saturado. PHP saturado a menudo genera más carga en la BD mediante reintentos, timeouts y multitudes golpeando al mismo tiempo.
Decisión: Si PHP-FPM está al límite, reduzca la concurrencia o añada capacidad. No lo aumente a ciegas; convertirá el rechazo de la BD en un colapso total del servidor.
Trabajo 10: Validar desajuste socket vs TCP de DB_HOST
cr0x@server:~$ sudo ls -l /var/run/mysqld/
total 4
srwxrwxrwx 1 mysql mysql 0 Dec 26 01:58 mysqld.sock
-rw-r--r-- 1 mysql mysql 5 Dec 26 01:58 mysqld.pid
cr0x@server:~$ php -r 'echo ini_get("mysqli.default_socket"), PHP_EOL;'
/var/run/mysqld/mysqld.sock
Significado: El socket existe y PHP espera la misma ruta de socket. Si PHP espera un socket diferente, las conexiones locales pueden fallar incluso cuando la BD está en ejecución.
Decisión: Si hay desajuste, ponga DB_HOST a 127.0.0.1 para forzar TCP (mitigación rápida) o corrija la configuración del socket en PHP (solución adecuada).
Trabajo 11: Comprobar espacio en disco y agotamiento de inodos (el clásico imitador de “BD murió”)
cr0x@server:~$ df -h /var/lib/mysql
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 100G 99G 1.0G 99% /var
cr0x@server:~$ df -i /var/lib/mysql
Filesystem Inodes IUsed IFree IUse% Mounted on
/dev/sda2 6553600 6553200 400 100% /var
Significado: Se han agotado los inodos. MySQL puede estar “en ejecución” pero incapaz de crear tablas temporales, redo logs o archivos nuevos. WordPress verá fallos de conexión o timeouts.
Decisión: Libere espacio/inodos inmediatamente (logs, cachés, respaldos antiguos), luego programe una solución de particionado/almacenamiento adecuada. El agotamiento de inodos es un problema estructural, no un mal humor.
Trabajo 12: Buscar bloqueos I/O que conviertan a la BD en un embustero (dice “en ejecución”, pero está atascada)
cr0x@server:~$ iostat -xz 1 3
Linux 6.1.0 (server) 12/26/2025 _x86_64_ (8 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
10.21 0.00 5.02 42.11 0.00 42.66
Device r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 8.00 120.00 256.0 6144.0 98.0 12.4 102.5 15.2 108.4 2.10 96.0
Significado: Alto %iowait y alto await con utilización cercana al 100%: su disco es el cuello de botella. Las consultas MySQL se quedarán en espera; los clientes harán timeouts; WordPress informará “no puede conectar”.
Decisión: Reduzca la presión de escritura (detenga trabajos ruidosos, reduzca ráfagas de logging), mueva la BD a almacenamiento más rápido o escale verticalmente. Si esto ocurre en un disco de VM compartida, puede ser víctima de vecinos ruidosos.
Trabajo 13: Buscar errores del sistema de archivos o remonteo en solo lectura
cr0x@server:~$ mount | grep ' /var '
/dev/sda2 on /var type ext4 (ro,relatime,errors=remount-ro)
cr0x@server:~$ sudo dmesg | tail -n 20
[12345.678901] EXT4-fs error (device sda2): ext4_journal_check_start:83: Detected aborted journal
[12345.678905] EXT4-fs (sda2): Remounting filesystem read-only
Significado: El sistema de archivos se remonteó en solo lectura debido a errores. MySQL puede seguir en ejecución pero no puede escribir, y entonces todo se desmorona.
Decisión: Trátelo como un incidente de almacenamiento. Detenga MySQL limpiamente si es posible, planifique fsck y restaure desde backups si es necesario. No siga hurgando; puede empeorar la corrupción.
Trabajo 14: Confirmar que WordPress no apunta al host de base de datos equivocado tras una migración
cr0x@server:~$ sudo -u www-data php -r "require '/var/www/html/wp-config.php'; echo DB_HOST, PHP_EOL;"
db.internal
cr0x@server:~$ ping -c 1 db.internal
PING db.internal (10.10.2.15) 56(84) bytes of data.
64 bytes from 10.10.2.15: icmp_seq=1 ttl=63 time=0.493 ms
Significado: La configuración de WordPress resuelve y el host es alcanzable a nivel ICMP. (ICMP no es prueba de servicio TCP, pero es una verificación rápida de cordura.)
Decisión: Si ping funciona pero MySQL no, concéntrese en firewall y listener de BD. Si ambos fallan, tiene problemas de enrutamiento o DNS.
Trabajo 15: Validar grants del usuario desde el lado BD (la discrepancia de host remoto es clásica)
cr0x@server:~$ mysql -u root -p -e "SHOW GRANTS FOR 'wpuser'@'10.10.3.%';"
Enter password:
+--------------------------------------------------------------------------------------------------+
| Grants for wpuser@10.10.3.% |
+--------------------------------------------------------------------------------------------------+
| GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER ON `wpdb`.* TO `wpuser`@`10.10.3.%` |
+--------------------------------------------------------------------------------------------------+
Significado: El usuario tiene permiso desde esa subred. Si solo tiene 'wpuser'@'localhost', las conexiones remotas fallarán con “Access denied.”
Decisión: Arregle los grants para que coincidan con la realidad. Tras migraciones, las suposiciones de “localhost” son asesinos silenciosos.
Trabajo 16: Detectar una tabla dañada y hacer una reparación relativamente segura (MyISAM) o una comprobación más cauta (InnoDB)
cr0x@server:~$ mysql -h db.internal -u root -p -e "CHECK TABLE wpdb.wp_options;"
Enter password:
+------------------+-------+----------+--------------------------------+
| Table | Op | Msg_type | Msg_text |
+------------------+-------+----------+--------------------------------+
| wpdb.wp_options | check | status | OK |
+------------------+-------+----------+--------------------------------+
Significado: La comprobación básica de integridad dice OK. Si ve “corrupt” en tablas MyISAM, REPAIR TABLE puede ayudar. Para InnoDB, la corrupción es una historia más grande.
Decisión: Si aparece corrupción y está en InnoDB: priorice restaurar desde backups o usar modos de recuperación de InnoDB con cuidado. “Repair” no es una varita mágica para InnoDB.
Errores comunes: síntoma → causa raíz → solución
Esta sección es deliberadamente específica. El consejo genérico es como los eventos de caída que se repiten en el calendario.
1) Síntoma: el error aparece después de un cambio de DNS o migración
- Causa raíz:
DB_HOSTapunta a un hostname/IP antiguo, o el TTL de DNS + cachés sigue enviando algunos servidores a la BD antigua. - Solución: Confirme
DB_HOSTen cada nodo web; limpie cachés DNS locales donde corresponda; mantenga el endpoint de BD estable (VIP/CNAME) y migre detrás de él.
2) Síntoma: errores intermitentes bajo picos de tráfico, bien con bajo tráfico
- Causa raíz: MySQL alcanza
max_connections, PHP-FPM tiene demasiados workers, o hay una multitud golpeando páginas sin caché. - Solución: Añada caché para rutas de lectura intensiva, limite la concurrencia de PHP-FPM, aumente la capacidad de BD y deje de pensar que “escalamos solo web” si la BD es el cuello de botella.
3) Síntoma: servicio BD “en ejecución” pero las conexiones hacen timeout
- Causa raíz: bloqueos I/O, sistema de archivos remonteado en solo lectura, o InnoDB atascado en recuperación/presión de flush.
- Solución: Mida latencia de disco, revise
dmesgy flags de montaje, reduzca la carga de escritura y mueva la BD a almacenamiento adecuado si es necesario.
4) Síntoma: “Access denied for user” tras cambiar la contraseña
- Causa raíz: WordPress usa credenciales antiguas; la gestión de configuración no propagó el cambio; o los grants del usuario son específicos por host y la identidad de host cambió.
- Solución: Actualice
wp-config.phpde forma consistente, verifique los grants para el host que se conecta y rote secretos mediante un proceso controlado (no pegándolo en Slack).
5) Síntoma: el error aparece solo en algunas páginas (admin funciona, público no)
- Causa raíz: caché/CDN sirviendo páginas de error obsoletas; o un plugin dispara consultas pesadas solo en ciertas rutas.
- Solución: Purge las caches, esquive el CDN para diagnóstico y luego profile las consultas lentas vinculadas a esas rutas.
6) Síntoma: el error apareció justo después de activar un plugin de “rendimiento”
- Causa raíz: caché de objetos mal configurado (endpoint Redis incorrecto), comportamiento agresivo de cron/heartbeat, o plugin que inunda la BD con consultas no cacheadas.
- Solución: Desactive el plugin para restaurar el servicio y luego reintrodúzcalo con pruebas de carga medidas. El trabajo de rendimiento sin mediciones es solo manualidades.
7) Síntoma: “MySQL server has gone away” y luego WordPress muestra error de conexión
- Causa raíz: max packet demasiado pequeño para consultas grandes, timeouts de conexiones inactivas, reinicio de BD o interrupciones de red.
- Solución: Revise los logs de BD por reinicios, ajuste timeouts y
max_allowed_packetsi procede, y mejore la fiabilidad de la red entre capas.
Modos de fallo de almacenamiento y sistema de archivos que se hacen pasar por “BD caída”
Aquí está la verdad impopular del ingeniero de almacenamiento: muchos incidentes de “conexión a la base de datos” son incidentes de almacenamiento con bigote falso.
La latencia de disco es un problema de conectividad disfrazado
Si InnoDB no puede flushear, aplicará contrapresión. Las consultas se encolan. Los hilos se acumulan. Las conexiones alcanzan timeouts. Desde la perspectiva de WordPress, la BD podría estar desenchufada.
Vigile:
- Alta presión de fsync: los flushes del redo log se quedan atascados en discos lentos.
- Tormentas de swap: la presión de memoria de la BD empuja páginas fuera; la latencia se dispara.
- Amplificación de escritura: tablas temporales en disco, grandes ordenaciones, estados
Copying to tmp table.
Agotamiento de inodos: la forma ridícula de caer
Las bases de datos crean archivos, tablas temporales, binlogs y redo logs. Si se agotan los inodos, el SO se niega amablemente. MySQL se degrada de forma poco amable. Su WordPress solo mostrará el mismo error genérico, porque por supuesto lo hará.
Remonteo en solo lectura: la catástrofe silenciosa
Ext4 con errors=remount-ro le hace un favor: intenta no agravar la corrupción. Pero convierte cada escritura en un fallo, y las bases de datos son mayoritariamente escrituras disfrazadas de lecturas.
Almacenamiento en red y “la BD está lenta hoy”
Si su base de datos está en almacenamiento en red, un array sobrecargado puede traducirse en segundos de latencia a nivel de bloques. MySQL esperará pacientemente. Los clientes no. Si está en la nube en volúmenes compartidos, también puede ser objeto de throttling. El SO rara vez lo anuncia con fanfarria; simplemente se vuelve lento.
Prevención que realmente funciona (no intuiciones)
Prevenir no es “añadir más CPU.” Para la fiabilidad de la BD en WordPress, la prevención trata de controlar la concurrencia, estabilizar la latencia de almacenamiento y hacer visibles las fallas antes de que sean un mensaje en la portada.
1) Ponga la base de datos en almacenamiento que se comporte bajo presión
- Use almacenamiento SSD/NVMe para el directorio de datos de MySQL y los redo logs.
- Prefiera NVMe local sobre volúmenes de IOPS misteriosas en red para sitios de alto tráfico.
- Monitoree la latencia de disco (
await,%util) igual que monitorea la CPU.
2) Limite la concurrencia en la capa web
Si se permite a PHP-FPM spawnear un pequeño ejército, lo hará. Entonces cada worker abre conexiones a la BD, y su base de datos se vuelve el portero más triste del mundo.
- Fije
pm.max_childrenrazonable según CPU, memoria y capacidad de BD. - Use caché para tráfico anónimo. La mayoría de páginas WordPress no necesitan golpear la BD por cada petición.
- Limite la tasa en endpoints de login y XML-RPC si no los necesita.
3) Haga de la “conectividad BD” un SLO monitorizado, no una superstición
Monitoree:
- Tiempo de conexión TCP desde nodos web a BD (checks sintéticos).
- MySQL
Threads_connected,Threads_runningy conexiones abortadas. - Latencia de disco y contadores de errores del sistema de archivos.
- Explosiones de volumen del slow query log.
4) Backups que restauren, no backups que existan
Un backup que no ha sido restaurado es un cuento para dormir. Practique restauraciones con regularidad, incluyendo:
- Dump lógicos para portabilidad (
mysqldumpo equivalente). - Backups físicos para velocidad (snapshots consistentes a nivel de archivos o herramientas de backup).
- Recuperación punto en el tiempo si tiene binlogs y un plan.
5) Evite puntos únicos de fallo cuando importe
No todos los sitios WordPress necesitan HA, pero si su negocio sí, constrúyalo:
- Primario/replica con failover automatizado (probado cuidadosamente).
- Separe la capa web de la BD para que escalar una no desestabilice la otra.
- Checks de salud que detecten “la BD acepta conexiones y puede ejecutar consultas”, no solo “el puerto está abierto”.
6) Mantenga WordPress sensato: reduzca carga de consultas y sorpresas
- Audite plugins. Cada plugin es un DBA potencial que no contrató.
- Use caché de objetos correctamente (y mírelo).
- Mantenga WordPress core y PHP actualizados por mejoras de rendimiento y estabilidad.
Broma #2: Un plugin prometió “optimización con un clic”, lo cual es cierto—un clic es todo lo que hace falta para optimizar su sitio hasta causar una caída.
Listas de verificación / plan paso a paso
Durante el incidente: lista de estabilización de 15 minutos
- Confirmar impacto: ¿Es todas las páginas o un subconjunto? ¿El error está cacheado por la CDN?
- Comprobar salud BD: estado del servicio, listener, registros.
- Probar desde host web: conecte usando
mysqlcon credenciales de WordPress. - Comprobar saturación: conexiones, hilos en ejecución, consultas lentas.
- Comprobar almacenamiento: disco lleno, inodos agotados, I/O wait, remonteo en solo lectura.
- Mitigar: reducir concurrencia (temporalmente), matar consultas desbocadas, desactivar plugin ofensivo si hace falta.
- Comunicar: establezca un ritmo claro de actualizaciones de estado con lo que sabe y lo que hará a continuación.
Tras la estabilización: lista de causa raíz (mismo día)
- Extraiga ventanas de error de MySQL, PHP-FPM y registros del servidor web.
- Correlacione con métricas: conexiones, latencia de disco, CPU, memoria, errores de red.
- Identifique el detonante: pico de tráfico, despliegue, cambio de plugin, evento de almacenamiento, cambio de DNS.
- Anote el modo exacto de fallo (ej.:
max_connectionsalcanzado, agotamiento de inodos, remonteo en solo lectura). - Implemente un cambio de prevención con plan de rollback.
- Añada/ajuste monitores para que esto provoque una alerta antes la próxima vez (o nunca más).
Lista de endurecimiento (semanal/mensual)
- Probar restauraciones de backups.
- Revisar la lista de plugins y eliminar peso muerto.
- Revisar consultas lentas y oportunidades de índices.
- Comprobar tendencias de crecimiento de disco y uso de inodos.
- Parchear OS, BD y PHP con un proceso controlado.
- Revisar capacidad: conteos de workers PHP-FPM vs max_connections de BD vs hardware.
Tres micro-historias corporativas desde el terreno
Micro-historia 1: El incidente causado por una suposición equivocada
La empresa tenía una arquitectura “simple”: un par de nodos web y un servicio de base de datos gestionado. El equipo migró WordPress a nuevos servidores web para obtener una versión más reciente de PHP y mejor CPU. Todo parecía bien en staging. El corte en producción se programó para una mañana tranquila.
El corte sucedió, DNS cambió y llegó el tráfico. En minutos: Error al establecer una conexión con la base de datos. Las métricas de la BD parecían normales. La BD estaba “arriba”. Los nodos web estaban saludables. Naturalmente, todos miraron a WordPress como si los hubiera traicionado personalmente.
La suposición errónea estaba incrustada en una sola línea: DB_HOST estaba configurado como localhost en los servidores antiguos, porque la arquitectura antigua tenía la BD en el mismo host años atrás. Durante migraciones anteriores, alguien había usado “temporalmente” un túnel SSH y nunca limpió la lógica de configuración. En los servidores nuevos no había MySQL local. WordPress intentó conectarse consigo mismo. Falló de forma predecible.
Arreglarlo fue trivial: apuntar DB_HOST al endpoint gestionado de BD, desplegar y listo. La lección duradera no fue “actualizar DB_HOST.” Fue: no deje que la deriva de infraestructura viva dentro de configuraciones de aplicación sin pruebas que verifiquen la topología. El equipo añadió una comprobación preflight para validar la conectividad BD desde cada nodo web antes de cualquier flip de DNS.
Micro-historia 2: La optimización que salió mal
Otra organización tenía un mandato de rendimiento. Las páginas eran lentas y alguien sugirió: “Aumentemos los workers de PHP-FPM para que las peticiones no hagan cola.” Sonaba razonable. Los servidores web tenían CPU libre. El cambio se desplegó durante horario laboral porque el riesgo “parecía bajo”.
El resultado fue inmediato: WordPress empezó a mostrar errores de conexión a la base de datos de forma intermitente. No una caída total, solo lo suficiente para arruinar conversiones y hacer que soporte se sintiera perseguido. MySQL estaba alcanzando límites de conexiones y la latencia de consultas se disparó. La BD no estaba dimensionada para la nueva concurrencia. Más workers de PHP significaron más conexiones simultáneas a la BD, más misses de caché y más presión en los flushes de InnoDB.
El equipo intentó lo instintivo: aumentar max_connections. Eso compró minutos, luego el servidor se quedó sin memoria y empezó a hacer swap. Ahora todo era lento: la BD, los nodos web, incluso los accesos SSH. Esto ya no era “un problema de WordPress.” Era una cascada de agotamiento de recursos.
El rollback lo solucionó. La corrección fue aburrida: añadir caché para tráfico anónimo, fijar límites sensatos de PHP-FPM, añadir índices a las consultas peores y escalar almacenamiento/IOPS de la BD. La mayor “optimización” fue simplemente no generar trabajo innecesario.
Micro-historia 3: La práctica aburrida pero correcta que salvó el día
Una compañía de medios ejecutaba WordPress como parte de una plataforma mayor. La BD era un primario único con una réplica caliente. Nada sofisticado. Lo interesante fue su disciplina: pruebas rutinarias de restauración y un runbook de failover documentado que vivía en el mismo repo que el código de infra.
Una tarde, el host primario de BD experimentó errores de sistema de archivos tras una actualización de kernel y reinicio. Volvió, pero el volumen de datos se remonteó en solo lectura. MySQL arrancó y luego falló progresivamente mientras intentaba escribir. WordPress mostró el error de conexión. Tuvieron unos cinco minutos de confusión, luego el on-call reconoció el patrón: “funcionando, pero sin escribir.”
No intentaron heroicidades en un sistema de archivos dañado. Ejecutaron el runbook: promovieron la réplica, actualizaron el endpoint de BD y reiniciaron nodos web para vaciar conexiones obsoletas. El tráfico se recuperó rápidamente. Después repararon el primario fuera de línea y lo resembraron correctamente.
La práctica salvadora no fue automatización mágica. Fue competencia ensayada y aburrida: backups validados, pasos de failover conocidos y una cultura de equipo que no trata los sistemas de archivos como inmortales.
Datos interesantes y contexto (breve y concreto)
- Dato 1: WordPress empezó en 2003, y la dependencia de MySQL ha estado ahí desde el principio; el error de “conexión a la BD” ha perseguido a administradores durante dos décadas.
- Dato 2: Durante muchos años, el driver de BD por defecto de WordPress fue la antigua extensión
mysql; las instalaciones modernas usanmysqli, lo que cambia cómo se comportan sockets y timeouts. - Dato 3: El comportamiento de MySQL ante “Too many connections” es abrupto: una vez que alcanza el límite, nuevas sesiones fallan de inmediato, incluso si el servidor está sano por lo demás.
- Dato 4: InnoDB se convirtió en el motor por defecto en MySQL 5.5; antes de eso MyISAM era común y las reparaciones de “tabla caída” eran más rutinarias.
- Dato 5: Los TTL de DNS pueden mantener endpoints de BD antiguos en cachés de clientes mucho más tiempo de lo esperado, especialmente en resolutores de contenedores y demonios de caché locales.
- Dato 6: La confusión socket Unix vs TCP es anterior a WordPress: los clientes pueden usar sockets por defecto para “localhost” pero TCP para “127.0.0.1”, lo que puede cambiar rutas de autenticación y permisos.
- Dato 7: Muchos plugins de WordPress implementan sus propias capas de caché de forma pobre; una caché de objetos mal configurada puede aumentar la carga de BD en lugar de reducirla.
- Dato 8: El tiempo de recuperación por crash de InnoDB es proporcional al tamaño del redo log y la carga; tras un crash, “la BD está arriba” puede significar aún “la BD está ocupada reparándose”.
- Dato 9: Los sistemas de archivos que se remontean en solo lectura ante errores son una característica de seguridad, no un bug—las bases de datos simplemente lo odian profundamente.
Preguntas frecuentes
1) ¿Por qué WordPress muestra el mismo error para fallos distintos?
Porque la falla ocurre en tiempo de conexión, antes de que WordPress pueda cargar opciones o ejecutar consultas significativas. No puede distinguir “contraseña incorrecta” de “host de BD ardiendo” sin exponer detalles. Necesita comprobaciones a nivel de plataforma.
2) ¿Debo reiniciar MySQL inmediatamente?
Sólo si ha comprobado primero los registros y los síntomas de almacenamiento. Reiniciar puede ayudar si el demonio está atascado, pero también puede empeorar la recuperación por crash o esconder el problema real. Si ve errores de disco o remonteo en solo lectura, reiniciar es culto de la carga.
3) ¿Cómo sé si es credenciales o conectividad?
Ejecute mysql -h ... -u ... -p -e "SELECT 1;" desde el servidor web usando las credenciales en wp-config.php. “Access denied” significa auth/grants. “Can’t connect” significa red/listener/firewall. Los timeouts suelen indicar saturación o bloqueos I/O.
4) ¿Por qué ocurre solo durante picos de tráfico?
Porque la concurrencia multiplica todo. Más peticiones → más workers PHP → más conexiones a BD → más contención de bloqueos y presión de flush. Si está cerca de capacidad, un pico lo empuja a rechazo de conexiones y timeouts.
5) ¿Aumentar max_connections es una buena solución?
A veces es un parche a corto plazo. A largo plazo puede salir mal al aumentar uso de memoria y cambio de contexto. Arregle el lado de la demanda (caché, optimización de consultas, limitación de tasa) y el lado de la oferta (recursos BD) juntos.
6) ¿Un disco lleno puede causar un error de conexión a la base de datos?
Sí. Disco lleno o inodos agotados puede impedir que MySQL cree tablas temporales o escriba logs, llevando a bloqueos y fallos que se manifiestan como problemas de conexión en la capa de aplicación.
7) ¿Cuál es la mitigación segura más rápida si la BD está sobrecargada?
Reduzca la carga primero: habilite/verifique caché de página completa para tráfico anónimo, limite endpoints abusivos y fije límites de workers PHP-FPM. Matar las consultas peores puede comprar tiempo, pero no es una estrategia por sí sola.
8) ¿Cómo prevengo meltdowns de BD causados por plugins?
Ejecute cambios de plugins como despliegues: rollout escalonado, comparación de métricas y plan de rollback. Además audite plugins trimestralmente. Menos código es menos caos.
9) ¿Por qué cambiar DB_HOST de localhost a 127.0.0.1 a veces “lo arregla”?
Porque fuerza TCP en lugar de socket Unix. Si la ruta del socket es incorrecta o los permisos son raros, TCP puede evitar el problema. Es una mitigación válida; la solución real es una configuración consistente de sockets.
10) Si la base de datos es remota, ¿cuál es el culpable oculto más frecuente?
La fiabilidad de la ruta de red y la resolución de nombres. Un pequeño cambio de DNS, una regla de firewall o un problema de enrutamiento pueden parecer exactamente una caída de BD desde el punto de vista de WordPress.
Conclusión: siguientes pasos que puede hacer hoy
Este error de WordPress es un síntoma, no una causa. Trátelo como un incidente de producción: aísle rápido el dominio de la falla, aplique mitigaciones quirúrgicas y luego arregle los problemas subyacentes de capacidad/configuración/almacenamiento para que no vuelva a repetirse.
- Escriba su runbook de diagnóstico rápido usando las tareas arriba, adaptado a su entorno (BD local vs BD gestionada, socket vs TCP).
- Añada dos monitores hoy: latencia sintética web-a-BD y latencia de disco en el host/volumen de BD.
- Limite la concurrencia (PHP-FPM y servidor web) según la capacidad de la BD, no por deseo.
- Pruebe restauraciones de backups esta semana. No “verifique que existen.” Réstoreselos.
- Audite plugins y elimine todo lo que esté sin mantenimiento, redundante o “instalado temporalmente” desde 2019.