본문 바로가기
IT 지식/빅데이터 & 분석

Hive의 메타스토어로 MariaDB를 설정했을 때 나는 에러

by 이민우 2024. 2. 26.
728x90
반응형

Hive는 메타데이터를 자체적으로 저장할 수도 있지만, 특정 DB를 설정해 해당 DB에 메타데이터를 저장할 수도 있다.

메타스토어 설정 가능 DB 목록 (https://cwiki.apache.org/confluence/display/Hive/AdminManual+Metastore+Administration)

 

 

이번에 새로운 프로젝트의 개발 및 인프라 구축을 맡게되었다. 그래서 요구사항대로 MariaDB를 메타스토어로 하는 Hive 2.3.6을 설치하려고 했다.

 

설치는 이전과 같이 진행했다.

https://123okk2.tistory.com/414

 

JAVA-HIVE/HBASE 간 통신_Hadoop/HIVE/HBase 설치

프로젝트를 진행하던 중, 빅데이터 플랫폼인 하둡의 대표적인 RDB인 Hive와, NoSQL DB인 HBase에 데이러틀 적재해야 하는 프로그램을 짜야할 일이 생겼다. Hadoop 기반 개발은 처음이기에 꽤 많이 헤멨

123okk2.tistory.com

 

위 게시글에서 추가로 한 일은 hive의 메타스토어를 mariadb로 설정하고, hive 설치 위치의 bin에 mariadb jdbc driver을 설치해준 것밖에 없다.

wget https://dlm.mariadb.com/3752081/Connectors/java/connector-java-3.3.3/mariadb-java-client-3.3.3.jar

 

설정을 마치고 메타 스토어를 생성해준다. 해당 파일은 hive 설치 경로 내 bin 폴더 안에 있다.

./schematool -initSchema -dbType mysql -verbose

 

그리고 hiveserver를 실행한다. 에러가 없이 잘 실행되었고, 아래 쿼리를 입력해보았다.

CREATE DATABASE test;

CREATE TABLE test.test_tbl (
    DATA_1 STRING COMMENT '스트링',
    DATA_2 INT COMMENT '인트'
);

 

그리고 잘 만들어졌는지 여부를 확인하자 아래와 같은 현상이 발생했다.

 

보다시피 COMMENT가 한글을 인식하지 못해 ???로 만들어진 것이다.

 

그래서 initSchema에 탑재된 초기화 쿼리를 보니 DB와 Table Create 시 latin_1로 언어 설정이 되어있음을 확인했다.

 

이를 해결하기 위해 Hive에서 생성한 메타스토어 테이블들의 목록을 긁어와 전부 UTF-8로 변경해주었다. 물론 전체를 할 필요 없이 특정 몇 개의 테이블만 하면 되지만 특정되는 테이블을 찾기 싫고, 또 한글이 주로 사용될 것인데 모든 테이블이 UTF-8이면 좋을 것 같아 전체에 적용했다.

ALTER TABLE AUX_TABLE CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE BUCKETING_COLS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE CDS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE COLUMNS_V2 CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE COMPACTION_QUEUE CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE COMPLETED_COMPACTIONS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE COMPLETED_TXN_COMPONENTS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE DATABASE_PARAMS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE DBS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE DB_PRIVS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE DELEGATION_TOKENS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE FUNCS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE FUNC_RU CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE GLOBAL_PRIVS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE HIVE_LOCKS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE IDXS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE INDEX_PARAMS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE KEY_CONSTRAINTS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE MASTER_KEYS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE NEXT_COMPACTION_QUEUE_ID CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE NEXT_LOCK_ID CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE NEXT_TXN_ID CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE NOTIFICATION_LOG CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE NOTIFICATION_SEQUENCE CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE NUCLEUS_TABLES CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE PARTITIONS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE PARTITION_EVENTS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE PARTITION_KEYS CONVERT TO CHARACTER SET utf8 COLLATE UTF8_UNICODE_CI;
ALTER TABLE PART_PRIVS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE ROLES CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE ROLE_MAP CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SDS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SD_PARAMS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SEQUENCE_TABLE CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SERDES CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SERDE_PARAMS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SKEWED_COL_NAMES CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SKEWED_COL_VALUE_LOC_MAP CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SKEWED_STRING_LIST CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SKEWED_STRING_LIST_VALUES CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SKEWED_VALUES CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE SORT_COLS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE TABLE_PARAMS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE TAB_COL_STATS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE TBLS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE TBL_PRIVS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE TXNS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE TXN_COMPONENTS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE TYPES CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE TYPE_FIELDS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE VERSION CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
ALTER TABLE WRITE_SET CONVERT TO CHARACTER SET utf8 COLLATE UTF8_UNICODE_CI;

-- 아래 세 개 테이블은 에러가 발생해서 제외
-- ALTER TABLE PART_COL_PRIVS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
-- ALTER TABLE PART_COL_STATS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;
-- ALTER TABLE TBL_COL_PRIVS CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

 

참고로 제외된 세 개의 테이블은 PK의 길이가 너무 길어 아래의 에러가 발생한다.

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

 

mariadb의 pk가 가질 수 있는 VARCHAR의 최대 칼럼 길이를 벗어나서 생기는 문제이므로, 세 개의 테이블 각각에서 길이가 너무 긴 컬럼들의 length를 256으로 변경하면 된다.

 

하지만 앞서 설명했듯 모든 테이블을 변경할 필요가 애초에 필요가 없으므로, 그냥 진행한다.

 

이제 아까 만든 테이블을 재생성해보자.

DROP TABLE test.test_tbl;

CREATE TABLE test.test_tbl (
    DATA_1 STRING COMMENT '스트링',
    DATA_2 INT COMMENT '인트'
);

 

겉보기에는 한글도 잘 들어갔고 잘 만들어진 것처럼 보인다.

 

그러나 사실은 정상 작동하지 않는 상태이다. 아래 쿼리를 입력해보자.

USE test;

SHOW TABLES;

 

 

그럼 아래와 같은 에러가 출력될 것이다.

Error: org.apache.hive.service.cli.HiveSQLException: Error while processing statement: FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. MetaException(message:Got exception: org.apache.hadoop.hive.metastore.api.MetaException Exception thrown when executing query : SELECT A0.TBL_NAME,A0.TBL_NAME AS NUCORDER0 FROM TBLS A0 LEFT OUTER JOIN DBS B0 ON A0.DB_ID = B0.DB_ID WHERE B0.`NAME` = ? AND LOWER(A0.TBL_NAME) LIKE '_%' ESCAPE '\' ORDER BY NUCORDER0)
        at org.apache.hive.service.cli.operation.Operation.toSQLException(Operation.java:380)
        at org.apache.hive.service.cli.operation.SQLOperation.runQuery(SQLOperation.java:257)
        at org.apache.hive.service.cli.operation.SQLOperation.access$800(SQLOperation.java:91)
        at org.apache.hive.service.cli.operation.SQLOperation$BackgroundWork$1.run(SQLOperation.java:348)
        at java.security.AccessController.doPrivileged(Native Method)
        at javax.security.auth.Subject.doAs(Subject.java:422)
        at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1657)
        at org.apache.hive.service.cli.operation.SQLOperation$BackgroundWork.run(SQLOperation.java:362)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java.lang.Thread.run(Thread.java:750)
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: MetaException(message:Got exception: org.apache.hadoop.hive.metastore.api.MetaException Exception thrown when executing query : SELECT A0.TBL_NAME,A0.TBL_NAME AS NUCORDER0 FROM TBLS A0 LEFT OUTER JOIN DBS B0 ON A0.DB_ID = B0.DB_ID WHERE B0.`NAME` = ? AND LOWER(A0.TBL_NAME) LIKE '_%' ESCAPE '\' ORDER BY NUCORDER0)
        at org.apache.hadoop.hive.ql.metadata.Hive.getTablesByType(Hive.java:1428)
        at org.apache.hadoop.hive.ql.exec.DDLTask.showTablesOrViews(DDLTask.java:2545)
        at org.apache.hadoop.hive.ql.exec.DDLTask.execute(DDLTask.java:444)
        at org.apache.hadoop.hive.ql.exec.Task.executeTask(Task.java:199)
        at org.apache.hadoop.hive.ql.exec.TaskRunner.runSequential(TaskRunner.java:100)
        at org.apache.hadoop.hive.ql.Driver.launchTask(Driver.java:2183)
        at org.apache.hadoop.hive.ql.Driver.execute(Driver.java:1839)
        at org.apache.hadoop.hive.ql.Driver.runInternal(Driver.java:1526)
        at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1237)
        at org.apache.hadoop.hive.ql.Driver.run(Driver.java:1232)
        at org.apache.hive.service.cli.operation.SQLOperation.runQuery(SQLOperation.java:255)
        ... 11 more
Caused by: MetaException(message:Got exception: org.apache.hadoop.hive.metastore.api.MetaException Exception thrown when executing query : SELECT A0.TBL_NAME,A0.TBL_NAME AS NUCORDER0 FROM TBLS A0 LEFT OUTER JOIN DBS B0 ON A0.DB_ID = B0.DB_ID WHERE B0.`NAME` = ? AND LOWER(A0.TBL_NAME) LIKE '_%' ESCAPE '\' ORDER BY NUCORDER0)
        at org.apache.hadoop.hive.metastore.MetaStoreUtils.logAndThrowMetaException(MetaStoreUtils.java:1390)
        at org.apache.hadoop.hive.metastore.HiveMetaStoreClient.getTables(HiveMetaStoreClient.java:1400)
        at org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient.getTables(SessionHiveMetaStoreClient.java:154)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.apache.hadoop.hive.metastore.RetryingMetaStoreClient.invoke(RetryingMetaStoreClient.java:173)
        at cohttp://m.sun.proxy.$Proxy37.getTables(Unknown Source)
        at org.apache.hadoop.hive.ql.metadata.Hive.getTablesByType(Hive.java:1424)
        ... 21 more (state=08S01,code=1)

 

처음에는 UTF-8 포멧의 문제인줄 알았다. 하지만 로그를 자세히 읽어보니, 특정 쿼리 실행에 문제가 되었고, 그 쿼리를 가져와 돌려보았다.

SELECT 
	A0.TBL_NAME,
	A0.TBL_NAME AS NUCORDER0 
FROM 
	TBLS A0 
	LEFT OUTER JOIN DBS B0 
	ON A0.DB_ID = B0.DB_ID 
WHERE 
	B0.`NAME` = 'test' AND 
	LOWER(A0.TBL_NAME) LIKE '_%' ESCAPE '\' ORDER BY NUCORDER0

 

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''\' ORDER BY NUCORDER0' at line 1

 

 

이는 \가 뒤의 '를 \'로 인식해서 발생하는 문제이다. 직접 쿼리를 눈으로 보면 \' 뒤의 모든 SQL이 하나의 문장으로 인식되고 있음을 확인할 수 있다.

 

바꾸는 방법은 간단한데, \를 \\로 바꿔주면 된다.

 

그런데 그렇다고 hive의 모든 쿼리를 일일히 찾아 바꿀 수는 없다.

그래서 설정을 찾아보니 아래와 같은 설정이 존재했다.

 

/etc/my.cnf 파일에서 위 내용을 추가한 후, mariadb와 hive2를 재실행시켜보았다.

 

참고로 아래는 모든 설정이다.

[client-server]
!includedir /etc/my.cnf.d

[client]
character-sets-dir = utf8
default-character-set = utf8

[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
character_set_server= utf8
collation_server=utf8_general_ci

init_connect = "SET collation_connection = utf8_general_ci"
init_connect = "SET NAMES utf8"
sql_mode=NO_BACKSLASH_ESCAPES

[mysqldump]
default-character-set = utf8

[mysql]
default-character-set = utf8

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0
# Settings user and group are ignored when systemd is used.
# If you need to run mysqld under a different user or group,
# customize your systemd unit file for mariadb according to the
# instructions in http://fedoraproject.org/wiki/Systemd

[mysqld_safe]
log-error=/var/log/mariadb/mariadb.log
pid-file=/var/run/mariadb/mariadb.pid

#
# include all files from the config directory
#
!includedir /etc/my.cnf.d

 

각설하고, 재실행 후 아까 에러가 난 show table 쿼리를 다시 실행해보면 아래와 같이 정상 작동함을 확인할 수 있다.

728x90
반응형