mysql不支持自动冷热分离,需通过外部策略实现:先导出冷数据至clickhouse或hdfs,再删除原表对应数据;分区表、data directory、exchange partition均无法跨系统迁移。

MySQL 本身不支持自动冷热分离,必须靠外部策略或架构配合实现。直接在 MySQL 内部“把冷数据挪到 ClickHouse 或 HDFS”是不可能的——它们是完全独立的存储系统,没有内置通道。真正可行的路径只有一条:先从 MySQL 导出冷数据,再导入目标系统,并切断原表中对应数据的访问路径。
为什么不能用 MySQL 的分区表直接对接 ClickHouse 或 HDFS
MySQL 分区表(如 PARTITION BY RANGE)只是逻辑上拆分、物理上仍存于同一实例的本地磁盘。它无法指向外部存储,更不会自动同步或迁移数据到 ClickHouse 或 HDFS。常见误解是以为加个 DATA DIRECTORY 就能跨系统,但该参数仅支持本地路径,且受限于 MySQL 版本和文件系统权限,对远程 HDFS 或 ClickHouse 完全无效。
试图用 ALTER TABLE ... EXCHANGE PARTITION 把分区“换出”到外部系统,也会失败——该语句只允许与结构完全一致的本地 InnoDB 表交换,不支持跨引擎或跨集群。
-
EXCHANGE PARTITION要求目标表引擎必须是 InnoDB,且主键、索引、字符集等全部一致 -
DATA DIRECTORY在 MySQL 8.0+ 中已弃用,且不支持网络路径或对象存储 - 任何想让 MySQL “托管” ClickHouse/HDFS 数据的配置,都会在启动或查询时报错
Unknown storage engine 'hdfs'或类似提示
真正可用的三类落地方式及选型建议
根据数据量、实时性要求和运维能力,选一种即可,不要混合使用:
-
批量归档 + 定时同步:适合日志、订单、监控等写多读少场景。每天凌晨用
mysqldump或SELECT INTO OUTFILE导出前 N 天数据为 CSV,再用clickhouse-client --query="INSERT FROM INFILE"或hdfs dfs -put写入目标。关键点是导出后执行DELETE FROM orders WHERE create_time ,并确保事务隔离和 binlog 位点一致性。 -
Binlog 解析 + 实时订阅:适合对延迟敏感的业务(如风控、报表)。用
Debezium或Canal捕获 MySQL binlog,过滤出旧数据变更(如UPDATE状态为archived),再投递到 Kafka,由 Flink/ClickHouse JDBC Sink 或自定义 Consumer 写入目标。注意:ClickHouse 不支持 UPDATE/DELETE,所以必须用ReplacingMergeTree引擎 +version字段模拟幂等写入。 -
应用层双写 + 查询路由:最可控也最重。在业务代码中判断写入时间,若
create_time ,则跳过 MySQL,直写 ClickHouse;新数据仍走 MySQL。查询时由中间件(如 ShardingSphere)按时间条件自动路由:最近 90 天查 MySQL,更早查 ClickHouse。缺点是侵入业务,但避免了数据一致性风险。
ClickHouse 建表时容易忽略的关键细节
即使数据成功导入,查询慢或报错往往源于建表配置错误。以下参数不是可选项,而是必填项:
-
MergeTree引擎必须指定ORDER BY,且该字段应是高频查询条件(如event_date或user_id),否则数据无序,WHERE查询会全表扫描 - 如果原始 MySQL 表有自增
id,ClickHouse 不要照搬为主键——改用(event_date, user_id)组合排序,既利于范围查询,又避免单点写入热点 -
TTL必须显式声明,例如TTL event_date + INTERVAL 365 DAY,否则冷数据不会自动落到 HDFS 磁盘(若已配置storage_policy) - 字段类型别硬套:MySQL 的
DATETIME对应 ClickHouse 的DateTime64(3, 'Asia/Shanghai'),而非String;TEXT应转为String,不是FixedString
HDFS 路径和权限配置的典型错误
在 EMR ClickHouse 集群中启用 HDFS 存储策略时,endpoint 和权限最容易出问题:
-
endpoint必须是 NameNode 的 RPC 地址,格式为hdfs://emr-header-1:8020,不是 WebUI 地址(如http://...),也不是 DataNode 地址 - 如果 HDFS 启用了 Kerberos,
clickhouse-server进程必须以有hdfs权限的 principal 启动,且/etc/clickhouse-server/config.xml中需配置<kerberos><principal>clickhouse/emr-header-1@EMR.COM</principal></kerberos> -
min_bytes_for_seek设得太小(如 1KB)会导致大量小 seek 请求压垮 NameNode;设得太大(如 100MB)会让小文件读取变慢。推荐值仍是默认1048576(1MB) - 测试是否生效:插入带
TTL的数据后,运行SELECT name, disk_name FROM system.parts WHERE table = 'your_table' AND active,确认disk_name是你定义的disk_hdfs
实际落地中最常卡住的环节不是技术实现,而是数据一致性校验和删除时机控制:MySQL 中删冷数据前,必须确认 ClickHouse/HDFS 已完成写入且 checksum 匹配;否则就真丢了。这个动作没法全自动,至少需要一个带人工确认开关的脚本。











