NOTIFICATION_LOG 는 메타스토어의 DDL 이벤트를 쌓는 테이블이다. 테이블 생성, 파티션 추가·삭제 같은 변경이 한 건씩 기록된다.
SELECT NL_ID, EVENT_ID, EVENT_TIME, EVENT_TYPE, DB_NAME, TBL_NAME
FROM NOTIFICATION_LOG ORDER BY EVENT_ID DESC LIMIT 10;
EVENT_TIME 은 epoch 초다.
SELECT FROM_UNIXTIME(MIN(EVENT_TIME)), FROM_UNIXTIME(MAX(EVENT_TIME)), COUNT(*)
FROM NOTIFICATION_LOG;
이 로그를 읽어 가는 소비자가 있다. 복제(replication)와 Hive 메타데이터를 따라가는 외부 시스템이 대표적이다. 소비자가 없거나 정리 주기가 길면 파티션이 많은 클러스터에서 수백만 건까지 쌓인다.
DDL 이벤트 소비자가 있다면 임의로 지우면 그쪽이 깨진다. 지우기 전에 확인한다.
소비자가 없다면 보관 기간 설정으로 자동 정리되게 두는 것이 맞다. 관련 설정은 메타스토어 쪽에 있고 이름은 배포판과 버전에 따라 다르다 (확인 필요).
hive.metastore.event.db.listener.timetolive
이 값이 보관 기간이다. 값을 줄이면 청소 스레드가 기간이 지난 행을 지운다. Cloudera Manager 를 쓴다면 Hive Metastore 의 구성에서 같은 이름을 찾아 바꾸고 메타스토어를 재시작한다.
백업을 먼저 뜬다.
mysqldump -h <host> -u <user> -p metastore NOTIFICATION_LOG > notification_log.sql
한 번에 지우면 락과 바이너리 로그가 크게 늘어난다. 나눠서 지운다.
DELETE FROM NOTIFICATION_LOG
WHERE EVENT_TIME < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL 30 DAY))
LIMIT 10000;
이 문장을 반복 실행해 남은 행이 0 이 될 때까지 돌린다.
MariaDB 는 VACUUM 이 없다. PostgreSQL 문법을 그대로 넣으면 문법 오류가 난다.
ERROR 1064 (42000): You have an error in your SQL syntax
InnoDB 는 행을 지워도 파일 크기가 줄지 않는다. 공간을 회수하려면 테이블을 재구성한다.
OPTIMIZE TABLE NOTIFICATION_LOG;
-- 또는
ALTER TABLE NOTIFICATION_LOG ENGINE=InnoDB;
둘 다 테이블을 다시 만드는 작업이라 잠금이 걸린다. 서비스 영향이 적은 시간에 한다. innodb_file_per_table 이 꺼져 있으면 공유 테이블스페이스라 파일 크기가 아예 줄지 않는다.
SHOW TABLE STATUS FROM metastore;
SELECT table_name,
ROUND((data_length+index_length)/1024/1024) AS mb
FROM information_schema.tables
WHERE table_schema='metastore' ORDER BY mb DESC LIMIT 20;
전체 테이블 무결성을 한 번에 보려면 mysqlcheck 를 쓴다. CHECK TABLE 을 테이블마다 치는 것보다 낫다.
mysqlcheck -h <host> -u <user> -p --check --databases metastore
mysqlcheck -h <host> -u <user> -p --analyze --databases metastore