如何将同一Hive表中2018/12/31分区数据迁移至2017/12/31分区?
解决Hive分区数据错误迁移的问题
我之前也踩过YYYY周年模式的坑,2017-12-31被归到2018周年确实很闹心,下面给你两种靠谱的迁移方法,按需选择:
方法一:用Hive SQL直接迁移(简单易操作)
这种方法不需要接触HDFS命令,直接在Hive客户端执行即可:
- 先把错误分区的数据写入到正确的目标分区:
-- 替换成你的表名和实际分区字段名 INSERT OVERWRITE TABLE your_table_name PARTITION(year=2017, month=12, day=31) SELECT * FROM your_table_name WHERE year=2018 AND month=12 AND day=31;
注意:如果你的分区字段是字符串类型,要给分区值加单引号,比如
PARTITION(year='2017', month='12', day='31')
- 确认数据迁移完成后,删除错误的分区:
ALTER TABLE your_table_name DROP PARTITION(year=2018, month=12, day=31);
方法二:HDFS移动文件+元数据刷新(大数据量更高效)
如果分区里的数据量很大,用SQL插入会比较慢,直接操作HDFS文件再刷新元数据效率更高:
- 先查询表的HDFS存储路径:
DESCRIBE FORMATTED your_table_name;
找到输出结果里的Location字段,比如hdfs://your-cluster/path/to/your_table
- 用HDFS命令把错误分区的目录移动到正确的路径下:
-- 替换成你的实际路径 hdfs dfs -mv /path/to/your_table/year=2018/month=12/day=31 /path/to/your_table/year=2017/month=12/day=31
- 刷新Hive元数据,让Hive识别新的分区:
MSCK REPAIR TABLE your_table_name;
有些环境下MSCK可能不生效,可以手动添加分区:
ALTER TABLE your_table_name ADD PARTITION(year=2017, month=12, day=31);
- 最后删除错误分区的元数据记录:
ALTER TABLE your_table_name DROP PARTITION(year=2018, month=12, day=31);
重要提醒
- 操作前一定要备份数据!比如先把错误分区的数据复制到临时目录:
hdfs dfs -cp /path/to/your_table/year=2018/month=12/day=31 /tmp/backup_20171231
- 赶紧把SimpleDateFormat的格式串改成
yyyy-MM-dd!小写y才是公历年份,大写Y是周年(基于周的年份),这是个很容易踩的坑。
内容的提问来源于stack exchange,提问作者Aditya Goel




