Error ‘tiempo de espera de conexión a la base de datos’ en Mastodon autoalojado: solución
🔍 WiseChecker

Error ‘tiempo de espera de conexión a la base de datos’ en Mastodon autoalojado: solución

Cuando autoalojas una instancia de Mastodon, el servicio depende de una base de datos PostgreSQL para almacenar publicaciones, cuentas y datos de la línea de tiempo. Un error de “tiempo de espera de conexión a la base de datos” significa que los procesos web o de streaming de Mastodon no pueden alcanzar la base de datos dentro del límite de tiempo configurado. Esto ocurre típicamente debido a agotamiento de recursos, pools de conexiones mal configurados o latencia de red entre el servidor de aplicaciones y el servidor de base de datos. Este artículo explica las causas raíz de este error de tiempo de espera y proporciona soluciones paso a paso para restaurar el funcionamiento normal.

Puntos clave: Restaurar la conectividad de la base de datos en tu instancia de Mastodon

  • Configuración max_connections de PostgreSQL: Limita las conexiones simultáneas; auméntala si tu instancia tiene muchos usuarios o servicios.
  • Variable de entorno DB_POOL de Mastodon: Controla el tamaño del pool de conexiones por proceso; configúrala para que coincida con los límites de PostgreSQL.
  • Comando pg_isready: Herramienta de diagnóstico rápida para comprobar si PostgreSQL acepta conexiones.

ADVERTISEMENT

Por qué Mastodon informa un tiempo de espera de conexión a la base de datos

La aplicación Mastodon utiliza el framework Ruby on Rails con el ORM ActiveRecord para comunicarse con PostgreSQL. Cuando una solicitud web o un trabajo en segundo plano intenta abrir una conexión a la base de datos, el sistema espera una ranura del pool o un handshake TCP. Si no hay ninguna ranura disponible dentro del período de tiempo de espera (por defecto 5 segundos), Rails lanza un ActiveRecord::ConnectionTimeoutError. Este error aparece en los registros como “could not obtain a database connection within 5.000 seconds” o similar.

Causas raíz comunes

Tres factores causan la mayoría de los tiempos de espera:

  • Agotamiento del pool de conexiones: Cada proceso de Mastodon (servidor web Puma, trabajadores Sidekiq y API de streaming) toma prestadas conexiones de un pool local. Si el tamaño del pool es demasiado pequeño y todas las ranuras están en uso, las nuevas solicitudes se ponen en cola y eventualmente agotan el tiempo de espera.
  • Límite de conexiones de PostgreSQL alcanzado: La base de datos en sí tiene un límite estricto (por defecto 100 conexiones). Si Mastodon más cualquier otro cliente excede este límite, PostgreSQL rechaza nuevas conexiones.
  • Cuellos de botella de red o recursos: El alto uso de CPU o memoria en el servidor de base de datos, o un enlace de red lento entre el contenedor de Mastodon y el host de la base de datos, puede retrasar el handshake más allá del tiempo de espera.

Pasos para solucionar el tiempo de espera de conexión a la base de datos

Estos pasos asumen que tienes acceso SSH a tu servidor Mastodon y puedes editar el archivo de configuración del entorno, típicamente .env.production en el directorio de Mastodon. También necesitas acceso sudo para reiniciar servicios y modificar la configuración de PostgreSQL.

  1. Comprueba el límite actual de conexiones de PostgreSQL
    Ejecuta sudo -u postgres psql -c "SHOW max_connections;" en el servidor de base de datos. El valor por defecto es 100. Si tu instancia atiende a más de unas pocas docenas de usuarios activos, aumenta este valor.
  2. Aumenta max_connections en postgresql.conf
    Edita /etc/postgresql//main/postgresql.conf. Encuentra la línea max_connections = 100 y súbela a 200 o más. Por ejemplo, max_connections = 300. Reinicia PostgreSQL con sudo systemctl restart postgresql.
  3. Verifica la configuración DB_POOL de Mastodon
    Abre .env.production en el directorio principal de Mastodon. Busca DB_POOL. Si no está, añade DB_POOL=25. Este valor no debe exceder max_connections dividido por el número total de procesos de Mastodon. Para un solo Puma y un proceso Sidekiq, 25 es seguro.
  4. Reinicia los servicios de Mastodon
    Ejecuta systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming para cargar la nueva configuración del pool. Si usas Docker Compose, ejecuta docker-compose restart.
  5. Monitorea el uso de conexiones
    Usa sudo -u postgres psql -c "SELECT count(
    ) FROM pg_stat_activity;" para ver las conexiones activas. Compara esto con el límite max_connections. Si el recuento se mantiene cerca del límite, necesitas un pool más grande o más recursos de base de datos.
  6. Reduce la concurrencia de Sidekiq si es necesario
    En .env.production, verifica SIDEKIQ_CONCURRENCY. El valor por defecto es 10. Cada trabajador concurrente usa una conexión de base de datos. Si tienes muchos procesos Sidekiq, reduce la concurrencia a 5 y prueba.
  7. Añade un pooler de conexiones de base de datos como PgBouncer
    Si tu instancia crece más allá de 500 usuarios, instala PgBouncer. Actúa como un proxy ligero que reutiliza las conexiones de base de datos. Configura PgBouncer con un tamaño de pool de 50 y establece DB_POOL de Mastodon a 5. Esto previene tormentas de conexiones.

