廢話不多說,報錯如下:
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.所以問題已經很明顯了,這樣修改雖然數據庫的字符集改了,但是其中表的字符集和字段都沒改過來