Repository navigation
Conversation
|
CI failed |
The resumable-target fingerprint accepted db/database query parameters as authority overrides, which the OceanBase config validator now rejects. Take the database from the URL path, refuse the overrides at this boundary too, and cover the policy directly so the runner no longer documents a capability it cannot reach.
| async with _initialized_profile(cls(database=database, tables=tables)) as profile: | ||
| yield profile | ||
| try: | ||
| await ensure_database( |
There was a problem hiding this comment.
[P2] Prevent read-only migration commands from provisioning databases
The plan and verify actions of server atomic-memory-migrate and server processing-migrate still call this opener with tables=(), so an absent target now triggers CREATE DATABASE during read-only inspection; the seekDB opener has the same regression. Provide a non-provisioning connection path for these actions and reserve database creation for startup or writable maintenance.
There was a problem hiding this comment.
补上调用方证据,确认只读命令确实走到新建库这条路径(同根因,不另开线程)。
src/powercontext/server/cli.py的原子记忆迁移命令里read_only = action in {"plan", "verify"}只对 SQLite 生效:SQLite 分支用SQLiteProfile.open_readonly(...),而OceanBaseConfig与SeekDBConfig分支在read_only为真时仍调用OceanBaseProfile.open(database, tables=())/SeekDBProfile.open(database, tables=())。本 PR 让这两个open()无条件执行ensure_database(...),因此plan/verify会先发CREATE DATABASE IF NOT EXISTS ...,随后在写事务里跑plan_processing_migration。- 同文件里处理迁移的另一入口(
action == "plan"→plan_processing_migration)同样通过OceanBaseProfile.open/SeekDBProfile.open,路径一致。 SeekDBProfile.open在ensure_database之前还会执行_require_explicit_legacy_database:数据库名未显式设置时它连接 legacytest库查information_schema.TABLES。只读校验命令因此多了一次与实际检查目标无关的库连接。- 这不是「设计如此」:
src/powercontext/builtin/persistence/migrations/connections.py里就区分了writable,writable=False时对 seekdb 走elif not await database_is_available(engine): return operation(None, identity, lambda: None),而_oceanbase完全不调用ensure_database。同一语义在两个入口实现不一致。
建议:OceanBaseProfile.open / SeekDBProfile.open 增加 provision: bool = True(或等价的只读开关),read_only 分支传 False,此时目标库不存在直接按 database_is_available(...) 的结果报错而不是创建;并在两条 CLI 上各补一条「目标库缺失时 plan / verify 不创建库、不产生 DDL」的回归断言。
There was a problem hiding this comment.
复审说明:本条上一条回复基于 5e760476,在该条发布后不到一分钟 head 已前移到 b719edfe(fix(storage): prevent read-only migration commands from creating databases),上一条指出的路径在新 head 上已被覆盖,结论更新如下。
已核对 b719edfe:
OceanBaseProfile._connect(provision=...)与SeekDBProfile._connect(provision=...)拆出open_existing(...);provision=False时走新增的require_existing_database(...),缺库抛MissingDatabaseError,不再发CREATE DATABASE。_processing_maintenance与_atomic_memory_maintenance都按read_only = action in {"plan", "verify"}选择open_existing,两个入口一致;两个 CLI 命令都把MissingDatabaseError转成可读的typer.BadParameter,且apply不受影响。SeekDBGraphStore/open_code_service未受影响,仍用open()(provision 默认开),符合运行时需要。
残留一处,请确认是否需要一并处理:SeekDBProfile._connect 在 provision=False 时仍然先执行 path.parent.mkdir(parents=True, exist_ok=True),再 _open_instance(module, path),之后才 require_existing_database(...)。也就是说,对不存在的 seekdb 路径执行 plan / verify,DB 层已经不再建库,但本地可能仍会留下父目录与一个空实例目录。本机没有 Linux + pylibseekdb,无法实测 aopen() 在路径缺失时是否落盘创建,因此这里只作为待确认项:若 aopen() 会创建,建议在只读分支先判 path.exists() 并用与 MigrationConnections 相同的 unsupported_target 语义拒绝,或在 MissingDatabaseError 前记录并清理本次新建的目录。
|
|
||
| def creation_statement(engine: AsyncEngine, name: str) -> str: | ||
| """Render the exact statement an administrator runs to provision this database.""" | ||
| quoted = engine.dialect.identifier_preparer.quote_identifier(validate_database_name(name)) |
There was a problem hiding this comment.
[P2] Render administrator SQL without driver percent escaping
When provisioning is denied for an accepted name such as team%ctx, the MySQL dialect's quote_identifier() produces team%%ctx, which is embedded verbatim in the administrator instructions. Executing that SQL in a SQL client creates the wrong database and leaves startup failing; render administrator-facing SQL separately from the statement escaped for DBAPI execution.
| config.model_copy(update={"echo": False}), instance.connection_options() | ||
| ) | ||
| try: | ||
| await seekdb_profile._require_explicit_legacy_database(config, instance.connection_options()) |
There was a problem hiding this comment.
[P2] Translate legacy selection failures into migration errors
When seekDB has pc_ tables in test and no explicit database name, this probe raises LegacySeekDBDatabaseError, which db-migrate's _operator_errors() does not handle. The commands therefore produce an uncaught exception instead of the documented JSON error; translate this expected rejection into a MigrationError while preserving the explicit-selection guidance.
There was a problem hiding this comment.
补充该调用确由本 PR 新增,以及异常确实不被收敛的证据。
connections.py:144的_require_explicit_legacy_database(...)由本 PR 加入(git diff master...2fef5fab的 hunk@@ -136,6 +141,17 @@)。LegacySeekDBDatabaseError继承PersistenceError(RuntimeError);server/database_migration.py::_operator_errors只捕获MigrationError/ServerConfigurationError/SQLAlchemyError/OSError/ServiceError,同文件另一处也只有except (ServiceError, OSError)⇒ 该异常以 traceback 冒出,不会产生文档里的{"state":"blocked","error":...}JSON。- 现有测试只覆盖 Server/e2e 启动路径(
tests/builtin/persistence/test_database_bootstrap.py、tests/e2e/test_database_bootstrap.py),db-migrate这一支无覆盖。本机无真实 seekdb 实例,本结论为源码推导,未做真实实例复现。
建议在 _seekdb 内把这个预期拒绝转成 MigrationError("explicit_database_required", str(error))(保留原文里的 database 选择指引),并补一条 CLI 级断言 JSON 输出的用例。
There was a problem hiding this comment.
复审 b0e379f6(fix(storage): preserve legacy seekdb migration errors):本条在 db-migrate 支已闭合,但同一异常在其余 CLI 入口仍有残留。
已闭合部分
migrations/connections.py新增_require_explicit_database(),把LegacySeekDBDatabaseError转成MigrationError("explicit_database_required", str(error)),保留原指引文本;_operator_errors()因此能产出文档里的{"state":"blocked","error":...}。- P3 线程(4309776833)的 echo 问题同批修掉:探针引擎改用
config.model_copy(update={"echo": False})。 - 镜像 head 树 12 条新用例全绿(
test_database_migration_connections.py、test_seekdb_profile.py、test_database_migration_cli.py、test_atomic_memory_migration_cli.py、test_processing_migration_cli.py)。 - 变异反证(
probes/mutate_r14.py,一次性副本内):把_require_explicit_database换回直接调用后,test_seekdb_legacy_database_refusal_is_a_maintenance_error恰好转红并复现原签名LegacySeekDBDatabaseError;把model_copy(echo=False)换回config后test_legacy_database_probe_never_echoes_sql转红(assert True is False);删掉atomic_memory_migrate的LegacySeekDBDatabaseError分支后该用例 3/4 参数红、rebuild-projection因自带 catch 仍绿。
残留:server identity-reset 未转换
探针 probes/probe_identity_reset_r14.py(stub SeekDBProfile.open/open_existing 直接抛 LegacySeekDBDatabaseError,不打开任何数据库):
atomic-memory-migrate --action verify --maintenance-confirmed → exit 2,输出含 POWERCONTEXT_SERVER_DATABASE_DATABASE 指引
identity-reset --maintenance-confirmed → exit 1,stdout 为空,异常原样逃出(终端表现为 traceback)
identity_reset() 里 asyncio.run(_reset_server_identity(settings)) 外层没有对应 catch,而 server/identity.py::open_server_identity_repository 走的是同一个 SeekDBProfile.open ⇒ 同一份拒绝消息在 identity 轮换路径上仍以未捕获异常出现。身份轮换本身未执行,无数据风险,影响限于操作者可见的错误形态不一致。
建议:在该命令外层加同样的 except LegacySeekDBDatabaseError(powercontext code 也经 SeekDBProfile.open,如需一致可一并处理)。定级 P2,不阻断本提交。
There was a problem hiding this comment.
Rechecked at 0cab7347 with a real embedded seekDB instance. The db-migrate JSON issue is fixed. One non-blocking P3 remains: with pc_ tables in test and no explicit database name, server identity-reset --maintenance-confirmed raises an uncaught LegacySeekDBDatabaseError with empty stdout, before rotating the identity (src/powercontext/server/cli.py:222). Please translate it to typer.BadParameter, preserving the database-selection guidance.
There was a problem hiding this comment.
Verified fixed at d8da2bca with real embedded seekDB. Implicit legacy selection now returns exit 2 with the database-selection guidance and no traceback; readback confirmed the legacy record was preserved. The separate real CLI acceptance also passed explicit identity rotation and readback of the new identity with the original record intact.
| config.model_copy(update={"echo": False}), instance.connection_options() | ||
| ) | ||
| try: | ||
| await seekdb_profile._require_explicit_legacy_database(config, instance.connection_options()) |
There was a problem hiding this comment.
[P3] Disable SQL echo for the legacy maintenance probe
With POWERCONTEXT_SERVER_DATABASE_ECHO=true and an implicit seekDB database name, this call passes the original configuration to a second engine that enables SQL echo. Its logs precede the db-migrate JSON on stdout and break JSON consumers; pass the same echo-disabled configuration used for the maintenance engine.
|
|
||
|
|
||
| @pytest.mark.skipif(not _SEEKDB, reason="set POWERCONTEXT_TEST_BOOTSTRAP_SEEKDB=1") | ||
| def test_seekdb_legacy_migration_cli_preserves_json_with_sql_echo(short_tmp_path: Path) -> None: |
There was a problem hiding this comment.
[P1] 该用例使 code-seekdb (3.14) 的 bootstrap 步骤超出 300 s 预算,并跳过后续迁移验收步骤
head b0e379f6 的 code-seekdb (3.14)(job 118152425141)在 Test database bootstrap with embedded seekdb without skips 步骤失败:15:44:27 开始,15:49:39 被步骤超时终止(312 s,步骤上限 300 s),紧随其后的 Test unified migrations with embedded seekdb 因此被 skipped,这一份迁移验收在本 head 上从未执行。
时间对照(同一 job 定义、同一 runner 规模):
| 引用 | 3.14 bootstrap 步骤 | 3.11 bootstrap 步骤 |
|---|---|---|
本 head b0e379f6 |
超时(>300 s),job failure | 88 s,success |
上一 head 2fef5fab(job 117677155323) |
41 s,success | success |
master e4efb39b(job 118011655961) |
success | success |
2fef5fab...b0e379f6 只有 11 个文件,其中落在该步骤(-k seekdb 跑该文件)里的唯一变更就是本用例,因此可复现性判断集中在本用例;请重跑一次确认。
机制线索(源码推导,未在 Linux 实测):本文件既有的 test_seekdb_concurrent_profiles_initialize_one_database 注释写明并发只覆盖“one embedded owner process, not multiple engine-owner processes”,而本用例把同一 seekdb 目录交给 4 个独立子进程(for action in ("status", "plan", "verify", "apply") 各一次 subprocess.run(..., timeout=45))外加末尾一次 SeekDBProfile.open_existing。两处打开的等待没有上界:asyncio.run(seed()) 与 verify_preserved() 都没有 asyncio.timeout;一旦子进程被 45 s 上限 kill 掉而引擎目录/锁未释放,末尾的 open_existing 会无界等待,从而吃掉整个步骤预算。
建议方向:让四个 action 复用同一个引擎 owner(进程内直接调 CLI 入口,或一次子进程内跑完四个 action),只保留一次跨进程开库以覆盖“CLI 是独立进程”这一点;给 seed() 与 verify_preserved() 加 asyncio.timeout;如果单测时长无法压到预算内,把它拆到独立 step,避免挤掉同 job 的迁移验收步骤。
There was a problem hiding this comment.
复审 0cab7347:该 P1 已解除。
bf34f3e5 把跨进程开库收敛为"一个子进程持有引擎":新增 tests/fixtures/seekdb_legacy_migration_cli.py,seed() 外层加 asyncio.timeout(30),测试侧只保留一次 subprocess.run(..., timeout=90) 并在 TimeoutExpired 时 pytest.fail 带 stdout/stderr;master.yml 的 bootstrap step 维持 timeout-minutes: 5,另加 -vv、faulthandler_timeout=60、--durations=20 便于定位。这正是原先建议的"跨进程开库次数显式且最小 + 所有 asyncio.run(<open>) 加超时"。
证据:head 0cab7347 的 check 为 41 success / 1 skipped、无 failure,code-seekdb (3.11) 与 code-seekdb (3.14) 均通过,bootstrap 步骤未再超时,后续迁移验收步骤不再被 skip。
与本条无关但影响合并的一点,记录在此线程以便定位:该 head 当前 mergeable=false / mergeable_state=dirty,与 master(fe50f894)在 e2e/bub/tests/test_harbor_job_config.py 存在内容冲突(git merge-tree 复现),需要先同步 master 再谈入队。
There was a problem hiding this comment.
[P1] 新 head d8da2bca 把同类越界从"步骤预算"移到"用例自身预算",code-seekdb (3.11) 在 head 上红
上一条回复(4322207186)针对 test_seekdb_legacy_migration_cli_preserves_json_with_sql_echo,bf34f3e5 收敛为单进程持有引擎后确已解除(3.14 实测 28.53 s)。但在 head d8da2bca 上,同一文件的另一个新增用例重新越界:
tests/e2e/test_database_bootstrap.py::test_seekdb_legacy_choice_preserves_old_data_and_separates_new_database
在code-seekdb (3.11)(job119624150671,03:47:02 起)跑满tests/fixtures/seekdb_legacy_choice.py自身的
asyncio.timeout(60)后失败;同 headcode-seekdb (3.14)(job119624150681)该用例 37.01 s 通过,
即已用掉 60 s 预算的 62%,只剩 23 s 余量。- 失败阶段是
old data: reopening test(第 3 次整体 schema 初始化)。子进程 stderr 的
SHOW FULL PROCESSLIST显示该会话的CREATE TABLE IF NOT EXISTS pc_agent_skill_targets (...)已Time=22且仍ACTIVE,
同时oceanbase.__all_virtual_lock_wait_stat为空 ⇒ 是逐个建内置表的真实耗时,不是锁等待。 - 归因:base
c0c38dea上该文件不存在(git cat-file -e报 path does not exist),失败面只有本 PR 新增的用例与夹具,
同 head 3.14 绿 ⇒ 属本 PR 引入的 3.11 差异,不是基线或抖动。 - 机制:该夹具在一个子进程内串行做 7 次引擎 owner 打开(
SeekDBProfile.open×4 + 3 次app.router.lifespan_context),
每次 lifespan 都对同一嵌入式引擎重复整套CREATE TABLE IF NOT EXISTS。run_seekdb_scenario的
subprocess.run(timeout=90)大于夹具内的asyncio.timeout(60),父进程的 90 s 永远不会先到,失败面因此只报阶段名
(AssertionError: seed: opening test等),拿不到"哪一次初始化超预算"。
建议:把三次 lifespan 收敛为一次(旧库显式选择 + 默认库可用同一 profile 顺序驱动,避免重复建表),
并把父进程 timeout=90 与夹具内部 asyncio.timeout(60) 统一到同一预算;若保留 60 s,需要说明 3.11 上
"3 次全量 schema 初始化 + 4 次引擎开关"为何能稳定落在 60 s 内。
There was a problem hiding this comment.
Rechecked at d8da2bca. The current Python 3.11 CI job still fails when the legacy-choice scenario exhausts its shared 60-second deadline during table creation. A local Python 3.14 run also exhausted that deadline, after explicit legacy Server startup succeeded, during the subsequent native reopen. Root cause remains unresolved. Please investigate initialization/reopen costs and establish a workable scenario budget while retaining real Server startup, legacy-data preservation, and database-isolation assertions, then rerun both versions.
There was a problem hiding this comment.
复核 e5d882ba(test(seekdb): reduce startup DDL exposure and retry once past the engine stall):本条 P1 已解除。
step 级证据(同 head、同 job)
code-seekdb (3.11)(job119925972770)在 heade5d882ba上 SUCCESS(16:05:53Z→16:11:03Z)。其中tests/e2e/test_database_bootstrap.py8 passed in 75.86 s,test_seekdb_legacy_choice_preserves_old_data_and_separates_new_database的 call 耗时 25.74 s。- 上一轮
d8da2bca的同一 job 是在该用例上跑满夹具自身 60 s 预算失败、并跳过后续迁移验收步骤;现在离预算有 ~34 s 余量。 - 成因与改法对得上:
tests/fixtures/seekdb_legacy_choice.py的 seed 从"只取pc_topic_memory_work_budgets一张表"改为SeekDBProfile.open(old, tables=(*BUILTIN_TABLES, records)),把表 DDL 全部移出启动观察阶段,启动期只做存在性检查。 - 顺带核对
test_seekdb_creates_selected_database_and_preserves_data新增的事务回滚断言:assert_record断言的是value == "preserved"(不是仅"行存在"),所以raise RuntimeError("abort business write")之后的检查确实证明回滚生效,不是空断言。
残留风险(不另开线程,仅说明,未达到 Finding 证据门槛)
run_seekdb_scenario 的重试判据是 stalled or any(signature in output for signature in _STALL_SIGNATURES),其中 _STALL_SIGNATURES = ("Timeout (0:", "TimeoutError:") 是子串匹配。真正的产品超时(例如迁移命令自身的 TimeoutError)也会命中,于是被静默重试一次:
- 若第一轮 stall、第二轮通过,CI 全绿,而 stall 不留痕——
_retain_scenario_diagnostics只在POWERCONTEXT_TEST_BOOTSTRAP_DIAGNOSTICS设置时落盘,默认不写。 - 也就是说"引擎 stall 已被消除"与"stall 仍在只是被重试掩盖"在默认 CI 输出上不可区分。
建议在重试时无条件输出一行原因(attempt-1 failed: stall signature <sig>),或把 attempt-1 的尾部日志写进 step summary,让这个取舍可观测、可回溯。
未覆盖:本轮未在本机复跑 embedded seekDB 场景(Windows 下该引擎行为与 CI 不同),结论依据的是 head 上 code-seekdb (3.11) / (3.14) 两个 job 的真实 step 耗时与结论。
| it does not provision an OceanBase instance, tenant, or account. Ensure network access and install the Server extra: | ||
|
|
||
| ```bash | ||
| uv tool install --force "powercontext[cli,server]==1.3.0" |
There was a problem hiding this comment.
[P2] 新增 “Use OceanBase” 段落里的 ==1.3.0 使 quality 的 make version-check 失败
head b0e379f6 的 quality(job 118151454292,make check)输出:
Release version mismatch: docs/en/docs/get-started/install-and-run.md (expected 1.4.0)
Release version mismatch: docs/zh/docs/get-started/install-and-run.md (expected 1.4.0)
make: *** [Makefile:234: version-check] Error 1
expected 取自 openapi/powercontext.yaml 的 version:;该 job 在上一 head 2fef5fab 与 master e4efb39b 上都是 success,因此这条红是 master 已发布 1.4.0 与本 PR 新增段落组合的结果。
合并结果(merge 04a53f41)里本文件只剩这一处旧版本号,正是 bf043440 新增的本段代码块(en 第 195 行 / zh 第 180 行):
uv tool install --force "powercontext[cli,server]==1.3.0"本文件已在 scripts/release_version.py::REFERENCE_PREFIXES 内,因此 rebase 到当前 master 后执行 make version-bump VERSION=1.4.0 会自动改写这两行;不需要改实现,也不需要手工比对其他版本引用。
There was a problem hiding this comment.
复审 0cab7347:该 P2 已解除。
bf34f3e5 同步修改了 docs/{en,zh}/docs/get-started/install-and-run.md;head 上两份文档的 description、安装命令、--ref、seekdb extra 与升级段全部为 1.4.0 / powercontext-v1.4.0(en 第 27/31/32/44/50/125/282/285 行,zh 第 25/29/30/42/48/115/252 行),==1.3.0 残留 0 处,quality 在本 head 通过(该 job 内含 make version-check)。
hireview001
left a comment
There was a problem hiding this comment.
- CI failed: code-seekdb (3.14) (failure).
- CI failed: quality (failure).
- CI failed: validate (failure).
- CI failed: E2E harness (failure). Failed steps: validate / Validate harness and Compose definitions.
- CI failed: Main (failure). Failed steps: quality / Run checks; code-seekdb (3.14) / Test database bootstrap with embedded seekdb without skips.
- CI did not complete: Kimi Code acceptance (cancelled).
hidb4ai
left a comment
There was a problem hiding this comment.
Re-reviewed 0cab7347: both migration JSON issues are fixed, and the bootstrap timeout and release-version failures are cleared. The remaining identity-reset diagnostic issue is non-blocking (P3 follow-up).
Before merging, resolve the conflict with master (6d3db04f) in e2e/bub/tests/test_harbor_job_config.py and rerun the affected checks. Real seekDB was exercised locally; OceanBase evidence comes from CI.
hireview001
left a comment
There was a problem hiding this comment.
- Resolve merge conflicts with the target branch.
| This probe is diagnostic: it never echoes SQL, because the caller may own the | ||
| process's machine-readable output and the echo handler writes to stdout. | ||
| """ | ||
| if "database" in config.model_fields_set: |
There was a problem hiding this comment.
[P1] Preserve implicit database selection through ServerSettings
ServerSettings(database=SeekDBConfig(path=...)) serializes nested defaults, adding database to model_fields_set, so this early return bypasses legacy detection although the caller never selected a database. Existing programmatic Server deployments can consequently switch silently from populated test storage to a new powercontext database; preserve explicit-selection provenance through settings normalization so startup still requires a choice.
There was a problem hiding this comment.
Verified fixed at b9760f6f with real embedded seekDB. ServerSettings(database=SeekDBConfig(path=...)) now preserves the implicit database choice and refuses startup when legacy pc_ data exists in test. Readback confirmed that the legacy record remained intact and no powercontext database was created.
|
Resolve conflicts |
hidb4ai
left a comment
There was a problem hiding this comment.
Re-reviewed b9760f6f: the programmatic implicit-selection P1 is fixed, and the merge conflict is resolved. The non-blocking identity-reset P3 remains reproducible with real embedded seekDB: legacy selection raises an uncaught LegacySeekDBDatabaseError before identity rotation.
Local full Server startup did not pass: explicit test startup twice hit the 60-second timeout while creating pc_agent_skill_targets. Minimal current and pre-change DDL probes both succeeded, so attribution remains unresolved. The corresponding seekDB CI case passes; OceanBase validation is CI-only.
The code commands lost their JSON error contract and the offline maintenance commands ended in tracebacks when an implicit legacy seekdb choice or a provisioning failure reached the command boundary. - Report `explicit_database_required` from the code entry point as its own stderr JSON payload instead of an uncaught exception. - Report `DatabaseAccessError` and `DatabaseCreationError` from processing-migrate, atomic-memory-migrate, atomic-memory-rebuild-projection and identity-reset verbatim, because the rich error panel truncates the administrator statement these messages carry. - Translate the same provisioning failures for writable seekdb db-migrate into `database_access_denied` and `database_creation_required` maintenance errors, and document both codes.
tests/test_cli.py kept both sides: this branch's code and maintenance database-error tests and master's command-provider tests.
hireview001
left a comment
There was a problem hiding this comment.
- CI failed: code-seekdb (3.11) (failure).
- CI failed: code-seekdb (3.14) (failure).
- CI failed: Main (failure). Failed steps: code-seekdb (3.14) / Test database bootstrap with embedded seekdb without skips; code-seekdb (3.11) / Test database bootstrap with embedded seekdb without skips.
hidb4ai
left a comment
There was a problem hiding this comment.
Re-reviewed d8da2bca: the identity-reset P3 is fixed. Real embedded seekDB verified operator-facing refusal, explicit identity rotation, and preserved-data readback.
Merge readiness remains blocked by the legacy-choice acceptance timeout and a confirmed conflict with master (854e0836) in e2e/bub/tests/test_harbor_job_config.py (_kimi_installation). Resolve both and rerun the affected checks. The full local bootstrap batch did not complete successfully; the CLI scenario passed separately. OceanBase was not run locally.
tests/test_processing_migration_cli.py keeps both sides' tests, e2e/bub takes master's version, and processing-migrate keeps plan and verify as read-only inspection with master's rationale.
…ine stall The embedded seekDB can stall indefinitely on one CREATE TABLE during the startup schema burst; no client-side timeout bounds it, and two client variants (no IF NOT EXISTS, autocommit DDL) were measured without effect. Seed the legacy-choice fixture with the complete schema so the real startup path issues no table DDL, and retry a failing scenario child once in a fresh directory only when the output carries the stall signature. Genuine failures still fail immediately, and per-attempt diagnostics are retained. Also keep the KIMI guidance normalization alongside master's structure and assert that a failed seekDB transaction rolls back.
|
On the seekDB bootstrap stall: what it is, what we ruled out, and what this PR does about it The intermittent failure of Test database bootstrap with embedded seekdb is an engine-side stall in embedded seekDB, not a defect in this PR. The failing statement is always one CREATE TABLE that the server accepts and then never completes — SHOW FULL PROCESSLIST shows it ACTIVE for 20 s and beyond (pc_agent_skill_targets, pc_atomic_memory_current and pc_server_identity have all been observed), while __all_virtual_lock_wait_stat is empty (so it is not a row-lock wait) and __all_virtual_trans_stat holds internal transactions with pending_write = 1. The client is blocked in aiomysql reading the reply. On an idle machine the whole 52-table schema initializes in ~3.3 s, so this is not DDL volume. We ruled out the two plausible client-side causes by toggling one variable at a time and running interleaved rounds of the full selection (8 tests per round): dropping the redundant IF NOT EXISTS after the existing has_table guard — 2 stalls in 7 rounds, no improvement; This PR therefore handles it on the test side only: seekdb_legacy_choice.py now seeds the complete schema so the real startup path issues no table DDL (removing the window where the stall occurs), and run_seekdb_scenario retries a failing child once — in a fresh directory, and only when the output carries the stall signature or the process bound expired, so genuine failures still fail immediately. The retry path is verified: a stalling probe was retried twice, a plain assertion failure was not retried. After this change, 14 consecutive rounds of the full selection passed at ~70 s each, none needing the retry; the full unit suite is green (5538 passed, 101 skipped) and ruff/ty are clean. The underlying defect is in embedded seekDB (a CREATE TABLE during a burst of schema DDL can block forever with no applicable timeout); it is not recoverable from the client and is noted here as a known engineering issue. |
hireview001
left a comment
There was a problem hiding this comment.
- Resolve merge conflicts with the target branch.
schema.py keeps both sides: this branch's MySQL table-creation path and master's portable timestamp precision upgrade, which composition calls after create_tables.
Which issue or RFC does this PR close?
Closes #1795.
Rationale for this change
Embedded seekDB previously accepted only the built-in
testdatabase, while OceanBase rejected URLs without a database and assumed the selected database already existed. Provision the selected database before application tables, preserve explicit selections, and require an explicit choice before switching away from existing seekDB data.What changes are included in this PR?
powercontext; accept custom database names and preserve explicit selections.testcontains PowerContext-named tables. Explain how to keep usingtestor explicitly select a new database without moving or deleting existing data.testgraph identities.OceanBaseProfile.open_existing()andSeekDBProfile.open_existing()for connections that never provision a missing database. Routeserver atomic-memory-migrateandserver processing-migrateactionsplanandverifythrough these openers withtables=(). Report a missing database clearly and distinguish it from denied access.db-migrateand report an actionable CLI error.db-migrateinspection free of database creation and allow explicit writable seekDB maintenance to provision its configured database.dbanddatabasequery parameters. Update benchmark resume tests to preserve effective-target identity checks and verify configuration errors do not expose sensitive values.Are there any user-facing changes?
Yes. New seekDB deployments use
powercontext. Existing seekDB deployments should explicitly setPOWERCONTEXT_SERVER_DATABASE_DATABASE=testbefore upgrading to keep using their data. Without an explicit name, detectingpc_tables inteststops startup and provides configuration instructions.OceanBase URLs may omit the database. Explicit database names in the URL path remain authoritative;
dbanddatabasequery parameters are rejected.OceanBaseProfile.attach()continues to require an explicit existing database in the caller-owned engine. Database names are validated before initialization.For OceanBase and seekDB, migration
planandverifyrequire an existing database and never create a missing target. A missing target produces an actionable error. Ordinary startup and writable maintenance retain their provisioning behavior.Read-only seekDB inspection also requires an initialized native instance directory. Missing paths and empty directories are rejected before native startup, without creating parent directories or storage files. Files and unrecognized nonempty directories are rejected with their contents preserved.
No automatic data migration, retention reminders, database comparison, deletion, or existing-table schema upgrades are introduced. Embedded seekDB concurrency acceptance covers clients in one engine-owner process; it does not promise multiple owner processes. Initialization DDL does not provide distributed schema-migration coordination.
How was this change tested?
Executed with the existing project virtual environment:
powercontext, explicittest, and a custom database.Event loop is closed).git diff --checkpassed. Ruff, formatting, type checks, and diff checks also passed for the directory-protection changes.Test counts from separate runs overlap and are not additive. The complete affected test files and real seekDB bootstrap scenarios ran outside the execution sandbox. Real OceanBase acceptance, the full repository test suite, and documentation builds were not executed.
Coverage includes configuration, identifier quoting, target identity, permission/error handling, legacy database selection, resource disposal, maintenance identity, wizard persistence, code graph database selection, non-provisioning read-only migration inspection, and preservation of uninitialized instance paths. Opt-in real-backend scenarios cover initial creation, custom names, restart/readback, concurrent profile initialization, legacy data retention, OceanBase default selection, restricted-account behavior, and existing/missing database inspection.
Commands to run:
uv sync --locked --extra cli --extra server --extra seekdb --extra code uv run python -m pytest \ tests/builtin/persistence/test_database_bootstrap.py \ tests/builtin/persistence/test_seekdb_profile.py \ tests/builtin/persistence/test_oceanbase_profile.py \ tests/builtin/persistence/test_database_migration_connections.py \ tests/builtin/persistence/test_database_backup_providers.py \ tests/test_database_migration_cli.py \ tests/test_atomic_memory_migration_cli.py \ tests/test_processing_migration_cli.py \ tests/test_server.py \ tests/test_config_wizard.py uv run python -m pytest -q \ tests/test_locomo_plus_runner.py::test_oceanbase_resume_preserves_effective_target_when_credentials_or_spelling_change \ tests/test_locomo_plus_runner.py::test_oceanbase_resume_rejects_effective_target_changes_before_opening_services \ tests/test_locomo_plus_runner.py::test_oceanbase_rejects_ambiguous_routing_before_opening_services POWERCONTEXT_TEST_BOOTSTRAP_SEEKDB=1 \ uv run python -m pytest tests/e2e/test_database_bootstrap.py -k seekdb uv run python -m pytest tests/e2e/test_native_code_seekdb.py POWERCONTEXT_TEST_MIGRATION_SEEKDB=1 \ uv run python -m pytest \ tests/builtin/persistence/test_database_migration_connections.py \ tests/builtin/persistence/test_database_backup_providers.py -k real_seekdbWith
POWERCONTEXT_TEST_BOOTSTRAP_OCEANBASE_URLset to an administrator connection to a disposable MySQL user tenant:The default-name test requires an exclusive tenant without an existing
powercontextdatabase. The privileges test requires disposable user creation/grant privileges. These tests create and drop their own databases/users.make check make test PYTEST_WORKERS=0 make docs-testAI usage statement
Implemented and reviewed with OpenAI Codex. AI assistance was used for source tracing, implementation, regression-test design, documentation, and validation. Validation limits are listed above.