ADVERTISEMENT

Si Mastodon aún tiene problemas después de la solución principal

El tiempo de espera persiste después de aumentar max_connections y DB_POOL

Si el error continúa, el servidor de base de datos en sí puede estar sobrecargado. Verifica el uso de CPU y memoria con htop o top. Si PostgreSQL usa el 100% de CPU, considera actualizar el hardware del servidor o mover la base de datos a una máquina dedicada. También verifica que el servidor Mastodon pueda alcanzar el host de la base de datos en el puerto 5432 sin pérdida de paquetes. Ejecuta ping -c 10 [database-ip] y busca paquetes perdidos.

El tiempo de espera de conexión solo afecta a los trabajos en segundo plano de Sidekiq

Los trabajadores Sidekiq manejan tareas como entregar toots y procesar medios. Si agotan el tiempo de espera pero la interfaz web funciona, el proceso Sidekiq puede tener una configuración REDIS_URL o de base de datos separada. Asegúrate de que .env.production contenga el mismo DATABASE_URL tanto para Puma como para Sidekiq. También verifica que Redis no esté sobrecargado: un Redis lento puede hacer que Sidekiq mantenga las conexiones de base de datos por más tiempo del esperado.

El error aparece después de agregar un nuevo servicio de Mastodon

Si recientemente agregaste un segundo proceso Puma o una cola Sidekiq adicional, el número total de conexiones de base de datos puede exceder max_connections. Multiplica el número de procesos por sus valores DB_POOL. Por ejemplo, dos procesos Puma con DB_POOL=25 cada uno usan hasta 50 conexiones. Agrega Sidekiq con concurrencia 10 y llegas a 60. Asegúrate de que max_connections de PostgreSQL sea al menos un 20% superior a este total.

DB_POOL de Mastodon vs max_connections de PostgreSQL: Comparación

Elemento DB_POOL (Mastodon) max_connections (PostgreSQL)
Descripción Número máximo de conexiones de base de datos por proceso de Mastodon Número máximo total de conexiones permitidas por el servidor de base de datos
Valor por defecto 5 o 10 dependiendo de la versión de Mastodon 100
Dónde configurarlo .env.production archivo postgresql.conf
Efecto de un valor demasiado bajo Errores de tiempo de espera de conexión bajo carga Nuevas conexiones rechazadas después de alcanzar el límite
Efecto de un valor demasiado alto Desperdicia memoria; puede exceder el límite de PostgreSQL Consume RAM; puede degradar el rendimiento
Recomendado para instancia pequeña 10 100
Recomendado para instancia mediana 25 200

Ahora puedes diagnosticar y resolver los errores de “tiempo de espera de conexión a la base de datos” en tu instancia de Mastodon autoalojada ajustando las configuraciones de max_connections y DB_POOL. Comienza verificando el límite actual de PostgreSQL con pg_isready y el comando SHOW max_connections. Después de aplicar las correcciones, monitorea los recuentos de conexiones con pg_stat_activity para confirmar que el tiempo de espera ya no ocurre. Para una estabilidad a largo plazo en instancias más grandes, considera implementar PgBouncer para agrupar conexiones de manera eficiente y prevenir futuros tiempos de espera.

ADVERTISEMENT