Hub

greco-cell

greco-cell

active medium work
Creado
2026-05-08
Actualizado
2026-05-29
Directorios
  • /home/sergio/code/greco-cell

Pendientes abiertos (3)

Ver todos →

🎯 Top de ataque (3)

  • #097 📅 2026-06-04 Recopilar / revisar la lista de requerimientos pendientes del cliente.
  • #098 📅 2026-06-06 Reanudar trabajo activo.
  • #095 📅 2026-06-10 Diagnosticar la razón por la que a veces hay que reiniciar mysql y/o php-fpm.

Actividad en bitácora 2 días

jun
jul
ago
sep
oct
nov
dic
ene
feb
mar
abr
may
L
X
V
Menos
Más

Greco Cell — Punto de venta

Contexto

Sistema de punto de venta para el cliente personal Greco Cell (telefonía celular). Cliente personal de Sergio, no facturado vía Electrosystems.

Estado real: activo pero sin movimiento reciente. Hay requerimientos pendientes que Sergio quiere reanudar (estado paralelo a deportescampeon).

Tareas pendientes

  • #097 📅 2026-06-04 — Recopilar / revisar la lista de requerimientos pendientes del cliente.
  • #098 📅 2026-06-06 — Reanudar trabajo activo.
  • #095 📅 2026-06-10 — Diagnosticar la razón por la que a veces hay que reiniciar mysql y/o php-fpm.

En progreso

(Nada activo. Proyecto en pausa de facto.)

Notas técnicas

🚨 Runbook: incidente activo (mysql/php-fpm)

Cuando Sergio diga “ya está pasando en grecocell” — leer este bloque y ejecutar en orden. NO reiniciar nada hasta tener el snapshot.

Acceso: ssh grecocell (llave id_rsa_es, user sergio, NOPASSWD para mysql y mysqladmin). Todo lo siguiente es read-only.

Paso 1 — captura inmediata (≤30s):

ssh grecocell '
echo "=== processlist ==="
sudo -n mysql -e "SELECT ID,USER,HOST,DB,COMMAND,TIME,STATE,LEFT(INFO,300) FROM information_schema.processlist WHERE COMMAND NOT IN (\"Sleep\",\"Daemon\") ORDER BY TIME DESC;"
echo "=== innodb status (locks/waits) ==="
sudo -n mysql -e "SHOW ENGINE INNODB STATUS\G" | sed -n "/LATEST DETECTED DEADLOCK\|TRANSACTIONS\|LATEST FOREIGN/,/^---/p" | head -80
echo "=== memoria/io ahora ==="
free -h; echo "---"; vmstat 1 3
echo "=== fpm workers + mysql conn ==="
pgrep -c -f "php-fpm: pool"; ss -ant | awk "\$5 ~ /:3306\$/ || \$4 ~ /:3306\$/ {c++} END {print c+0}"
'

Paso 2 — snapshot histórico (los 10-15 min previos):

ssh grecocell 'tail -20 /var/log/grecocell-snapshot.log'

Buscar: mysql_slow_running subiendo sostenido, fpm cerca de 96, mem_avail_mb cayendo.

Paso 3 — slow log:

ssh grecocell 'sudo -n mysql -e "SELECT start_time, user_host, query_time, lock_time, rows_examined, LEFT(sql_text,400) FROM mysql.slow_log ORDER BY start_time DESC LIMIT 20\G"'

La query culpable casi seguro aparece aquí. Anotar rows_examined y patrón (SELECT ... FROM cortes WHERE fecha BETWEEN ...).

Paso 4 — nginx 504 confirmation (no requiere sudo de Antigravity):

ssh grecocell 'tail -200 /var/log/nginx/access.log 2>/dev/null | awk "\$9 ~ /^5/" | tail -20'

Si los logs son root:adm sin acceso, pedir a Sergio: sudo tail -200 /var/log/nginx/error.log.

Paso 5 — descartar OOM: Pedir a Sergio (necesita sudo password): sudo dmesg -T | tail -50 | grep -iE "oom|kill|memory".

Paso 6 — decisión de reinicio:

  • Si hay query atorada identificada en processlist → sudo mysqladmin -uroot kill <ID> (mata SOLO esa query, sin reiniciar mysql entero). Workers fpm se desbloquean solos.
  • Si fpm está pegado pero mysql ya no tiene queries lentas → sudo systemctl reload php8.3-fpm (más suave que restart).
  • Si todo lo demás falla → restart mysql (perderemos slow log volátil — exportar antes con paso 3).

Tras estabilizar: dejar correr 15 min más para que snapshot capture el “post-incidente”, luego presentar a Sergio diagnóstico + propuesta de fix permanente (probable: índice missing en cortes.fecha o cortes.sucursal_id).

Stack

  • Local: Laravel 11 + Livewire 3 + PHP 8.2 (composer.json). Sail para dev. (Nota previa “Inertia + Vue” del 2026-05-08 estaba incorrecta — es Livewire.)
  • Prod (VPS DigitalOcean, host grecocell en ~/.ssh/config, IP 24.199.99.50):
    • Ubuntu 24.10, kernel 6.11.0-29-generic
    • MySQL 8.0.42, nginx 1.26.0, PHP 8.3.11-FPM
    • 3.8 GB RAM, 0 swap, uptime 292 días (al 2026-05-15)
    • App en /var/www/grecocell, user sergio con sudo
    • SSH llave id_rsa_es

