5.4 KiB
5.4 KiB
Convex — Loop do application::exports::worker (Nov/2025)
Documento técnico descrevendo o incidente que derrubava o backend Convex em produção e o passo a passo adotado para corrigir e evitar recorrências.
1. Resumo Executivo
- Sintoma visível: o WebSocket
wss://convex.esdrasrenan.com.br/api/1.29.2/synccaía em código 1006 a cada poucos segundos. - Causa raiz: um export agendado automaticamente pelo próprio Convex (
application::exports::worker) reiniciava toda vez que o backend subia. Durante o “replay” o worker lia documentos (principalmente máquinas e cron jobs antigos) cujo shape já não batia com o esquema atual, causando panic emshape_inference/src/object.rs:67. - Impacto: o container
sistema_convex_backendreiniciava em loop.npx convex deploye qualquer CLI que dependesse do backend ficavam presos emstart_push/wait_for_schema. O frontend ficava sem sincronização em tempo real. - Correção aplicada: saneamento manual do banco SQLite do Convex (limpeza de cron/exports/records incompatíveis) seguido de um restart completo. O export pendente finalizou com sucesso e o backend estabilizou.
2. Detecção
docker service logs --tail 400 sistema_convex_backendmostrava:- Mensagens repetidas do export (
Export gg20vw5b... progress: ...). - Panics em
application::exports::workeroucommon::errorscom mensagensObject with shape ... not in Shape ....
- Mensagens repetidas do export (
- No navegador e no
npx convex deploy, as conexões WebSocket encerravam com código 1006.
3. Diagnóstico / Root Cause Analysis
- O Convex self-hosted mantém exports incrementais. Quando o backend reinicia, o worker reprocessa o export pendente.
- Em
sistema_convex_data, a tabeladocumentspossuía registros legados:- Cron
hours-usage-alerts-hourly(já removido do código). - Documentos de máquinas com
metadata/customFieldsmaiores do que o shape compilado.
- Cron
- Assim que o export lia esses documentos “fora do shape”, o Convex fazia
panic!, derrubando o processo principal. - Como o export jamais completava, o worker reiniciava e o ciclo se repetia.
4. Procedimento de Recuperação (Runbook)
⚠️ Sempre trabalhar em cima do volume
sistema_convex_data.
Todos os comandos abaixo devem ser executados comorootna VPS.
4.1. Parar o backend e fazer backup
docker service scale sistema_convex_backend=0
# Guardar uma cópia datada
docker run --rm -v sistema_convex_data:/convex/data \
busybox sh -c 'ts=$(date +%Y%m%d%H%M%S); cp /convex/data/db.sqlite3 /convex/data/db.sqlite3.backup-$ts'
4.2. Inspecionar o banco (SQLite)
Usamos a imagem nouchka/sqlite3, montando o volume:
docker run --rm -it -v sistema_convex_data:/convex/data nouchka/sqlite3 /convex/data/db.sqlite3
Consultas úteis:
-- Verificar o export pendente
SELECT json_value FROM documents
WHERE json_extract(json_value, '$.name') = 'hours-usage-alerts-hourly';
-- Identificar documentos de máquinas problemáticos
SELECT hex(id), hex(table_id), ts
FROM documents
WHERE json_extract(json_value, '$._id') = 'jn7aq2647e6g69qbrg7q9n6aas7sxqje';
4.3. Sanear dados incompatíveis
- Cron legado
DELETE FROM documents WHERE hex(table_id) = 'C24DDDBFBA00025744D7672E2AC74F91' AND json_extract(json_value, '$.name') = 'hours-usage-alerts-hourly'; - Máquina fora do shape
- Remover índices ligados ao documento:
DELETE FROM indexes WHERE document_id = X'AB88C43B8D0326EBC40F74D4CA564F9E'; - Remover o documento em si:
DELETE FROM documents WHERE id = X'AB88C43B8D0326EBC40F74D4CA564F9E';
- Remover índices ligados ao documento:
- (Opcional) Qualquer export/cron adicional pode ser limpado usando o mesmo padrão:
DELETEna tabeladocumentse correspondentes emindexes.
4.4. Subir o backend e validar
docker service scale sistema_convex_backend=1
docker service logs --tail 400 -f sistema_convex_backend
Critérios de sucesso:
- Logs mostram
application::exports::worker ... completede, logo após,No exports requested or in progress. - Não existem novas linhas
Caught error/shape_inference. - WebSocket
/api/1.29.2/syncvolta a responder 101 Switching Protocols.
5. Pós-incidente / Prevenção
- Desabilitar jobs pesados por padrão: já deixamos
REPORTS_CRON_ENABLED=falseeAUTO_PAUSE_ENABLED=falsenas variáveis. Mantê-las assim até que o Convex publique um fix oficial. - Sempre limpar exports antigos antes de alterar schema: se um export for rodado manualmente, aguardá-lo completar antes de editar tabelas grandes (
machines,ticketWorkSessionsetc.). - Monitorar logs após deploys:
docker service logs sistema_convex_backend | rg exports::workerajuda a verificar se há novos exports presos. - Documentar qualquer alteração direta no SQLite: registrar no repositório (neste arquivo) os comandos executados, garantindo um histórico completo.
6. Referências rápidas
- Volume Convex:
sistema_convex_data - Banco:
/convex/data/db.sqlite3 - Contêiner SQLite:
nouchka/sqlite3 - Parar/Subir serviço:
docker service scale sistema_convex_backend=0|1 - Arquivo anterior de referência:
/convex/data/db.sqlite3.pre-export-clean-20251118123551
Última revisão: 18/11/2025 — sanado por remoção dos registros incompatíveis e rerun bem-sucedido do export gg20vw5b479d9a2jprjpe3pxg57vk9wa.