Zabbix DB가 느릴 때: MySQL 파티션으로 해결하는 실무 구축법 (2편) — 디스크 분리와 Tablespace 구성으로 I/O 분산하기

개요

이 문서는 Zabbix DB가 점점 느려지는 주요 원인 중 하나인 I/O 집중 문제를 줄이기 위한 실무 가이드다.
MySQL 8.x에서 Zabbix의 history·trends 데이터를 별도 디스크로 분리하고,
General Tablespace를 구성해 데이터 저장 경로를 명확히 분리하는 과정을 다룬다.

1편에서 Zabbix 7.4 + MySQL 설치와 스키마 로드를 완료했다면,
이제부터는 디스크 구조를 나누고 테이블을 실제 물리적으로 분리하는 단계다.


1) 전제 조건

  • OS: Ubuntu 22.04
  • DB: MySQL 8.x
  • 스키마: /var/lib/mysql/zabbix (이미 1편에서 생성 완료)
  • 별도 디스크: /data (마운트 완료 상태)
  • MySQL 프로세스 소유자: mysql:mysql

이 작업은 MySQL이 기동 중이어도 가능하지만,
데이터 디렉토리 추가 → AppArmor 정책 수정 → MySQL 재시작 순으로 반드시 진행해야 한다.


2) 디렉토리 생성 및 권한 설정

# 디렉토리 생성
mkdir -p /data/history
mkdir -p /data/trends

# 권한 설정
chown -R mysql:mysql /data
chmod 700 /data/history /data/trends

체크포인트

  • MySQL 서비스 계정(mysql)이 /data 이하를 읽고 쓸 수 있어야 함.
  • /data 디스크가 별도 장치(sdb 등)로 마운트되어 있어야 I/O 분산 효과가 있다.

3) AppArmor 정책 수정

MySQL은 AppArmor를 통해 접근 가능한 경로를 제한한다.
새로 만든 /data 경로를 허용하지 않으면, 테이블스페이스 생성 시 “access denied”가 발생한다.

vi /etc/apparmor.d/usr.sbin.mysqld

아래 두 줄을 추가한다:

/data/ r,
/data/** rwk,

저장 후 AppArmor를 재시작한다:

systemctl restart apparmor

체크포인트

  • /data/가 포함된 줄이 정책에 추가되어야 함.
  • 로그(/var/log/syslog)에 “AppArmor parser error”가 없어야 함.

4) MySQL 설정에 디렉토리 등록

MySQL 8.0.21 이후 버전부터는 테이블스페이스를 생성할 수 있는 경로를 미리 지정해야 한다.

vi /etc/mysql/mysql.conf.d/mysqld.cnf

맨 하단에 아래 설정을 추가한다:

innodb_directories=/data

저장 후 MySQL 재시작:

systemctl restart mysql

체크포인트

  • mysql> SHOW VARIABLES LIKE 'innodb_directories';
    → 값이 /data로 표시되어야 함.

5) General Tablespace 생성

이제 각 디스크에 Tablespace를 생성한다.

mysql -uroot -p
# (패스워드 입력)

use zabbix;

-- history용 테이블스페이스 (/data/history)
CREATE TABLESPACE ts_history ADD DATAFILE '/data/history/ts_history.ibd' ENGINE=InnoDB;

-- trends용 테이블스페이스 (/data/trends)
CREATE TABLESPACE ts_trends ADD DATAFILE '/data/trends/ts_trends.ibd' ENGINE=InnoDB;

결과 확인

ls -l /data/history/ts_history.ibd
ls -l /data/trends/ts_trends.ibd

두 파일이 실제로 생성되어 있어야 한다.
파일이 보이지 않는다면 AppArmor 설정이나 innodb_directories 설정이 누락된 것이다.


6) 기존 테이블을 테이블스페이스로 이동

Zabbix는 설치 시 기본적으로 모든 데이터를 /var/lib/mysql/zabbix에 저장한다.
이제 ALTER TABLE 명령으로 history·trends 데이터를 별도 디스크로 분리한다.

-- history 계열 → /data/history
ALTER TABLE zabbix.history       TABLESPACE ts_history;
ALTER TABLE zabbix.history_uint  TABLESPACE ts_history;

-- trends 계열 → /data/trends
ALTER TABLE zabbix.trends        TABLESPACE ts_trends;
ALTER TABLE zabbix.trends_uint   TABLESPACE ts_trends;

7) 작업 이후 점검

  1. /data/history/data/trends에 각 테이블의 .ibd 파일이 실제로 이동되었는지 확인
  2. du -sh /var/lib/mysql/zabbix/data/history 사이 용량 차이 확인
  3. mysql> SHOW ENGINE INNODB STATUS\G 명령으로 오류 여부 점검
  4. AppArmor가 계속 차단하면 /etc/apparmor.d/cache/를 삭제 후 apparmor_parser -r 재적용

8) 마무리 요약

단계명령/작업목적
/data 디렉토리 생성mkdir, chown물리적 디스크 분리
AppArmor 수정/data/** rwk,접근 허용
MySQL 설정innodb_directories=/data테이블스페이스 허용 경로 등록
테이블스페이스 생성CREATE TABLESPACE디스크별 I/O 분산
테이블 이동ALTER TABLE ... TABLESPACEZabbix 핵심 테이블 이동
검증SELECT TABLE_NAME, TABLESPACE_NAME실제 분리 확인

9) 다음 편 예고

3편에서는 MySQL 8.0 환경에서 file-per-table로 전환한 뒤
historytrends를 각각 일 단위 / 월 단위 파티션으로 구성하는 과정을 다룬다.
여기서부터는 실질적인 DB I/O 최적화가 시작된다.

ⓒ 2025 엉뚱한 녀석의 블로그 [quirky guy's Blog]. 본문 및 이미지를 무단 복제·배포할 수 없습니다. 공유 시 반드시 원문 링크를 명시해 주세요.
ⓒ 2025 엉뚱한 녀석의 블로그 [quirky guy's Blog]. All rights reserved. Unauthorized copying or redistribution of the text and images is prohibited. When sharing, please include the original source link.

🛠 마지막 수정일: 2025.10.27