老库实测结论(只读账号直连)
本文档记录 2026-10-09 用只读账号对老库做的实测。所有数字均为查询所得, 不是推断。与 <code>README.md</code> §4.2 的"待办清单"一一对应。
复现方式:<code>tools/legacy_db.py</code>(连通性/表清单/DDL)、 <code>tools/compare_dup_tables.py</code>(重名表结构比对)。 凭据在
私密/legacy-ro.env(已 gitignore)。⚠️ 本文件里会出现源实例地址与账号名——它们是"实测对象"的标识,不写就说不清结论是 对哪台库得出的(该账号是只读的,没有口令也无法利用)。口令不在本文件、也不在仓库 任何文件里,只存在于
私密/legacy-ro.env。别为了"方便复现"把口令补进来。
0. 连库方式:CLI 不可用,必须走 PyMySQL
本机 Homebrew 的 mysql 客户端是 26.7,已移除 mysql_native_password 插件,
而老库账号正是该认证方式,直接连报:
ERROR 2059 (HY000): Authentication plugin 'mysql_native_password' cannot be loaded
PyMySQL 用纯 Python 实现了该插件,故统一走 PyMySQL。
(备选:/opt/homebrew/opt/mysql-client@9.6 的插件目录里仍有该 .so,但需显式指定 plugin-dir。)
只读承诺的执行情况:全程仅发 SELECT / SHOW / 读 information_schema,
未做任何写操作。账号本身也确为只读(见 §2 授权)。
1. 六库同实例 ✅,但库名有严重误导性
先纠正一处我自己的误判:各模块配置文件里写的 druid.url(指向
rm-2zeq6z9f00w52tcq7jo)与代码实际面向的库不符,不能作为迁移源依据。
判定迁移源的可靠方法是:看代码引用的表在哪个库里真实存在。
按此做的模块 × 库命中矩阵(去分表后缀):
| 模块 | 引用表数 | zt_sys |
zt_park |
zt_order |
zt_order_n |
zt_bill |
zt_charge |
|---|---|---|---|---|---|---|---|
zteits-sys |
32 | 30 (94%) | 1 | 1 | 1 | – | – |
zteits-park |
127 | – | 110 (87%) | 2 | 3 | 1 | – |
zteits-order |
91 | – | – | 9 | 86 (95%) | – | – |
zteits-pay |
86 | – | – | 79 (92%) | 8 | – | – |
zteits-bill |
55 | – | – | 1 | – | 54 (98%) | – |
zteits-charge |
4 | – | – | – | – | – | 4 (100%) |
每个模块都有唯一且高命中率的归属库 → 六库全在
renniting-prod-net.mysql.zhangbei.rds.aliyuncs.com 这一台实例上,
INSERT INTO ... SELECT 同实例搬迁的前提成立。
⚠️ 但有两个必须记住的命名陷阱
zt_order里装的是 pay 域,不是 order 域。zteits-pay引用的 86 张表里 79 张在zt_order(92%); 而 order 域的表在zt_order_n。库名与业务域刚好错位。zt_order里还混着一份 2018 年的订单归档。 该库的td_b_order/td_b_pay_order/td_b_order_detail_park末行create_date分别是 2018-04-08 / 2018-04-26 / 2018-03-27—— 冻结了 8 年;而同库的td_c_cust_person(客户)今天仍在写入。 所以zt_order= pay 活库 + 2018 订单死档案, 搬迁时不能整库照搬,要按表区分。
建议:新库按业务域命名,不要沿用
zt_order/zt_order_n这种 与内容错位的旧名(方案 §4.4 定的parking_cloud单库 + 前缀正是为此)。
对照:另一台实例是另一个环境
rm-2zeq6z9f00w52tcq7jo 上有 zt_sys/zt_park/zt_order/zt_pay/zt_bill/zt_business
——库名与张北部分重叠但内容不同(例如它有 zt_pay,张北没有)。
本次迁移不涉及该实例(除 zteits-business 的 11 张表,见 §7)。
2. 只读账号的授权范围(已核实,覆盖完整)
GRANT SELECT, LOCK TABLES, SHOW VIEW ON `zt_sys`.* TO 'readonly'@'%'
GRANT SELECT, LOCK TABLES, SHOW VIEW ON `zt_park`.* TO 'readonly'@'%'
GRANT SELECT, LOCK TABLES, SHOW VIEW ON `zt_order`.* TO 'readonly'@'%'
GRANT SELECT, LOCK TABLES, SHOW VIEW ON `zt_order_n`.* TO 'readonly'@'%'
GRANT SELECT, LOCK TABLES, SHOW VIEW ON `zt_bill`.* TO 'readonly'@'%'
GRANT SELECT, LOCK TABLES, SHOW VIEW ON `zt_charge`.* TO 'readonly'@'%'
GRANT SELECT, LOCK TABLES, SHOW VIEW ON `xxl_job`.* TO 'readonly'@'%'
GRANT PROCESS, REPLICATION SLAVE, REPLICATION CLIENT ON *.*
确为只读,且正好覆盖迁移所需的六个库——授权范围与 §1 的归属矩阵完全吻合, 说明这个账号就是为本次六库合一准备的。
⚠️ 澄清一个我此前的误报:
zt_pay不在这份授权里,但它不是缺失—— pay 域的表物理上就在zt_order(§1)。所以"pay 库结构拿不到"这个卡点 不存在,无需额外授权。
3. 六库概览
| 库 | 表数 | 近似行数 | 数据大小 | 非 utf8mb4 表 |
|---|---|---|---|---|
zt_park |
387 | 1,193,632,380 | 414.4 GB | 368 |
zt_order_n |
112 | 409,273,992 | 260.3 GB | 99 |
zt_order |
108 | 293,091,812 | 88.8 GB | 106 |
zt_bill |
60 | 5,656,547 | 1.35 GB | 55 |
zt_sys |
38 | 1,775,497 | 0.58 GB | 38 |
zt_charge |
4 | 16 | 0.1 MB | 0 |
| 合计 | 709 | ~19 亿 | ~747 GB | 666 |
要点:
- 规模远超预期:747 GB / 19 亿行,且 19 亿里有 16 亿在
zt_park。 迁移窗口、分批策略都要按这个量级重估,不能用"小库直接搬"的假设。 zt_charge基本是空库(4 表 / 16 行)→ 充电业务实际未在这套库上跑, 或跑在dev_charge。TABLE_ROWS是 InnoDB 估算值(分表族会被逐张累加),量级可信,精确值需逐表COUNT(*)。- 非 InnoDB 表 0 张(无视图、无 MyISAM),搬运无引擎障碍。
4. 重名表:19 组,7 组可直接合并、12 组必须处理
4.1 ✅ 结构完全一致(列+索引+排序规则全同)—— 7 组
| 表 | 库 |
|---|---|
income_temp |
zt_order_n、zt_park |
month_dchz |
zt_order_n、zt_park |
table_15_free |
zt_order_n、zt_park |
td_b_settlement |
zt_order、zt_order_n |
td_b_settlement_org |
zt_order、zt_order_n |
td_b_settlement_share_record |
zt_order、zt_order_n |
td_p_parking_share_order_temp |
zt_order、zt_order_n |
4.2 ⚠️ 结构不一致 —— 12 组
差异分三类,处理方式完全不同:
| 表 | 差异性质 | 活跃份 |
|---|---|---|
parking_lot(4 库) |
zt_bill == zt_order(列全同,仅索引差);zt_order_n / zt_park 是超集(多 area_type/is_special/parent_pl_no/pl_category/push_state/support_etc 等 8~10 列) |
zt_park(3040 行,08-23 更新) |
sys_org(4 库) |
zt_sys == zt_park == zt_order_n;zt_order 是旧版(short_name 非空、缺 index_org_id) |
zt_sys(204 行);zt_order 为 0 行 |
park_in_out_record |
zt_park 是超集(多 4 列 + 6 个索引) |
zt_park(9674 万行 / 32 GB,今天更新);zt_order 仅 115 万行 / 231 MB,长期未更新 |
t_vip_card_cust_info |
zt_bill 多 3 列(cust_name/cust_phone/parent_cust_card_no) |
zt_bill(78816 行,今天更新);zt_order 1892 行,陈旧 |
tb_b_park_income_day |
zt_order_n 多 2 个索引 |
zt_order_n(22.7 万行,今天 02:00);zt_order 1796 行 |
td_b_settlement_record |
zt_order_n 多 3 列(case_refund_*),check_status 默认值不同(左空/右 100) |
zt_order_n(8604 行,今天 02:01);zt_order 90 行 |
td_b_settlement_serial |
zt_order_n 多 settlement_month |
两侧都近乎空 |
td_b_wx_config |
zt_order_n 多 cert_name;org_id 类型 int(30) vs int(10) |
两侧各 19/23 行 |
td_c_coupon_person |
cust_id 索引不同 |
— |
td_c_cust_person |
⚠️ 方向相反:zt_order 反而多 4 列(etc_open_state/etc_protocol_state/freeze_date/freeze_state),deivce_type 默认值不同 |
zt_order(82691 行,今天 10:59);zt_order_n 26367 行,陈旧 |
tp_e_employee_charge |
zt_park 多 7 列(eqp_* 设备字段) |
zt_park(2217 行,今天 10:55) |
tp_p_berths |
zt_park 多 car_number_color |
zt_park(30162 行,今天 11:01) |
由这 12 组得出的关键判断
重名表其实是两种性质,必须分开处理:
跨库冗余副本(
sys_org、parking_lot、park_in_out_record、t_vip_card_cust_info、tp_p_berths、tp_e_employee_charge) —— 为了在本库做 JOIN 而复制过来的只读副本,长期不同步、结构已漂移。 典型如sys_org:zt_sys有 204 行,zt_park/zt_order_n各只有 20 行,zt_order更是 0 行 —— 副本不仅滞后,还是残缺的。新老两代同表(
zt_ordervszt_order_n的结算/收入系列) —— 且活跃方向不一致:tb_b_park_income_day、td_b_settlement_record活的是zt_order_n,而td_c_cust_person活的是zt_order。 没有任何一条统一规则可判,必须逐表定性。
⚠️
parking_lot/sys_org这类"字段集是超集/子集"的差异, 合库时不能取并集(会破坏另一侧代码),也不能随意取一侧(会丢列)。归属可由 §1 的矩阵推断:
parking_lot的活份在zt_park(3040 行、有更新),sys_org的活份在zt_sys(204 行,其余库只有 20 行甚至 0 行)。 也就是说zt_bill/zt_order/zt_order_n里的那几份都是跨库只读副本—— 合库时保留主份、丢弃副本,并把原来的跨库 JOIN 改成走parking-module-api(正好落回红线第 7 条"禁止跨模块直接访问数据库")。 但副本上的独有列不能直接丢——那说明有代码在写副本,需先查清调用方。
5. 字符集:666/709 张不是 utf8mb4,另有 30 张 utf8_bin 排序规则冲突
| 排序规则 | 表数 | 风险 |
|---|---|---|
utf8_general_ci |
635 | 3 字节 utf8,存不下 emoji/生僻字(4 字节) |
utf8mb4_general_ci |
39 | 目标形态 |
utf8_bin |
30 | ⚠️ 见下 |
utf8mb4_unicode_ci |
4 | 与 general_ci 混用需统一 |
latin1_swedish_ci |
1 | ⚠️ zt_order_n.td_b_pay_blncac_wx,含中文必乱码 |
⚠️ utf8_bin 造成的真实 JOIN 障碍
parking_lot 在 zt_bill / zt_order / zt_order_n / zt_park 四个库里都是 utf8_bin,
而周边表的同名列是 utf8_general_ci:
| 表 | 列 | 排序规则 |
|---|---|---|
parking_lot |
pl_no |
utf8_bin |
park_in_out_record |
pl_no |
utf8_general_ci |
tp_p_berths |
pl_no |
utf8_general_ci |
MySQL 5.7 下两者相 = 比较会报 Illegal mix of collations。
即:合库统一排序规则后,一批老系统里"本来就跑不通"的 JOIN 会开始能跑 ——
这与 Dubbo 那 8 处"合并顺手修好"属于同一类行为变化,回归时要专门过。
另外 zt_park 里有一批带 del20181116 前缀的历史备份表(如
del20181116td_g_guide_park_berths),而代码里仍在按老名字
td_g_guide_park_berths 查(见 §7)——表被改名删了,代码没跟。
6. 分表族:实测确认,共 228 张物理表(2 个族)
🔁 2026-10-10 修正:本节原写「230 张、3 个族」,把
parking_running_statistic2023/2025也算成了族。那是错的—— 判据见下。真正的分表族只有 2 个、228 张;那两张是人工快照, 已移入 §8 的嫌疑清单(合计约 133 GB,见 §6.1)——2026-10-10 已拍板不搬。
什么叫分表族:表名由代码在运行期拼出来("tp_p_eqp_log" + yyyyMM)。
因此判据是代码里存不存在 "前缀" 这个字面量——静态表在 SQL 里永远只以裸名字
出现(FROM parking_running_statistic),Java 里不会有它的引号字面量。
这条判据已固化进 tools/audit_junk_tables.py 的 sharded_in_code(),
并做双向自检(登记的都真在拼 / 在拼的都登记了,任一不满足即 exit 2)。
| 库 | 表名前缀 | 后缀 | 张数 | 范围 | 代码拼装处 |
|---|---|---|---|---|---|
zt_park |
tp_p_eqp_inout_record |
yyyyMM |
115 | 201709 ~ 202703 | EqpInOutParkStatisticServiceImpl |
zt_park |
tp_p_eqp_log |
yyyyMM |
113 | 201711 ~ 202703 | TpPEqpLogDaoImpl / EqpLogDaoImpl / EqpHeartBeatJob |
未来到 2027 年 3 月(说明有预建表任务)。
合库时必须连着分表族一起搬,且不能把 ${...} 写死;
ParkingLotUseStatisticDaoImpl:169 那个"用当前时间拼表名"的存量缺陷也在此列。
6.1 ⚠️ 被误判为族的 parking_running_statistic*:整个家族约 183 GB
判据(§6)改正后,这个前缀下的物理表没有一张是分表族成员,全是静态表; 带后缀的那几张贴是人工滚动快照:
| 表 | 估算行数 | 大小 | 建表时间 | 代码引用 | 处置 |
|---|---|---|---|---|---|
zt_park.parking_running_statistic |
1.05 亿 | 20.5 GB | 2026-04-17 12:05 | ✅ 有(2 个 XML)——全家族唯一被代码读的那张 | 随迁 |
zt_park.parking_running_statistic2023 |
3.86 亿 | 83.0 GB | 2024-05-22 | 无 | 不搬(§10.1) |
zt_park.parking_running_statistic2025 |
2.41 亿 | 50.5 GB | 2026-04-17 12:03 | 无 | 不搬(§10.1) |
zt_park.parking_running_statistic_his |
1.25 亿 | 25.3 GB | 2022-07-27 | 无 | 暂定搬(未确认) |
zt_park.parking_running_statistic_chifeng_2019021 |
1947 万 | 3.6 GB | 2022-07-27 | 无 | 暂定搬(未确认) |
zt_park.parking_running_statistic_chifeng |
1.36 万 | 2.5 MB | 2022-07-27 | 无 | 暂定搬(未确认) |
怎么认出它是滚动快照的:无后缀那张的建表时间与 …2025 只差 2 分钟
(12:03 / 12:05),是典型的「把老表 CREATE TABLE … SELECT 出来存档、再重建一张空表接着写」。
于是带日期的贴是滚动前的历史数据,而代码只读无后缀那张——这也解释了为什么年度
不连号(只有 2023、2025,没有 2024):它不是分区方案,是人工存档。
全家族合计约 183 GB(占六库 747 GB 的近四分之一),其中 133.5 GB 已拍板不搬。
⚠️
_his(25.3 GB)、_chifeng_2019021(3.6 GB)、_chifeng(2.5 MB)与已拍板不搬的 那两张是同一形态,但它们连嫌疑判据都没命中(名字里没有日期后缀), 也没拿到处置指示——所以仍按"先全搬"。要一并省掉的话说一句即可, 再省约 29 GB(改写一处DO_NOT_MIGRATE就行,见 §10.1)。
7. 代码引用、但六库中都不存在的表(40 张)
这份清单比"表清单"更有用——它直接指出哪些代码在查不存在的表:
| 模块 | 张数 | 表 | 定性 |
|---|---|---|---|
zteits-business |
11 | td_c_business_*、order_business_coupon* |
在另一实例的 zt_business(§1 对照)→ 属方案 §4.6 的随迁例外范畴 |
zteits-pay |
5 | car_search_history、cust_person_credit、td_b_bills_days、td_b_park_card_cust、td_b_park_card_rel |
⚠️ pay 的归属库是 zt_order(§1),这 5 张在六库里都真的没有 → 要么是死代码,要么在另一实例。需逐张确认 |
zteits-park |
17 | hub_*(6)、nbtemp、generate_test_table、inpark_log、outpark_log、eqp_in_time、eqp_out_time、park_pay_log、parking_lot_berths、parking_lot_credentials、charger_assess_result_log、td_g_guide_park_berths |
混合:部分是从未建表的死代码(generate_test_table/nbtemp);td_g_guide_park_berths 是表已改名——同库存在 del20181116td_g_guide_park_berths,代码没跟着改;hub_* 疑似未上线对接 |
zteits-order |
4 | inspection_log、order_arrearage_edit_log、order_park_bjxc_success、park_in_time |
待定 |
zteits-sys |
2 | tb_work_order、tb_work_order_process |
工单表,疑似属其他系统 |
对 P2 的意义:zt_business 那 11 张与方案 §4.6 已识别的"business 随迁"对上了,
属已规划项;其余 29 张必须在搬迁前逐张定性,
否则会把"本来就坏的代码"原样搬进新系统、继续 silently 失败。
已确认的一例:
td_g_guide_park_berths—— 表在 2018-11-16 被改名成del20181116td_g_guide_park_berths,代码仍在查老名字。 这类"改名未同步"很可能还有别的,值得用同一手法(比对物理表名单)继续挖。
8. 废弃/备份表:逐张确认完毕(2026-10-10)
逐张确认已做完,产物是 <code>../docs/废弃表逐张确认.md</code> (由 <code>tools/audit_junk_tables.py</code> 生成,可随时重跑)。 本节只记口径与结论,逐张明细看那份报告。
8.1 确认结果:61 张,按判据分布
| 判据 | 张数 |
|---|---|
_bak 备份 |
16 |
名含 temp(独立词) |
12 |
_<8位日期> 后缀 |
11 |
_copy 副本 |
8 |
_<4位数字> 后缀 |
6 |
裸<数字>后缀(无下划线,见 §6.1) |
3 |
| 名含 test(独立词) | 2 |
del 前缀带日期 |
2 |
_<6位年月> 后缀 |
1 |
按库:zt_park 27、zt_order_n 13、zt_sys 8、zt_order 8、zt_bill 5
(zt_pay / zt_charge 无命中)。
⚠️ 本节原列的「
del<日期>2 张、_<日期>12 张、_copyN8 张、_bak14 张、temp词 13 张、test词 1 张」是按旧口径数的粗数(未排除分表族、未做词边界), 以 8.1 表为准。
8.2 确认方法(为什么不能只看名字)
三条证据缺一不可,全部由脚本产出:
- 精确
COUNT(*)(不是TABLE_ROWS估算)——估算对大表可差数十个百分点, 而"这张表到底是不是空的"恰恰是关键判断; - 代码引用——在
parking-module-*里搜表名。分表位置(FROM/JOIN/…之后 或 Java 字面量,硬证据)与疑似(其余命中)两级,两级都贴命中行原文; - 建表时间——
_bak不等于陈旧:sys_op_advice_bak是 2026-02-25 建的 (109 万行 / 200 MB,与无后缀的sys_op_advice只差 4 秒——同一类滚动操作)。 近期建的备份表很可能是运维在用的。(这条问对了:2026-10-10 业务方确认那是备份, 不用管 → §10.1。)
8.3 结论分布与处置
| 结论 | 张数 | 处置 |
|---|---|---|
| 🔴 有表位置代码引用 | 6 | 必须随迁——是活表,只是名字像残留 |
| 🟠 疑似引用(非表位置) | 1 | zt_park.temp——已人眼核对,6 处命中全是 SQL 别名/foreach item,确认无引用;它 7 行,故处置同下下行 |
| 🟡 有数据但无引用 | 46 | 先全搬(§10 决策;老库仍在,可逆) |
| 🟡 无引用但行数未知 | 1 | parking_running_statistic_chifeng_2019021(3.6 GB,超限未数)。同族的 _his(25.3 GB)连判据都没命中——这两张都没拿到处置指示,仍按"先全搬"(§6.1 末注) |
| ⬛ 已拍板不搬(空表 4 + 备份 3) | 7 | 不搬(新库建表脚本里也不要有)。4 张空表不搬零代价;3 张有数据的备份见 §10.1 |
小计 6 + 1 + 46 + 1 + 7 = 61 √ (⚠️ 原表写的是 6 + 2 + 1 + 48 + 4:其中「🟠 近期创建 2 张」已由业务方答复, 转成 ⬛;🟢 4 张空表也归入 ⬛ 以便一处看全。分类口径变了,总数不变。)
🔴 的 6 张(都不许按名字处置,明细见报告):
zt_order.td_b_temp_parklot、zt_order.td_p_parking_share_order_temp、
zt_order_n.td_p_parking_share_order_temp、zt_park.duty_roster_base_temp、
zt_park.tp_p_eqp_inout_record_temp、zt_sys.sys_export_temp_file。
⚠️ 这 6 张的存在恰恰说明「名字像临时表」与「是不是临时表」无关:
td_b_temp_parklot是停车场临时信息表(insert into …),duty_roster_base_temp是排班导入的中间表(TRUNCATE+ 搬进duty_roster_base),都在日活路径上。⚠️ 反方向的风险更大:也不能仅凭名字搬。把
sys_org_copy这类历史副本 原样搬进新库,它就永久留在新库里——00建库脚本与后来的建表语句都不知道它存在, 等于往新库注入一批无来源、无归属、以后没人敢删的表。这正是 §8.3 放行的 只有两类的原因:4 张空表(不搬零代价,判据是数据自证)与 3 张拿到明确拍板的备份(§10.1,有数据,判据是业务判断而非数据)。 第二类的风险方向相反——不搬会少数据,所以它必须有外部拍板留痕, 条目的理由串里写清"谁、何时、凭什么"(见tools/audit_junk_tables.py文件头)。
另注:month_dchz、table_15_free 这类"看着像临时表"的不是残留,
是被代码正常引用的业务表(且在两库结构一致)——名字判据一开始就没命中它们,
被误列进来过,这里明确排除。
9. 闭环情况与剩余事项
9.1 已闭环
| 原疑问 | 结论 |
|---|---|
| 迁移源是哪台实例? | ✅ 张北 renniting-prod-net(模块×库命中矩阵 87~100%,见 §1) |
zt_pay 结构拿不到? |
✅ 不存在此问题——pay 域的表就在 zt_order(§1) |
| 六库是否同实例? | ✅ 是,同实例可直接 INSERT INTO ... SELECT |
zt_order / zt_order_n 谁是谁? |
✅ zt_order_n = order 域活库;zt_order = pay 域活库 + 2018 订单归档(§1) |
| 字符集是否都是 utf8mb4? | ✅ 否,666/709 不是,含 30 张 utf8_bin + 1 张 latin1(§5) |
| 分表族到底有多少张? | ✅ 实测 228 张物理表 / 2 个族,到 2027-03(§6)。原写的 230 张 / 3 个族含误判,2026-10-10 修正 |
| §8 那些废弃/备份表怎么处置? | ✅ 61 张逐张确认完毕(2026-10-10,§8)→ 分层处置见 §8.3:7 张不搬(空表 4 + 备份 3),其余 54 张随迁。其中 3 张备份(约 133 GB)不再进入迁移体量(§10.1) |
9.2 仍需你定夺
| # | 事项 | 说明 |
|---|---|---|
| 1 | zteits-business 的 11 张表要不要随迁 |
它们在另一台实例的 zt_business,本次只读账号覆盖不到。按方案 §4.6,business 仅在"被核心模块运行时调用"时才随迁——需要拿它是随迁还是砍掉 |
| 2 | zt_order 里那份 2018 订单归档怎么处理 |
是一并搬进新库(保留历史查询能力),还是只搬 pay 域活表、归档另行放置?这直接影响迁移体量(该库 88 GB,大部分是归档) |
| 3 | 关键大表的精确行数 | 本次用 TABLE_ROWS 估算。定迁移窗口前,需对 zt_park 的几张大表取精确 COUNT(*) |
| 4 | ✅ 2026-10-10 已闭环:61 张逐张确认完毕,口径与处置见 §8;逐张明细见 docs/废弃表逐张确认.md(可重跑) |
第 2 条影响最大:
zt_order(88 GB)与zt_order_n(260 GB)合计 349 GB, 若归档可剥离,迁移体量能显著下降。
10. 已确认的决策(2026-10-09)
| # | 事项 | 决策 | 影响 |
|---|---|---|---|
| 1 | zteits-business |
随迁。其 11 张表在另一实例的 zt_business,需在该实例开一个只读账号(只需 SELECT ON zt_business.*),填入 私密/legacy-ro.env 的 LEGACY_DB_BUSINESS_* |
未提供前,六库比对不受影响;提供后补做 business 的结构比对 |
| 2 | zt_order 里的 2018 年订单归档 |
一并搬进新库(零数据丢失优先;老库仍作只读回滚路径) | 迁移体量包含这部分,约为数十 GB |
决策 2 意味着新库会携带一批"新代码永远不会查"的表。 若后续确认体积不可接受,可从老库单独导出这批表另存,而不影响新库结构—— 因此这个决策是可逆的,现在按"先全搬"执行。
10.1 废弃/备份表处置(2026-10-10)
§9.2 第 4 项闭环后的决定,口径见 §8.3:
| # | 事项 | 决策 | 影响 |
|---|---|---|---|
| 3 | §8 的 61 张废弃/备份表 | 按 §8.3 分层处置:🔴 6 张随迁(是活表);🟠 1 张已核为无引用;🟡 47 张先全搬;⬛ 7 张不搬(空表 4 + 备份 3) | 与决策 2 的"零数据丢失优先"一致;⬛ 那 7 张不进 00 建库脚本 |
| 4 | parking_running_statistic2023 / …2025(约 133 GB) |
✅ 2026-10-10 业务方拍板:备份表,无需理会 → 不搬进新库 | 迁移体量最值得省的一块(§6.1);133 GB 不进 parking_cloud。数据留在老库(未销毁),需要时从老库单独导出 |
| 5 | sys_op_advice_bak(2026-02-25 建,109 万行 / 200 MB) |
✅ 同上,不搬 | 只有 200 MB,搬不搬都无所谓;按拍板走,与新库"少一批没人认领的表"更一致 |
| 6 | parking_running_statistic_his(25.3 GB)/ _chifeng_2019021(3.6 GB)/ _chifeng(2.5 MB) |
仍按"先全搬"——与决策 4 是同一形态(§6.1),但没拿到指示 | 要一并省掉约 29 GB 的话,把这三张加进 DO_NOT_MIGRATE 的 备份 层即可 |
落地在哪(这决定才是真的,报告只是生成物):
| 落地处 | 内容 |
|---|---|
tools/audit_junk_tables.py 的 DO_NOT_MIGRATE |
唯一事实来源。值 = (层级, 理由),备份 层的理由串必须写清"谁、何时、凭什么" |
同上,main() 的自检 |
逐条复核前提仍成立(两层共有:仍存在、仍无表位置引用;空表 层另有"仍是 0 行")。不成立就 exit 2 |
sql/migration/exclude_tables.txt |
30 行(23 副本 + 7 不搬)→ mysqldump --ignore-table |
sql/migration/99_verify.sql §1 |
NOT IN (...)——不排掉它会永远报红(那 7 张是有意不在目标库里的) |
sql/migration/98_count_reconcile.sql |
排除集同上;顺带把 zt_park 段最贵的两次 COUNT(*)(6.27 亿行)也省掉了 |
⚠️ 决策 3 里 🔴 那 6 张不能按"名字像临时表"处理:它们是日活路径上的真表 (如
td_b_temp_parklot、duty_roster_base_temp),误删会直接坏业务。 这正是 §8 一开始就警告的"不能仅凭名字删"。⚠️ 决策 4/5 是唯一一批"知道有数据、仍然不搬"的表。它们的守卫比空表弱: 只能保证"代码里还是没人读它"这个前提,证明不了"这是你需要的备份"—— 那是业务判断,任何查询都答不了。所以改动它们时先回到这条决策,别只看脚本过不过。