hive报错: Specified key was too long; max key length is 767 bytes(详解!!!)

Posted 魏大宾

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hive报错: Specified key was too long; max key length is 767 bytes(详解!!!)相关的知识,希望对你有一定的参考价值。

这篇文章将hive的报错还是比较清楚的。

 

还是一句老话,菜鸡一只,如果有说错的地方,请大家海涵!!~也希望能够批评指出,让小弟能够学习到更多东西~


废话不多说,报错如下:

DataNucleus.Datastore (Log4JLogger.java:error(115)) - An exception was thrown while adding/validating class(es) : Specified key was too long; max key length is 767 bytes
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Specified key was too long; max key length is 767 bytes

然后在全网搜索,几乎所有的文章都没正面讲原因(不好意思,这里用了夸张的手法,如果有说错的,还请见谅),要么就是臭长臭长的,很难受。

还有一个东西提一下,就是hive在控制台打印的报错信息是这样子的:

 ERROR [main]: metastore.RetryingHMSHandler (RetryingHMSHandler.java:invoke(150)) - HMSHandler Fatal error: javax.jdo.JDODataStoreException: Error(s) were found while auto-creating/validating the datastore for classes. The errors are printed in the log, and are attached to this exception.

说实话,第一段很好判断,其实就是mysql的字符集编码的问题(所实话,这是一个很大的问题,后面慢慢解释),然后第二段报错是控制台打印的,只能够看出报错是因为在创建/插入/更新某个数据的数据出现了异常。

所以从这里告诉我们一个道理:出现报错去看log日志好吗?????
Hive中的日志分为两种
1. 系统日志,记录了hive的运行情况,错误状况。
2. Job 日志,记录了Hive 中job的执行的历史过程。

系统日志存储
在$HIVE_HOME/conf/hive-log4j.properties 文件中记录了Hive日志的存储情况
重命名hive-log4j.properties.template   hive-log4j.properties
默认的存储情况:$
hive.root.logger=WARN,DRFA
hive.log.dir=/tmp/$user.name # 默认的存储位置是/tmp这个临时目录(这个目录就好像Windows的回收站)
hive.log.file=hive.log  # 默认的文件名
可以修改到
hive.log.dir=/user/apache-hive-1.2.1-bin/log/$user.name
hive.log.file=hive.log

Hive的Job日志存储
//Location of Hive run time structured log file
    HIVEHISTORYFILELOC("hive.querylog.location", "/tmp/" + System.getProperty("user.name")),
默认存储与 /tmp/user.name目录下。

通过如上的修改,再次生成的hive日志文件,就会在你自己指定的目录中了

扯远了,言归正传!!

所以通过以上的乱七八糟的东西,我们就确定了报错,是mysql中hive的元数据库的字符集问题,也正是因为字符集问题,导致了create或者insert或者load等等操作出现了问题!

1、如果有兴趣和心思,大家可以先研究明白mysql的字符集都有哪些地方是可以设置的。

2、如果没有,那请看接下来鄙人讲的东西。

原因分析:

-1.mysql数据库创建数据库的时候的字符集默认是latin1,很有可能之前被修改过,改成UTF8或者其他

如何查看?

注:这里的a这个库,是我的hive的元数据信息的库

如果是如上的这张图,那么a这个数据库的字符集就是utf-8,并且如果hive在这个库里面生成的相关元数据信息表,这些表也都会是utf-8的字符集!不信你看!

你会发现这里的所有表甚至表中的字段都是utf-8的字符集,并且当你在操作hive的时候,那么就很有可能会出现标题上的错误!

-2.然后你就会去百度,搜索各种各样的文章,发现可以这么修改数据库的字符集

alter database a character set latin1;

这里顺便提一句:

//修改数据库
alter database 数据库名 character set utf8;
//修改表
alter table 表名 convert to character set gbk;
//修改字段
alter table 表名 modify column '字段名' varchar(30) character set gbk not null;
//添加表字段
alter table 表名 add column '字段名' varchar (20) character set gbk;

天真的你发现,已经完全修改过来了,应该不会有问题了!

-3.然而这时候,你重启了你的环境(包括重启虚拟机一大堆杂七杂八的操作),打开hive,发现该报错的还是报错!

-4.为什么呢,你可以尝试下看看元数据库里的表的字符集有改变吗?

-5.所以问题已经很明显了,这样修改虽然数据库的字符集改了,但是其中表的字符集和字段都没改过来

解决:

关于如何解决这个问题网上的说法很多很杂,这里做一些整理

-1.将原来那个元数据信息库删除

drop database a;

-2.手动创建一个空的数据库

create database metastore character set latin1;

或者可以先创建:create database metastore

然后在alter修改字符集

-3.在hive-site.xml中配置

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:mysql://bigdata-01:3306/metastore?createDatabaseIfNotExist=true</value>

<description>JDBC connect string for a JDBC metastore</description>

</property>

-4.然后再去开启hive,如果能正常开启就接着看下一步,如果不行,一定记得看hive的log日志

-5.如果成功了,请记得一定要去mysql中查看metastore中任意一张表的元数据信息

-6.如果你发现表中的元数据信息是latin1,那么你的hive操作就不会报Specified key was too long; max key length is 767 bytes,这样问题就解决了!
--------------------- 
作者:lsr40 
来源:CSDN 
原文:https://blog.csdn.net/lsr40/article/details/79422718 
版权声明:本文为博主原创文章,转载请附上博文链接!

以上是关于hive报错: Specified key was too long; max key length is 767 bytes(详解!!!)的主要内容,如果未能解决你的问题,请参考以下文章

hive报错: Specified key was too long; max key length is 767 bytes(详解!!!)

Specified key was too long; max key length is 767 bytes

hive异常:创建MySQL时Specified key was too long; max key length is 1000 bytes

异常Specified key was too long;max key length is 767 bytes解决由于HDFS格式化造成Hive数据全部丢失的问题

laravel报错1071 Specified key was too long; max key length is 1000 bytes

activiti 创建23张表是报错:Specified key was too long; max key length is 767 bytes