今天,通过HiveMetaStoreClient查询Hive的表信息,结果在查询的时候,出现主键超长错误,错误日志如下:
2014-05-19 20:34:20,039 INFO DataNucleus.Datastore:The class "org.apache.hadoop.hive.metastore.model.MFieldSchema" is tagged as "embedded-only" so does not have its own datastore table.
2014-05-19 20:34:20,058 INFO DataNucleus.Datastore:The class "org.apache.hadoop.hive.metastore.model.MOrder" is tagged as "embedded-only" so does not have its own datastore table.
2014-05-19 20:34:21,123 ERROR DataNucleus.Datastore:Error thrown executing CREATE TABLE `TABLE_PARAMS`
(
`TBL_ID` BIGINT NOT NULL,
`PARAM_KEY` VARCHAR(256) BINARY NOT NULL,
`PARAM_VALUE` VARCHAR(4000) BINARY NULL,
CONSTRAINT `TABLE_PARAMS_PK` PRIMARY KEY (`TBL_ID`,`PARAM_KEY`)
) ENGINE=INNODB : 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
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:406)
at com.mysql.jdbc.Util.getInstance(Util.java:381)
由于之前MySQL大小写的原因,本人曾将MySQL的元信息库删除重建过,是Hive自动创建的表,但是并不包含Hive全部原信息表,所以在通过HiveMetaStoreClient查询Hive信息时,Hive会自动创建需要的表
回到异常本身,通过查询资料,基本可以定位出由于本人数据库默认设置的UTF-8,而Hive建表编码是latin1,UTF-8字符占用空间较大,所以导致出现主键超过最大长度的异常
解决方案:
在Hive的发布包里面,其实已经包含了每个版本元数据脚本,里面有所有Hive需要的建表语句以及升级脚本,已经Hive元信息支持的数据库类型,以0.12版本的Hive为例,它的脚本目录为:${HIVE_HOME}/scripts/metastore/upgrade/mysql,里面包含了需要的数据库脚本,因此建议安装或者升级完Hive之后,手动将该目录下,对应版本的脚本添加到数据库中