Quando vários hosts Linux compartilham o diretório inicial do Codex (~/.codex por padrão) pelo Network File System (NFS), eles podem corromper um banco de dados SQLite se o abrirem ao mesmo tempo no modo de registro antecipado de gravação (WAL). Para trabalhar de forma interativa na CLI ou no Codex App via SSH, migre o diretório inicial compartilhado. Para executar tarefas em lote independentes, mantenha o diretório inicial do Codex ou o diretório do SQLite no disco local de cada host.
Por que o NFS pode causar problemas no SQLite
O Codex App e a interface do terminal usam um índice SQLite para listar as conversas. Os bancos de dados também armazenam as metas e o estado do processamento das memórias. Em disco local, o Codex normalmente usa o modo WAL. Processos em hosts diferentes não conseguem compartilhar a memória de que o WAL precisa.
Quando detecta NFS no Linux, o Codex cria os bancos de dados no modo de diário de reversão (DELETE), que usa bloqueios de arquivo. Migre os bancos de dados existentes que usam WAL antes de abri-los em outro host.
O Codex também salva os eventos das conversas em arquivos rollout-*.jsonl. Esses arquivos já podem ficar no NFS porque apenas um processo por vez grava em cada arquivo. A migração do SQLite mantém esses arquivos onde estão.
Migre um diretório inicial existente em NFS
1. Verifique o diretório inicial compartilhado
Execute codex --version em cada host, inclusive nos que funcionam como backend SSH. Use uma versão que inclua codex migrate-nfs-db, como a Codex CLI 0.166.0. Confirme que todos os hosts que compartilham esse diretório inicial usam o mesmo diretório do SQLite. Peça ao administrador de armazenamento que verifique se um bloqueio de arquivo mantido em um host impede que o outro obtenha um bloqueio conflitante. Se a montagem não garantir esse comportamento, mantenha o SQLite no disco local.
Durante a migração, não defina nem altere o diretório inicial do SQLite ou o diretório de logs.
2. Pare o Codex em todos os hosts
Conclua os turnos ativos, feche o aplicativo e a CLI e pare os servidores remotos do aplicativo, os daemons em segundo plano e as tarefas agendadas que usam esse diretório inicial. Mantenha todos eles parados em todos os hosts até o fim da migração. Se outro processo gravar no banco de dados durante a migração, ele poderá corromper o banco e causar a perda de alterações em metas ou memórias.
Os registros das sessões ficam em arquivos separados e não permitem restaurar todo o estado do banco de dados.
No modo daemon, a CLI se conecta a um servidor em segundo plano que continua em execução entre as sessões. O socket Unix desse servidor só funciona no host que o iniciou. Recomendamos executar a CLI sem o daemon quando vários hosts compartilham um diretório inicial do Codex via NFS. Pare o daemon em cada host em que ele estiver em execução com o comando codex app-server daemon stop.
Para impedir que a CLI volte a iniciá-lo, defina daemon_auto_start como false na seção [features] do arquivo config.toml compartilhado.
[features]
daemon_auto_start = false
Para uma única sessão da CLI, passe a opção --no-daemon. Com essa opção, a CLI também ignora qualquer daemon que já esteja em execução.
3. Execute a migração
Para cada diretório inicial compartilhado do Codex, execute a migração em apenas um host Linux. Use a conta do proprietário do diretório e a configuração que ele usa normalmente. Mantenha o Codex parado nos outros hosts até o fim da migração.
codex migrate-nfs-db
4. Retome uma conversa
Se o comando exibir Skipped logs database, verifique onde está o banco de dados de logs. Se estiver em disco local, nenhuma outra ação será necessária. Se estiver no NFS, confirme que ele usa o modo de diário DELETE ou mova-o para o disco local antes de reabrir o Codex em outro host.
Depois que a migração for concluída com sucesso, abra o mesmo projeto em outro host com a mesma conta de usuário. Retome uma conversa conhecida no aplicativo ou execute codex --no-daemon resume. Verifique se o último turno aparece e se você consegue continuar a conversa.
Mova os logs de diagnóstico para o disco local
Etapa opcional, recomendada após a migração. Os logs de diagnóstico ajudam a investigar erros e a identificar por que o Codex demora para iniciar. Gravá-los no disco local reduz o tráfego no NFS.
Crie em cada host um diretório de logs privado no qual o usuário possa gravar. Defina log_dir no arquivo config.toml do usuário como o caminho absoluto do diretório de logs desse usuário. Por exemplo, Alice poderia usar a seguinte configuração.
log_dir = "/var/local/codex/alice/logs"
Os novos logs são gravados nesse diretório. Os antigos permanecem onde estão.
Quando a configuração gerenciada define sqlite_home, o banco de dados de logs do SQLite permanece no diretório exigido mesmo que você defina log_dir. Consulte a configuração gerenciada.
Aplique o modo de diário a todos os hosts de uma frota
Primeiro, pare todos os clientes em cada host que usa um dos diretórios iniciais afetados. O nome da configuração inclui unsafe porque converter um banco de dados enquanto outro host grava nele pode corrompê-lo.
Com os clientes parados, adicione a opção abaixo à configuração gerenciada dos hosts, no arquivo /etc/codex/requirements.toml.
unsafe_enforce_sqlite_journal_mode = true
A configuração se aplica a todos os usuários dos hosts configurados. Na próxima vez que um usuário iniciar o Codex, o aplicativo migrará automaticamente os bancos de dados WAL existentes à medida que os abrir para gravação no NFS. Para cada diretório inicial compartilhado, aguarde o fim da migração em um host antes de reconectar os demais. Se a migração falhar, mantenha os outros clientes parados e siga as etapas de recuperação.
Execute tarefas em lote independentes
Se uma tarefa executada sem supervisão não precisar do histórico das suas sessões interativas, execute codex exec com um diretório inicial do Codex no disco local do executor. Se os arquivos de sessão precisarem ficar no NFS, defina CODEX_SQLITE_HOME como um diretório local privado para cada tarefa. Assim, os executores não disputarão o acesso ao mesmo banco de dados.
- Mantenha um registro da conversa. Atribua a cada tarefa um
CODEX_HOMEprivado e persistente para o registro da sessão e umCODEX_SQLITE_HOMEprivado no disco local do host para o banco de dados. O índice do executor é separado do índice das suas sessões interativas. Mantenha o registro da sessão em$CODEX_HOME/sessions/se precisar inspecionar a tarefa depois que o executor terminar. - Mantenha apenas o resultado. Coloque o diretório inicial da tarefa no disco local e execute
codex exec --ephemeral. Assim, o Codex não salva uma sessão que possa ser retomada. Use-opara gravar a resposta final em um arquivo persistente ou--jsonpara transmitir os eventos ao executor da tarefa à medida que ocorrem.
Se a tarefa precisar de um registro da sessão, configure o agendador para criar os dois diretórios e provisionar a autenticação e a configuração no diretório inicial da tarefa. Substitua os caminhos do exemplo pelos caminhos do diretório inicial persistente do Codex para essa tarefa e do diretório do SQLite no disco local do executor. Se a opção sqlite_home estiver definida na configuração gerenciada ou na configuração do usuário, ela terá precedência sobre CODEX_SQLITE_HOME.
CODEX_HOME="/mnt/nfs/codex/jobs/job-1234" \
CODEX_SQLITE_HOME="/var/local/codex/jobs/job-1234" \
codex exec "Summarize this repository's build steps."
Perguntas frequentes
Como saber se um erro está relacionado ao NFS?
Um erro de migração como cannot open source database exclusively indica que o Codex não conseguiu bloquear o banco de dados. Outro cliente também pode causar esse erro em disco local. No Linux, execute findmnt -T "$DB_PATH" com o caminho do banco de dados afetado. Se o comando exibir nfs ou nfs4, verifique em todos os hosts se há processos gravando no banco e peça ao administrador de armazenamento que verifique se o bloqueio entre hosts funciona nessa montagem. Pare os clientes que ainda estiverem em execução antes de tentar novamente.
O que devo verificar na saída da migração?
Para cada banco de dados, o Codex exibe as mensagens Migrated database: e WAL backup:, ou a mensagem Already in DELETE mode:. Se você depende de permissões de grupo ou de regras de acesso estendidas, verifique essas permissões e regras após a migração, antes de reabrir os clientes.
Se log_dir já estava definido, o comando pula o banco de dados de logs. Antes de compartilhar esse banco entre hosts, confirme que ele usa o modo DELETE ou mantenha-o no disco local.
Se aparecer No databases found., verifique o diretório do SQLite que está em uso para o usuário proprietário do diretório inicial. Se faltar espaço local para os arquivos temporários da migração, escolha um diretório no disco local do host com espaço suficiente e passe o caminho absoluto com --staging-dir.
Como faço a recuperação se a migração falhar?
Mantenha os outros clientes parados. Anote a mensagem de erro exata, o caminho do banco de dados e o caminho da cópia de segurança exibido pelo comando. Alguns bancos de dados podem já ter sido migrados. Mantenha o banco de dados original e seus arquivos auxiliares juntos no diretório de backup correspondente. Depois de resolver um erro de bloqueio ou de falta de espaço, execute codex migrate-nfs-db novamente no mesmo host. Se houver um erro de integridade ou se o arquivo substituto estiver ausente, trabalhe com cópias antes de restaurar qualquer arquivo. Os registros das sessões podem ajudar a reconstruir o histórico das conversas. Para recuperar o estado armazenado exclusivamente no SQLite, incluindo as metas, é preciso ter um banco de dados íntegro.
Antes de iniciar uma sessão separada da CLI, confirme que as configurações gerenciadas de armazenamento não redirecionarão as gravações para o diretório inicial afetado. Em seguida, inicie o Codex usando um diretório temporário no disco local. Talvez seja necessário fazer login ao usar o novo diretório inicial.
recovery_home=$(mktemp -d /tmp/codex-nfs-recovery.XXXXXXXX) &&
CODEX_HOME="$recovery_home" CODEX_SQLITE_HOME="$recovery_home" \
codex --no-daemon --sandbox read-only \
"Help me recover a failed Codex NFS migration, run `$ codex doctor` to get the information about corrupted databases. Backup paths for databases should be in the original database with `_wal_migration_backup` in the end of the file. Ask user for the original error. Plan a recovery using copies and leave the originals untouched."