hive 分区值支持中文

本文详细探讨了在Hive中遇到中文分区名插入失败的问题,通过MySQL字符集排查,发现PARTITIONS表使用了latin1字符集导致冲突。解决办法包括修改表字符集至utf8,以及调整关键字段长度。重点在于如何确保字符集兼容性以避免此类问题。
摘要由CSDN通过智能技术生成

背景

hive 插入分区时(insert into 或者add partition等操作)分区值是中文的时候,就出现报错。
alter table test add partition(part=“中文”);
hivemetastore报错信息

2021-12-01T15:25:03,474 ERROR [pool-8-thread-134] bonecp.ConnectionHandle: Database access problem. Killing off this connection and all remaining connections in the connection pool. SQL State = HY000
2021-12-01T15:25:03,478 ERROR [pool-8-thread-134] DataNucleus.Transaction: Operation rollback failed on resource: org.datanucleus.store.rdbms.ConnectionFactoryImpl$EmulatedXAResource@6e8aa02d, error code UNKNOWN and transaction: [DataNucleus Transaction, ID=Xid=
2021-12-01T15:25:03,479 ERROR [pool-8-thread-134] metastore.RetryingHMSHandler: Retrying HMSHandler after 2000 ms (attempt 1 of 10) with error: javax.jdo.JDOException: Exception thrown when executing query : SELECT DISTINCT 'org.apache.hadoop.hive.metastore.model.MPartition' AS `NUCLEUS_TYPE`,`A0`.`CREATE_TIME`,`A0`.`LAST_ACCESS_TIME`,`A0`.`PART_NAME`,`A0`.`PART_ID` FROM `PARTITIONS` `A0` LEFT OUTER JOIN `TBLS` `B0` ON `A0`.`TBL_ID` = `B0`.`TBL_ID` LEFT OUTER JOIN `DBS` `C0` ON `B0`.`DB_ID` = `C0`.`DB_ID` WHERE `B0`.`TBL_NAME` = ? AND `C0`.`NAME` = ? AND `A0`.`PART_NAME` = ?

原因定位

怀疑是中英文的问题,但是还是不能确认。进入mysql控制台,执行上面的命令(需要通过开启mysql通用日志获取到上面错误日志中?的内容)
执行后出现这个错误

ERROR 1267 (HY000): Illegal mix of collations (latin1_swedish_ci,IMPLICIT) and (utf8_general_ci,COERCIBLE) for operation '='

这个时候,可以确定是字符集的问题了。
确认一下,果然PARTITIONS表的字符集是latin1,不支持中文

MariaDB [hivemeta]> show create table PARTITIONS;
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table      | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| PARTITIONS | CREATE TABLE `PARTITIONS` (
  `PART_ID` bigint(20) NOT NULL,
  `CREATE_TIME` int(11) NOT NULL,
  `LAST_ACCESS_TIME` int(11) NOT NULL,
  `PART_NAME` varchar(767) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL,
  `SD_ID` bigint(20) DEFAULT NULL,
  `TBL_ID` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`PART_ID`),
  UNIQUE KEY `UNIQUEPARTITION` (`PART_NAME`,`TBL_ID`),
  KEY `PARTITIONS_N49` (`TBL_ID`),
  KEY `PARTITIONS_N50` (`SD_ID`),
  CONSTRAINT `PARTITIONS_FK1` FOREIGN KEY (`TBL_ID`) REFERENCES `TBLS` (`TBL_ID`),
  CONSTRAINT `PARTITIONS_FK2` FOREIGN KEY (`SD_ID`) REFERENCES `SDS` (`SD_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

解决方案

在hive连接的mysql中执行下面命令,更改字符集为utf8

alter table PARTITIONS default character set utf8;
alter table PARTITION_KEY_VALS default character set utf8;
alter table SDS default character set utf8;
field coding
alter table PARTITIONS modify column PART_name varchar(190) character set utf8;
alter table PARTITION_KEY_VALS modify column PART_KEY_VAL varchar(256) character set utf8;
alter table SDS modify column LOCATION varchar(4000) character set utf8;

细节说明

  1. MariaDB [hivemeta]> alter table PARTITIONS modify column PART_NAME varchar(767) CHARACTER SET utf8;
    ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
    原因:PART_NAME是索引建,按照规定最大的长度就是767字节,而设置为utf8字符集之后,就相当于一个utf8字符要占用3个字节,因此就不能直接设置767,设置200就不会报错了。

mysql的日志开启

  1. show variables like ‘general_log’; – 查看日志是否开启

  2. set global general_log=on; – 开启日志功能

  3. show variables like ‘general_log_file’; – 看看日志文件保存位置

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值