Volver a la wiki

Workflow D1 Cleanup — purga diaria de bib_index_runs, bib_change_log y auth_codes

Workflow D1 Cleanup — purga diaria de bib_index_runs, bib_change_log, auth_codes y activity_log

Resumen

Workflow de GitHub Actions (D1 Cleanup) que purga cada noche las tablas D1 que acumulan filas sin control en crearacksl-workspace-db. Introducido en PR#49 (2026-05-18, s71) para bib_index_runs y bib_change_log; PR#201 (2026-09-27, #381) añade una cuarta tabla, activity_log, y un paso de recorte para las filas que ya llevaban los args del MCP sin resumir.

ParámetroValor
Fichero.github/workflows/d1-cleanup.yml
Trigger programadocron: "30 2 * * *" (02:30 UTC / 04:30 CEST)
Trigger manualworkflow_dispatch habilitado
Timeout6 minutos (subido de 3 en PR#201 al añadir los pasos de activity_log)
Concurrenciagrupo d1-cleanup, cancel-in-progress: false
Toggle de pausavars.BIBLIOTECARIO_PAUSADO != 'true'

Tablas purgadas

1. bib_change_log — cambios detectados entre indexaciones

DELETE FROM bib_change_log
WHERE changed_at < datetime('now', '-30 days')

2. bib_index_runs — historial de ejecuciones del Bibliotecario

DELETE FROM bib_index_runs
WHERE started_at < datetime('now', '-30 days')
  AND id NOT IN (
    SELECT run_id FROM bib_change_log WHERE run_id IS NOT NULL
  )
DELETE FROM auth_codes
WHERE used_at IS NOT NULL
   OR created_at < datetime('now', '-1 hour')

4. activity_log — registro de actividad (retención 180 días + recorte de args del MCP)

Añadida en PR#201 (#381, decisión de Edu del 27-09-2026). Motivo: cada llamada del MCP se registraba con los args enteros en details.args (functions/api/mcp/index.ts), y las indexaciones periódicas de la Biblioteca (bib_index_docs/bib_index_chunks, cada 15 min) llevan como arg el texto completo de lo que indexan. El 27-09-2026 esto eran 1.975 filas y 93 de los 255 MB totales de la D1 — 93 de los 119 MB de la copia diaria de esa noche.

Paso 4 — retención de 180 días:

DELETE FROM activity_log WHERE timestamp < datetime('now', '-180 days')

La primera fila de activity_log es del 12-04-2026, así que este DELETE no borra nada real hasta mediados de octubre de 2026.

Paso 5 — recorte de filas antiguas ya guardadas enteras:

UPDATE activity_log
SET details = json_object('tool', json_extract(details, '$.tool'), 'recortado', 1)
WHERE source = 'mcp'
  AND length(details) > 4000
  AND json_valid(details)
  AND json_extract(details, '$.tool') IS NOT NULL

Orden de ejecución y razón (FK)

Paso 1: bib_change_log > 30d       ← primero (referencia run_id)
Paso 2: bib_index_runs > 30d       ← segundo (referenciado por change_log)
Paso 3: auth_codes                  ← independiente
Paso 4: activity_log > 180d         ← independiente (sin FK)
Paso 5: recorte activity_log MCP    ← independiente, idempotente

Los pasos 3, 4 y 5 no tienen dependencias de FK entre sí ni con los pasos 1-2; su orden actual en el workflow es por convención (orden de introducción), no por necesidad.


Toggle de pausa global

if: ${{ vars.BIBLIOTECARIO_PAUSADO != 'true' }}

El mismo flag vars.BIBLIOTECARIO_PAUSADO que usan los demás crons del Bibliotecario (reindex-ts a las 00:15, curator a las 03:00). Si se activa el flag, este workflow queda en skip automático sin necesidad de deshabilitarlo manualmente — afecta a los 5 pasos por igual, incluidos los dos nuevos de activity_log.


Planificación horaria

00:15 UTC  →  reindex-ts   (Bibliotecario)
02:30 UTC  →  D1 Cleanup   ← este workflow
03:00 UTC  →  curator      (Bibliotecario)

La ventana 02:30 fue elegida para evitar contención sobre crearacksl-workspace-db con los otros dos crons. Los pasos 4 y 5 (activity_log) se ejecutan dentro de la misma ventana, tras la copia diaria de las 00:00.


Cleanup manual ejecutado en s71 (2026-05-18)

Antes de activar el workflow programado, se ejecutó un one-shot manual con los siguientes resultados:

TablaFilas borradas
bib_index_runs475
bib_change_log84
auth_codes4

Tras el cleanup: 0 filas > 30 días pendientes en bib_index_runs.


Operación en producción

Verificar último run

gh run list --workflow 'D1 Cleanup' --limit 5

Ejecutar manualmente (one-shot)

gh workflow run d1-cleanup.yml

Pausar el workflow sin deshabilitarlo

# Activar flag global (pausa D1 Cleanup + reindex-ts + curator)
gh variable set BIBLIOTECARIO_PAUSADO --body 'true'

# Reactivar
gh variable set BIBLIOTECARIO_PAUSADO --body 'false'

Ver qué hay en la BD antes de purgar (diagnóstico)

# Filas acumuladas en bib_index_runs
wrangler d1 execute crearacksl-workspace-db --remote \
  --command "SELECT COUNT(*) as total, MIN(started_at) as oldest FROM bib_index_runs"

# Filas > 30 días
wrangler d1 execute crearacksl-workspace-db --remote \
  --command "SELECT COUNT(*) FROM bib_index_runs WHERE started_at < datetime('now', '-30 days')"

# Filas de activity_log aun sin resumir (details > 4000 bytes, llamadas MCP)
wrangler d1 execute crearacksl-workspace-db --remote \
  --command "SELECT COUNT(*) FROM activity_log WHERE source = 'mcp' AND length(details) > 4000"

Alertas y posibles problemas

SíntomaCausa probableAcción
Workflow en skip sin falloBIBLIOTECARIO_PAUSADO=truegh variable set BIBLIOTECARIO_PAUSADO --body 'false'
DELETE falla con FK errorOrden de pasos alterado o migración añadió FK nuevaRevisar schema D1, restaurar orden paso 1 → 2
0 filas borradas en bib_index_runsLas filas tienen change_log asociados (protección NOT IN)Normal si el paso 1 no borró nada tampoco
auth_codes crece sin pararUsuarios no completan el magic-link y el cron no purgaVerificar que created_at < -1h cubre el TTL real configurado
activity_log sigue pesando tras el recorteEl recorte solo toca source = 'mcp' con tool; llamadas web o de otros crons no se resumenNormal — revisar de qué source son las filas grandes antes de tocar la query
El Worklog muestra “0 elementos” en una llamada que sí tenía listaLa fila es antigua y aún no pasó por el paso 5, o summarizeArgs truncó el arg como string largo en vez de listaComprobar details en crudo; no es un bug del Worklog si la fila es pre-27-09-2026

Véase también

Subir