feat(storage): implement per-user DB isolation and migration tooling#167
Conversation
Add the per-user database isolation RFC covering shared-vs-user DB split, restore safety, snapshot/branch handling, migration, and metadata reconciliation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR migrates Memoria from a legacy single shared database to a shared control-plane DB plus per-user mem_u_* databases, adding routing, migration tooling, and updating snapshot/branch behavior to be per-database scoped.
Changes:
- Add
DbRouterand split storage migrations intomigrate_user()andmigrate_shared()to support multi-DB routing. - Introduce an offline CLI migration flow (
memoria migrate legacy-to-multi-db) with dry-run/execute and JSON reporting. - Scope snapshot operations to user databases and update MCP/API/service layers to use routed per-user stores.
Reviewed changes
Copilot reviewed 27 out of 28 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| memoria/crates/memoria-storage/src/store.rs | Add optional DbRouter, split migrations, route edit-log/access patterns, scope safety snapshots by DB |
| memoria/crates/memoria-storage/src/router.rs | New shared→user DB router with registry + lazy per-user DB provisioning |
| memoria/crates/memoria-storage/src/migration.rs | New legacy→multi-db migration planner/executor + report + identifier bounding |
| memoria/crates/memoria-storage/src/lib.rs | Export router/migration modules and types |
| memoria/crates/memoria-storage/Cargo.toml | Add sha2 dependency for user DB hashing |
| memoria/crates/memoria-service/tests/plugin_repository.rs | Update test config with shared DB fields |
| memoria/crates/memoria-service/src/service.rs | Route per-user operations via DbRouter, adjust batching/caches, disable rebuild worker in multi-db |
| memoria/crates/memoria-service/src/scheduler.rs | Update test config with shared DB fields |
| memoria/crates/memoria-service/src/pipeline.rs | Persist phase now resolves per-user SQL store in multi-db mode |
| memoria/crates/memoria-service/src/governance.rs | Route governance operations across per-user DBs when router is enabled |
| memoria/crates/memoria-service/src/config.rs | Add shared_db_url and multi_db toggle + effective SQL URL helper |
| memoria/crates/memoria-mcp/tests/snapshot_e2e.rs | Align snapshot internal naming with scoped model + duplicate-create behavior |
| memoria/crates/memoria-mcp/tests/branch_e2e.rs | Add merge/replace regression test with mock embedder |
| memoria/crates/memoria-mcp/src/tools.rs | Route MCP tools to per-user SQL stores; adjust snapshot health + branch-aware queries |
| memoria/crates/memoria-mcp/src/git_tools.rs | Scope snapshot naming by DB, route git ops per user store, improve merge replace behavior |
| memoria/crates/memoria-git/src/service.rs | Create snapshots FOR DATABASE and filter SHOW SNAPSHOTS by database |
| memoria/crates/memoria-cli/src/main.rs | Add migrate command and wire multi-db startup (router + shared store) |
| memoria/crates/memoria-api/src/state.rs | Route batcher flush/rebuild APIs via MemoryService for multi-db |
| memoria/crates/memoria-api/src/routes/snapshots.rs | Resolve per-user git/sql context for snapshot reads/diffs |
| memoria/crates/memoria-api/src/routes/sessions.rs | Make session summary query branch-aware via active table |
| memoria/crates/memoria-api/src/routes/metrics.rs | Aggregate metrics across per-user DBs + use shared pool for shared tables |
| memoria/crates/memoria-api/src/routes/memory.rs | Route profile/history/retrieval params via per-user SQL store + branch-aware stats query |
| memoria/crates/memoria-api/src/routes/governance.rs | Route governance endpoints via per-user SQL store and scope cooldown keys |
| memoria/crates/memoria-api/src/routes/auth.rs | Use shared auth pool for API key operations (no per-user store assumption) |
| memoria/crates/memoria-api/src/routes/admin.rs | Aggregate admin stats across per-user stores and use shared pool where appropriate |
| memoria/crates/memoria-api/src/auth.rs | Route tool-usage and call-log batch flush/rebuild via per-user stores in multi-db |
| memoria/Cargo.lock | Lockfile update for new dependency |
| docs/per-user-database-architecture.md | New architecture RFC/design doc for per-user DB isolation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Code Review Report — PR #167
📊 概览
📝 总结PR 的设计方向正确——从单 DB 行级隔离升级为 per-user DB 隔离,根治了 但实现呈现典型的 "先实现后打补丁" 模式:6 个 commit 中 3 个是 patch(主 commit 后 12 分钟就开始打补丁)。核心问题集中在三个方面:(1) 连接池爆炸 — 每用户创建独立 🧨 破坏性测试审判
🔴 Must Fix1. 连接池爆炸 + 无界缓存 —
|
| 议题 | 老K | 铁壁 | 闪电 | 测姐 | 补丁犬 | 裁决 |
|---|---|---|---|---|---|---|
| 连接池爆炸 | 🔴 | — | 🔴 | — | 🟡 | 🔴 Must Fix (共识) |
| DDL SQL 注入 | 🔴 | 🔴 | — | — | 🟢 | 🔴 Must Fix (共识) |
| 凭据日志泄露 | — | 🔴 | — | — | — | 🔴 Must Fix |
| Multi-DB 零测试 | 🟢 | ⚪ | — | 🔴 | 🔴 | 🔴 Must Fix (共识) |
| N+1 查询 | — | — | 🟡 | — | 🟡 | 🟡 Should Fix (共识) |
| Router 双持有 | 🔴 | — | — | — | — | 🟡 降级 (设计改进, 不阻塞功能) |
| 补丁链 | — | — | — | — | 🔴 | 🔴 升为 Must Fix (并发安全) |
🤖 Generated by 7-agent jury code review system v1.5 · Agents: 老K(架构), 铁壁(安全), 闪电(性能), 测姐(测试), 补丁犬(代码健康) · 定锤(裁判) synthesis by orchestrator
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔄 Re-review Report — PR #167
🔴 修复状态
📊 改善摘要
🟡 仍待关注1. migration.rs 仍无集成测试1137 行迁移代码(含 2.
|
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
@mergify requeue |
Merge Queue Status
Required conditions to enter a queue
|
## Summary - rebase the branch onto current `upstream/main`, keeping only the follow-up fixes that are not already included by `#167` and `#169` - stabilize the per-user DB rollout by finishing the routed-store / DB-switching follow-ups and fixing multi-db stats routing - remove access-count ranking bias from retrieval scoring, refresh the architecture guide, add the cutover runbook, and expose MCP trust-tier guidance with strict validation ## Validation - `cargo test -p memoria-mcp --test tools_unit test_tools_list -- --nocapture` - DB-backed tests still require a live MatrixOne/MySQL instance via `DATABASE_URL` (default: `mysql://root:111@localhost:6001/...`); current local environment has no listener on `6001` Approved by: @XuPeng-SH
Summary
mem_u_*databasesmemoria migrate legacy-to-multi-dbdry-run/execute flow, including a pre-execute MatrixOne safety snapshot and JSON reportingsnapshot_e2ewith the scoped naming modelValidation
make checkcargo test -p memoria-service --libcargo test -p memoria-mcp --libcargo test -p memoria-api --libcargo test -p memoria-storage --libcargo test -p memoria-git --libcargo test -p memoria-mcp --test snapshot_e2e -- --test-threads=1mem_u_*user DBs995/995), execute migration, migrated API 13-user 10m soak (5122/5122), all with0non-2xx and0exceptionsNotes
mem_api_keys, registry, locks/tasks/plugins), while user data/branches/snapshots live in dedicated routed DBsalready existsmessage instead of bubbling into an internal error