会,但只阻塞目标分区写入;READ ONLY 不阻止 TRUNCATE/DROP,需配合文件系统权限与权限管控;MySQL 与 Hive 实现本质不同,且旧版 MySQL 可能因优化器缺陷导致查询变慢。
ALTER TABLE MODIFY PARTITION READ ONLY 会阻塞写入吗
会,但只阻塞目标分区的写入,不影响其他分区。执行时,mysql(或 hive/trino 等)会对该分区加元数据锁,新 insert/update/delete 到这个分区的操作会被挂起,直到语句完成。不是全表锁,这点常被误判。
实操建议:
- 避开业务高峰执行,尤其当分区是按天/小时滚动、且下游有实时写入时
- 提前用
SHOW PROCESSLIST或SELECT * FROM information_schema.PROCESSLIST确认没有长事务正往该分区写数据 - 在 Hive 中,
ALTER TABLE ... PARTITION (...) SET TBLPROPERTIES ('readonly'='true')是更轻量的替代,不触发元数据重写,但仅限 Hive 元数据层生效,不阻止底层 HDFS 文件被删
READ ONLY 分区还能被 TRUNCATE 或 DROP 吗
能。只读属性只限制 DML(INSERT/UPDATE/DELETE),不限制 DDL。执行 TRUNCATE PARTITION 或 DROP PARTITION 仍会成功——这恰恰是最大隐患:运维同学可能以为“只读=安全”,结果一删分区,历史数据全丢。
实操建议:
- 必须配合文件系统级防护:比如把分区路径设为 HDFS 只读权限(
hdfs dfs -chmod -R 555 /path/to/partition),或在对象存储上关闭 DELETE 权限 - 在 MySQL 分区表中,没有原生的“不可删分区”机制,只能靠权限控制:回收普通账号的
DROP和ALTER权限,只保留给 DBA 账号 - 自动化脚本里,对含
READ ONLY的分区做DROP前,强制检查information_schema.PARTITIONS表中的PARTITION_DESCRIPTION或自定义注释字段是否标记了 “archived”
Hive 和 MySQL 对 READ ONLY 的实现差异
根本不是一个东西。MySQL 的 ALTER TABLE ... MODIFY PARTITION READ ONLY 是 8.0.26+ 才支持的语法,作用于 InnoDB 分区表,本质是设置分区的内部标志位;而 Hive 没有这个语法,所谓“只读分区”只是社区习惯说法,实际靠 SET TBLPROPERTIES + 外部权限组合模拟。
实操建议:
- MySQL 中确认状态看
INFORMATION_SCHEMA.PARTITIONS表的PARTITION_DESCRIPTION字段是否含READ ONLY字样(注意:不是独立字段) - Hive 中查
DESCRIBE FORMATTED table_name PARTITION(...),重点看Table Parameters:区域是否有readonly=true,但这只是提示,无强制力 - Trino 连接 Hive catalog 时,即使 Hive 元数据标了 readonly,Trino 默认仍允许写入——得在 catalog 配置里显式开启
hive.allow-drop-table=false等策略
为什么 ALTER TABLE ... READ ONLY 后查询变慢了
不是因为只读本身,而是触发了隐式全分区扫描。某些旧版本 MySQL(如 8.0.23 之前)在分区表启用了 READ ONLY 后,优化器可能放弃分区裁剪(partition pruning),转而扫描所有分区再过滤,尤其当 WHERE 条件没覆盖分区键时。
实操建议:
- 执行后立刻验证执行计划:
EXPLAIN SELECT ...,确认partitions列是否只显示目标分区名 - 升级到 MySQL 8.0.33+,该问题已在 Bug #107629 修复
- 若无法升级,改用
SELECT ... FROM table_name PARTITION (p202401)显式指定分区,绕过优化器误判
分区只读不是开关,是权限、元数据、文件系统三层叠加的结果。漏掉任何一层,保护就形同虚设。

