Config relevante de prod (descubierta 2026-05-15)

  • PHP-FPM pool (/etc/php/8.3/fpm/pool.d/www.conf):
    • pm = dynamic, pm.max_children = 96 ← alto para 3.8 GB
    • pm.start_servers = 6, pm.min/max_spare = 6/19, pm.max_requests = 500
    • Socket UNIX /run/php/php8.3-fpm.sock
  • MySQL (defaults excepto donde indique):
    • max_connections = 151, innodb_buffer_pool_size = 128 MB (default)
    • wait_timeout = interactive_timeout = 28800
    • Max_used_connections = 13 desde último restart de mysql (~5.6 días) → bajo, sin saturación de conexiones
  • nginx: site /etc/nginx/sites-enabled/grecocell, fastcgi_read_timeout default 60s
  • Slow query log: activado dinámicamente 2026-05-15 con long_query_time=1.0, log_output=TABLE,FILE, archivo en /var/lib/mysql/grecocell-slow.log. Cambio volátil — se pierde al reiniciar mysql; pendiente persistir en mysqld.cnf si la config nos sirve.

Setup de diagnóstico instalado 2026-05-15

  • Script /usr/local/bin/grecocell-snapshot.sh corre cada 60s vía grecocell-snapshot.timer (systemd).
  • Log /var/log/grecocell-snapshot.log owner sergio:sergio, rotado por logrotate (14 días, compress).
  • Cada línea registra: load, mem_used_mb, mem_avail_mb, fpm (workers), mysql_thr_conn,run, mysql_slow_running (queries no-Sleep, no-Daemon, TIME>3), conn3306 (TCP only).
  • Baseline en reposo: load <0.1, fpm=6-12, mysql_thr 1-3, conn3306 7-14, mem_avail ~2.8 GB.

Acceso de Antigravity

  • SSH a grecocell vía ~/.ssh/config, llave id_rsa_es.
  • NOPASSWD configurado por Sergio 2026-05-15 para mysql y mysqladmin.
  • Otros sudo (sed, install, systemctl, journalctl, dmesg, cat de logs root) requieren password — pedir a Sergio cuando haga falta.

Hipótesis de los reinicios mysql/php-fpm

  • Síntoma: timeout de nginx (504), generalmente noches a hora de cierre, cuando varias sucursales corren el reporte diario. Pasa de forma errática (antes ~cada 1-2 días, ahora menos tras cambios sin documentar). A veces reiniciar mysql arregla; a veces hay que reiniciar php-fpm.
  • Ruta probable: /cortes/reporte (CortesController::reporte, paginado a 100, filtra por fecha + sucursales con whereDate y whereIn).
  • Hipótesis principal (2026-05-15): una query de cortes/reporte ocasionalmente cruza 60s (timeout nginx), no por saturación de conexiones (Max_used_connections=13) sino por single-query lenta posiblemente sin índice apropiado o con N+1 amplificado. Reiniciar mysql mata la query; reiniciar fpm libera workers atorados esperándola. El slow log debería capturar la culpable antes del próximo 504.
  • Hipótesis secundaria: memoria — pm.max_children=96 con 3.8 GB y 0 swap es un riesgo si la query se vuelve pesada en RAM (Eloquent + relaciones grandes), pero el patrón de conexiones no la apoya como causa primaria.

Pendiente de documentar aquí

  • Lista concreta de requerimientos pendientes del cliente.

Bitácora

2026-05-08

  • Pidió Sergio: registrar el proyecto.
  • Hice: archivo creado con cliente y status.
  • Falta: todo — necesita ser revisitado.

2026-05-15

  • Pidió Sergio: preparar todo para diagnosticar los reinicios mysql/php-fpm la próxima vez que pasen — él avisa, yo ya con permisos y contexto listo.
  • Hice:
    • Inventario completo de stack prod (Ubuntu 24.10, MySQL 8.0.42, PHP 8.3-FPM, nginx 1.26, 3.8 GB RAM sin swap, uptime 292 días).
    • Identificada ruta sospechosa: CortesController::reporte (/cortes/reporte).
    • Descubierto pool FPM max_children=96 (alto para 3.8 GB) y MySQL Max_used_connections=13 (bajo → debilita hipótesis de saturación).
    • A. Slow query log activado dinámicamente (long_query_time=1.0, log_output=TABLE,FILE, archivo en /var/lib/mysql/grecocell-slow.log). Volátil — se pierde al reiniciar mysql.
    • B. Snapshot cada 60s instalado: /usr/local/bin/grecocell-snapshot.sh + systemd timer grecocell-snapshot.timer + logrotate. Log en /var/log/grecocell-snapshot.log (owner sergio:sergio, lo leo sin sudo). Captura: load, mem, fpm workers, mysql threads, slow_running, conn3306. Verificado funcionando con baseline limpio.
    • C. NOPASSWD para mysql/mysqladmin configurado por Sergio para que yo pueda correr SHOW PROCESSLIST / SHOW ENGINE INNODB STATUS sin esperarlo.
    • Plan de diagnóstico documentado en sección “Notas técnicas” arriba.
  • Falta:
    • Esperar al próximo incidente. Sergio avisa.
    • Si la config nos sirve tras el primer incidente, persistir slow log en /etc/mysql/mysql.conf.d/mysqld.cnf.
    • Acciones correctivas (índices, tuning, swap, bajar max_children, etc.) — solo después de tener evidencia del slow log + snapshot.