# 2026-07-03 — work #03: 清理 dataset_registry 中 6 个 MySQL/SQLite-era 旧 task ## 发现 work #02 写完后 daily_check 报告仍是 18 行,其中 6 个是 `disabled`: ``` 🚫 stock_info storage=SQLite dashboard/data_uat/db.sqlite → stocks 🚫 kline storage=dashboard/data_uat/market/kline/stock/{code6}.parquet 🚫 hs300 storage=dashboard/data_uat/market/kline/index/{code}.parquet 🚫 industry storage=SQLite dashboard/data_uat/db.sqlite → stock_sector_map + sectors 🚫 sector storage=dashboard/data_uat/derived/sector/sector_features_daily.parquet 🚫 scoring storage=SQLite dashboard/data_uat/db.sqlite → score_snapshots ``` 6/18 = 33% 噪音。每次巡检都看到这一坨 `🚫 disabled` 干扰对真正 missed 的注意力。 ## 根因 PG 迁移(commit 7a985dd, 2026-07-02)后: - 旧 task(`stock_info` / `kline` / `hs300` / `industry` / `sector` / `scoring`)的 sync_script 路径全部指向 `dashboard/api/services/sync/*.py::xxx` —— 这些是 sibling `dashboard/` 项目的旧脚本,**当前项目里根本不存在** - storage_uri 指向 `dashboard/data_uat/` 下的 SQLite/Parquet 文件 —— dashboard 项目本身**没在 worktree 里**(`ls dashboard/` 不存在) - 迁移时把它们 `enabled=0` 标记禁用,但**没删行** —— 留作历史 实际上 dashboard 项目已下线(PG 接管),这些行是真正的孤儿。 ## 解决 写 `bin/archive/clean_legacy_registry_rows.py`(一次性脚本),保守策略: 1. 必须 `enabled=0`(不碰 enabled=1 的) 2. 必须满足以下两条之一: - `storage_layer` ∈ `{sqlite, parquet, mysql, ""}`(旧 stack 标志) - `sync_script` 不以 `app.tasks.` 开头(不在新 PG 体系下) 3. 默认 dry-run,必须显式 `--apply` 才 DELETE 4. 删前 dump 被删行 + 事务保护 执行结果: ``` 扫描到 6 行废弃行: stock_info, kline, hs300, industry, sector, scoring ✅ 已删除 6 行 ``` daily_check 复跑验证:`{'missed': 10, 'disabled': 0, 'not_expected': 1, 'ok': 1}` —— 18 行 → 12 行,disabled 噪音清零。 ## 不在清理范围(保守原则) - `enabled=0` 但 `storage_layer='pg'` 的行:可能是临时禁用,不是孤儿,保留观察 - `enabled=1` 的所有行:哪怕 sync_script 路径奇怪,先看实际行为再说 - dashboard 项目的源码 / 数据文件:本项目是 market_sync,不动 sibling 项目的产物 ## 关联 - work #01: 2026-07-03-01-market-sync-timeout.md(修了 2h timeout) - work #02: 2026-07-03-02-morning-no-trigger.md(补了 09:00 早盘) - [[market-data-overview]]:现在 12 行 task 列表与项目实际状态一致 ## 后续(不在本 work 范围) 如果发现 enabled=0 的 PG task(如 kline_daily 临时关),可以走相同脚本(如果满足新策略),或单条 `DELETE` —— 单条操作不在本 work 范围。