Skip to content

EdgeClaw Memory scheduled maintenance 偶发 SQLite database is locked #121

Description

@DemonswhisperYe

标注

AI 提交(由用户授权的 AI 助手根据本机日志与源码检查整理)。

问题描述

PilotDeck 在启用 EdgeClaw Memory 后,运行过程中会偶发出现 SQLite 报错:database is locked

该问题不是单个 workspace 的数据库损坏;从日志看,多个 memory workspace 都出现过同类锁错误。发生时会导致 memory scheduler / maintenance 任务失败,并可能在用户会话执行期间伴随 gateway retry 或错误事件。

观察到的报错

日志文件:~/.pilotdeck/server-3001.log

出现过的典型日志:

[server] [memory-scheduler] scheduled maintenance failed for /home/ye/.pilotdeck/memory/workspaces/8547594726: Error: database is locked
  code: 'ERR_SQLITE_ERROR',
  errcode: 5,
  errstr: 'database is locked'
[server] [memory-scheduler] scheduled maintenance failed for /home/ye/.pilotdeck/memory/workspaces/da975b3393: Error: database is locked
    at MemoryRepository.deletePipelineState (.../src/context/memory/edgeclaw-memory-core/lib/core/storage/sqlite.js:709:75)
    at EdgeClawMemoryService.runDueScheduledMaintenance (.../src/context/memory/edgeclaw-memory-core/lib/service.js:687:36)
  code: 'ERR_SQLITE_ERROR',
  errcode: 5,
  errstr: 'database is locked'
[server] [memory-scheduler] scheduled maintenance failed for /home/ye/.pilotdeck/memory/workspaces/80be3f1ce8: Error: database is locked
    at MemoryRepository.deletePipelineState (.../src/context/memory/edgeclaw-memory-core/lib/core/storage/sqlite.js:709:75)
    at EdgeClawMemoryService.runDueScheduledMaintenance (.../src/context/memory/edgeclaw-memory-core/lib/service.js:669:36)
  code: 'ERR_SQLITE_ERROR',
  errcode: 5,
  errstr: 'database is locked'

另有 gateway 侧日志:

[gateway] database is locked

涉及的 workspace 不止一个

本机日志中至少出现过以下 memory workspace:

/home/ye/.pilotdeck/memory/workspaces/8547594726
/home/ye/.pilotdeck/memory/workspaces/da975b3393
/home/ye/.pilotdeck/memory/workspaces/80be3f1ce8

读取 pipeline_state.workspaceDir 后,对应关系大致为:

8547594726  workspace=/home/ye/projects/PilotDeck
80be3f1ce8  workspace=/home/ye/.pilotdeck/projects/gongzuoqu2
da975b3393  workspace=/home/ye/.pilotdeck

进程与文件句柄证据

运行时观察到两个 PilotDeck 相关 Node 进程同时打开同一批 memory SQLite 文件:

PID 2528  node --import tsx /home/ye/projects/PilotDeck/ui/server/index.js
PID 2557  node ... src/cli/pilotdeck.ts server --port 18790

二者均持有类似文件句柄:

/home/ye/.pilotdeck/memory/workspaces/80be3f1ce8/control.sqlite
/home/ye/.pilotdeck/memory/workspaces/80be3f1ce8/control.sqlite-wal
/home/ye/.pilotdeck/memory/workspaces/80be3f1ce8/control.sqlite-shm

/home/ye/.pilotdeck/memory/workspaces/8547594726/control.sqlite
/home/ye/.pilotdeck/memory/workspaces/8547594726/control.sqlite-wal
/home/ye/.pilotdeck/memory/workspaces/8547594726/control.sqlite-shm

/home/ye/.pilotdeck/memory/workspaces/da975b3393/control.sqlite
/home/ye/.pilotdeck/memory/workspaces/da975b3393/control.sqlite-wal
/home/ye/.pilotdeck/memory/workspaces/da975b3393/control.sqlite-shm

相关源码位置

本地源码检查发现,Web server 和 Gateway 都会触发 memory maintenance。

Web server 侧:

// ui/server/services/memoryService.js
const MEMORY_SCHEDULER_INTERVAL_MS = 60_000;

async function executeScheduledMaintenanceForDataDir(dataDir) {
  const { service } = getOrCreateServiceForDataDir(dataDir);
  return enqueueMaintenanceTask(dataDir, async () =>
    service.runDueScheduledMaintenance('scheduled:server_scheduler')
  );
}

Gateway 侧:

// src/cli/createLocalGateway.ts
scheduleMemoryMaintenance(projectKey?: string): void {
  const runtime = this.resolve(projectKey);
  const service = runtime.memoryService;
  if (!service) return;
  ...
  await service.runDueScheduledMaintenance("scheduled");
}

报错堆栈对应的写入点:

// src/context/memory/edgeclaw-memory-core/lib/core/storage/sqlite.js
deletePipelineState(key) {
  this.db.prepare("DELETE FROM pipeline_state WHERE state_key = ?").run(key);
}

SQLite 初始化中观察到 WAL:

PRAGMA journal_mode = WAL;

影响

  • memory scheduler / maintenance 偶发失败;
  • 多个 workspace 都可能触发,不局限于单一项目;
  • 发生在用户交互/任务执行期间时,可能导致日志中出现 retry 或错误事件;
  • 当前观察中 pending sessions 没有长期积压,但该错误会反复污染日志,并可能导致维护任务未按预期完成。

环境信息

  • OS: Linux 6.17.0-35-generic x64
  • Node.js: v24.15.0
  • PilotDeck 启动方式:systemd user service
  • 相关服务:
node --import tsx /home/ye/projects/PilotDeck/ui/server/index.js
node ... src/cli/pilotdeck.ts server --port 18790

期望行为

EdgeClaw Memory 的 scheduled maintenance 在多进程/多 runtime 同时存在时,不应因为 SQLite 写锁直接失败;至少不应让常规维护任务反复产出 database is locked 错误。

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions