分区表迁移必须先在目标端创建结构完全一致的分区表,再逐分区导入数据;推荐用exchange partition在线交换,但需确保临时表定义严格匹配且无残留数据;迁移后务必执行analyze table更新统计信息。

分区表迁移不能直接用 RENAME TABLE
直接 RENAME TABLE old_table TO new_table 在跨库或跨实例时会失败,因为分区定义(PARTITION BY)是表结构的一部分,而 RENAME 只改名不复制元数据。更关键的是:目标库若未提前建好相同分区策略,RENAME 会报错 ERROR 1503 (HY000): A PRIMARY KEY must include all columns in the table's partitioning function 或类似校验失败。
真正能用的路径只有一条:先在目标端创建**结构完全一致**的分区表(含相同 PARTITION BY 表达式、相同分区数量、相同分区边界),再逐分区导入数据。
- 用
SHOW CREATE TABLE导出源表 DDL,手动检查并修正库名、存储引擎、字符集等细节,再执行建表 - 注意
MAXVALUE分区不能被复制到新表后直接插入——必须确保最后一个分区存在且可写,否则INSERT会报ERROR 1708 (HY000): Cannot add or update a child row - 如果源表用了
LIST或RANGE COLUMNS,目标端 MySQL 版本必须 ≥ 源版本,低版本不识别高版本新增的分区语法
用 ALTER TABLE ... EXCHANGE PARTITION 做在线交换
这是唯一能在不锁全表前提下把数据“搬”进新分区表的方法,但前提是:你有一个和目标分区结构完全一致的**空临时表**,且该表与要交换的分区具有相同的定义(字段顺序、类型、索引、NOT NULL 约束等),否则交换直接失败。
典型流程是:建空临时表 → 把数据批量灌入临时表(用 INSERT ... SELECT 或 LOAD DATA)→ 用 EXCHANGE PARTITION 把临时表内容“原子替换”进目标表对应分区。
- 临时表必须和目标分区使用相同存储引擎(比如都是
InnoDB),且不能有外键引用 - 交换前务必确认临时表无数据残留:
SELECT COUNT(*) FROM temp_table,否则会把旧数据混进去 -
EXCHANGE PARTITION不校验数据是否符合分区规则,如果临时表里有超出该分区边界的行,交换后查不到,但数据实际已“丢失”在分区内部——不会报错,只会静默过滤
超大分区导出导入别碰 mysqldump
mysqldump --single-transaction 对超大分区极易触发长事务、MVCC 版本堆积、甚至 Undo log 膨胀导致主从延迟飙升。单个分区几亿行时,dump 文件可能达上百 GB,网络传输 + 导入耗时不可控,还容易因超时中断。
更稳的做法是:按分区切片导出为 CSV 或 Parquet(用 SELECT ... INTO OUTFILE 或外部工具),再用 LOAD DATA INFILE 或 INSERT ... VALUES 批量加载。
-
SELECT * FROM t PARTITION(p202401) INTO OUTFILE '/tmp/t_p202401.csv'—— 注意路径需为 MySQL 服务端本地路径,且用户要有FILE权限 - 导入前关掉唯一键检查:
SET unique_checks=0,导入后再开;大批量插入时也建议关掉自动提交:SET autocommit=0,每 10 万行COMMIT一次 - 如果目标端是 MySQL 8.0+,可用
LOAD DATA LOCAL INFILE配合客户端文件,但需确认local_infile=ON且客户端支持
分区交换后记得更新统计信息
MySQL 的优化器依赖 INFORMATION_SCHEMA.PARTITIONS 和 ANALYZE TABLE 生成的统计信息做执行计划。交换分区后,原分区的行数、索引分布等元数据不会自动刷新,可能导致后续查询走错索引、误判分区裁剪失效。
最简单有效的方式就是对整张表跑一次 ANALYZE TABLE,尤其当交换了多个分区后,不要跳过这步。
-
ANALYZE TABLE big_partitioned_table是轻量操作,InnoDB 下只采样索引页,一般秒级完成 - 如果表上有全局二级索引,
ANALYZE也会更新其统计,避免因索引选择率不准导致慢查询 - 某些监控系统依赖
PARTITION_ROWS字段判断数据倾斜,不ANALYZE就永远显示旧值
分区迁移这事,表面是搬数据,实际是搬元数据一致性。很多人卡在交换后查询变慢,翻半天慢日志才发现是统计信息没更新——这种细节,一漏就白忙半天。










