开放问答
5 亿行非分区大表在线转按月分区:唯一键冲突与切换期数据同步怎么解
该问题的正文、回答与评论。
提问者 陈清和-922 · 状态 open
MySQL分区表在线迁移gh-ostDBA
【背景】 MySQL 8.0.32,InnoDB,生产库一张交易流水表 t_flow 约 5 亿行、单表 140GB,目前是非分区表,唯一键是 (order_no, biz_date) 两个业务字段。业务侧 90% 查询都带 3 个月内的 created_at 时间范围,删历史数据用 DELETE 经常跑 20 分钟以上,慢日志里 DELETE 和按时间范围的 SELECT 混在一起很难拆。目标很明确:转成按 created_at 的 RANGE 月分区,让 DROP PARTITION 接管删历史、让分区裁剪把大表查询切小。
【现象与卡点】 卡在三个具体点,社区里 id=79、id=420 的讨论给了方向但没给落地细节:
- 唯一键与分区键的冲突:MySQL 要求分区表的所有唯一键必须包含分区列,而我们的 (order_no, biz_date) 里没有 created_at。是把 created_at 硬塞进唯一键(业务代码要改,且要确认 created_at 在业务上真能区分),还是放弃唯一键改用「唯一索引 + 应用层兜底」(风险和业务方很难谈),有没有更稳的中间路线?
- 在线转换的数据同步:直接建一张分区新表 + 双写,但 5 亿行存量数据的迁移窗口里,老表还在被大量写入,增量追平靠 binlog(Canal/gh-ost 思路)还是靠定时 diff 对账?迁移期间应用是双写老表还是切到新表?
- 切换窗口:哪怕做到「秒级切换」,实际锁表 / rename / 应用连接池重连的停机窗口你们一般控制在多长?有没有踩坑过的顺序?
【已尝试】
- 在测试库用 gh-ost 试过直接加列 + 改分区,gh-ost 对「转分区」这种结构性变更支持不好,中途报过分区键相关的错;
- 试过 pt-online-schema-change,同样不支持分区变更,放弃;
- 双写方案在测试环境跑了 1 天,存量 5 亿行迁移到增量追平花了 6 小时+,但没做切换演练。
【期望的回答形态】 希望有同学能给出完整的落地顺序:建表 DDL(含分区键怎么进唯一键)→ 存量迁移工具与参数 → 增量同步与对账方案 → 切换那 30 分钟到 2 小时的具体步骤(含 rename 顺序、回滚预案)。最好带实际跑过的数据:迁移耗时、切换停机时长、回滚是怎么做的。如果你们最后放弃分区改走了归档或冷热分离,也请说下原因和代价,我这边好评估。
已采纳
回答者
回答正文
评论
暂无评论。