MySQL 的 DROP PARTITION 不支持 WHERE 条件,必须显式指定分区名,如 ALTER TABLE t DROP PARTITION p2021, p2020;需先通过 INFORMATION_SCHEMA.PARTITIONS 查询分区名再删除。
MySQL 里 DROP PARTITION 不支持 WHERE 条件
想按时间删掉 2022 年前的分区?直接写 alter table t drop partition where dt 会报错:<code>error 1064 (42000): you have an error in your sql syntax。mysql 的 drop partition 只接受显式分区名列表,不支持条件过滤。
实操建议:
- 先用
SELECT PARTITION_NAME FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME = 't' AND TABLE_SCHEMA = 'db'查出所有分区名 - 手动筛选出要删的分区(比如
p202101,p202102),拼成逗号分隔列表 - 执行
ALTER TABLE t DROP PARTITION p202101, p202102 - 如果分区多、命名有规律,可用脚本生成 SQL(Python 或 shell 都行),但别在生产库上直接执行动态拼接语句,先
SELECT CONCAT(...)看结果再确认
PostgreSQL 分区表不能用 DROP PARTITION
PostgreSQL 没有 ALTER TABLE ... DROP PARTITION 语法。它的分区是普通表继承关系或声明式分区(v10+),删除分区实际是 DROP TABLE 子分区本身。
实操建议:
- 查子分区:对声明式分区,用
SELECT inhrelid::regclass FROM pg_inherits WHERE inhparent = 't'::regclass - 确认子分区无外键引用、无活跃查询(
pg_stat_activity过滤),再执行DROP TABLE t_2021_q1 - 如果用了
ATTACH PARTITION,删前记得先DETACH PARTITION,否则报ERROR: cannot detach partition of a partitioned table - 注意:
DROP TABLE会释放磁盘空间,但 WAL 日志量大,大分区建议在低峰期操作
TRUNCATE PARTITION 比 DROP 更安全但不释放表结构
有些场景不需要彻底删分区,只是清空数据、保留结构(比如后续还要写入同周期数据)。Oracle 和 PostgreSQL(v13+)支持 TRUNCATE PARTITION,MySQL 不支持该语法,但可通过 TRUNCATE TABLE 子分区实现类似效果。
实操建议:
- MySQL:若用
LIST或RANGE COLUMNS分区且子分区可单独访问(如mytable#P#p2021),可TRUNCATE TABLE mytable#P#p2021(需开启show_compatibility_56=ON或 MySQL 8.0+ 支持隐式分区表名) - PostgreSQL:直接
TRUNCATE TABLE t_2021_q1,比DROP快,且不影响父表结构和约束 - 风险点:MySQL 中误 truncate 主表会清空全部分区;PostgreSQL 中 truncate 子分区不会触发父表上的
BEFORE TRUNCATE触发器(如有)
分区键类型不匹配会导致 DROP 失败或误删
分区键是 DATE 类型,但传了字符串 '2021-01-01' 当分区名?或者分区名含下划线但脚本按短横线解析?这类类型/格式错位会让 DROP 找不到目标,或删错分区。
实操建议:
- MySQL 分区名严格区分大小写,且不自动补零(
p20211≠p202101) - PostgreSQL 子分区名建议全小写+下划线,避免用连字符(-)导致 SQL 解析失败
- 执行前加校验:比如
SELECT COUNT(*) FROM t PARTITION (p202101)(MySQL)或SELECT COUNT(*) FROM t_202101(PG),确认分区存在且数据量合理 - 线上操作务必加
--dry-run模式(自己写脚本模拟)或先在从库验证
p2021_w01,今年改成 p2022_week01,正则一写死,就跳过新格式分区。

















