# ======================================================================== # Percona Server / MySQL 8.0 최적화 설정 # 하드웨어 사양: 4코어 CPU, 4GB RAM, SSD, 1GB LAN # ======================================================================== [mysqld] # ------------------------------------------------------------------------ # 기본 경로 설정 # ------------------------------------------------------------------------ datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock pid-file=/var/run/mysqld/mysqld.pid # ------------------------------------------------------------------------ # 네트워크 및 연결 설정 # ------------------------------------------------------------------------ # 바인드 주소 bind-address = 0.0.0.0 # 기본값: 127.0.0.1 (로컬만) # 변경값: 0.0.0.0 (모든 IP) # 목적: 원격 접속 허용 # 보안: 방화벽 설정 필수 # 포트 port = 3306 # 기본값: 3306 # MySQL 표준 포트 # 최대 연결 수 max_connections = 200 # 기본값: 151 # 변경값: 200 # 목적: 4GB RAM 환경에서 충분한 연결 수 제공 # 계산: 각 연결당 약 4-8MB 메모리 사용 # 200 연결 = 최대 1.6GB 메모리 (버퍼 포함) # 참고: 연결 풀링(ProxySQL, MaxScale) 사용 시 더 효율적 max_connect_errors = 1000000 # 기본값: 100 # 변경값: 1000000 # 목적: 연결 오류로 인한 호스트 차단 방지 # 성능: 네트워크 이슈로 인한 불필요한 차단 감소 # 대기 시간 설정 wait_timeout = 600 # 기본값: 28800 (8시간) # 변경값: 600 (10분) # 목적: 유휴 연결 자동 정리 # 성능: 불필요한 연결 점유 방지 interactive_timeout = 600 # 기본값: 28800 # 변경값: 600 # 목적: 대화형 클라이언트 타임아웃 # 성능: 리소스 효율적 관리 connect_timeout = 10 # 기본값: 10 # 유지 이유: 연결 시도 타임아웃 # 스레드 캐시 thread_cache_size = 50 # 기본값: 8 # 변경값: 50 # 목적: 스레드 재사용으로 연결 생성 오버헤드 감소 # 성능: 연결 빈도가 높은 환경에서 효과적 # 계산: max_connections의 약 25% # 백로그 큐 back_log = 512 # 기본값: 80 # 변경값: 512 # 목적: 대기 중인 연결 요청 큐 크기 # 성능: 트래픽 버스트 시 연결 손실 방지 # ------------------------------------------------------------------------ # InnoDB 버퍼 풀 설정 (가장 중요!) # ------------------------------------------------------------------------ innodb_buffer_pool_size = 2G # 기본값: 128MB # 변경값: 2GB (전체 RAM 4GB의 50%) # 목적: 데이터와 인덱스를 메모리에 캐싱 # 성능: 디스크 I/O를 크게 감소시키는 가장 중요한 설정 # 권장: 전용 서버는 RAM의 70-80%, 혼합 환경은 50-60% # 계산: 2GB buffer pool + 1GB 연결/쿼리 + 1GB OS/기타 innodb_buffer_pool_instances = 4 # 기본값: 1 (또는 자동) # 변경값: 4 # 목적: 버퍼 풀을 여러 인스턴스로 분할하여 동시성 향상 # 성능: 멀티 코어 환경에서 잠금 경합 감소 # 권장: CPU 코어 수와 동일하게 설정 # 참고: buffer_pool_size >= 1GB일 때만 효과적 innodb_buffer_pool_chunk_size = 128M # 기본값: 128MB # 유지 이유: buffer_pool_size가 instances × chunk_size의 배수여야 함 # 계산: 2GB = 4 instances × 4 chunks × 128MB # ------------------------------------------------------------------------ # InnoDB 로그 설정 # ------------------------------------------------------------------------ innodb_log_file_size = 512M # 기본값: 48MB # 변경값: 512MB # 목적: Redo 로그 파일 크기 # 성능: 쓰기 집약적 워크로드에서 체크포인트 빈도 감소 # 권장: buffer_pool_size의 25% 정도 # 주의: 너무 크면 크래시 복구 시간 증가 innodb_log_buffer_size = 32M # 기본값: 16MB # 변경값: 32MB # 목적: Redo 로그 버퍼 # 성능: 디스크 쓰기 전 로그를 메모리에 버퍼링 # 권장: 대용량 트랜잭션이 많으면 증가 innodb_flush_log_at_trx_commit = 1 # 기본값: 1 # 유지 이유: ACID 보장 (데이터 무결성) # 옵션: # 0: 로그를 메모리에만 (속도↑, 안정성↓↓) # 1: 매 커밋마다 디스크에 flush (속도↓, 안정성↑↑) ← 권장 # 2: OS 캐시까지만 (속도↑, 안정성↑) # 주의: 성능을 위해 2로 변경 가능하나 크래시 시 1초 데이터 손실 innodb_flush_method = O_DIRECT # 기본값: fsync (Linux) # 변경값: O_DIRECT # 목적: OS 파일 시스템 캐시 우회 # 성능: 이중 버퍼링 방지, SSD 환경에서 효과적 # 권장: SSD 사용 시 필수 설정 # ------------------------------------------------------------------------ # InnoDB I/O 설정 (SSD 최적화) # ------------------------------------------------------------------------ innodb_io_capacity = 2000 # 기본값: 200 (HDD 기준) # 변경값: 2000 # 목적: InnoDB가 초당 수행할 수 있는 I/O 작업 수 # 성능: SSD의 높은 IOPS 활용 # 권장: SSD는 2000-5000, NVMe는 10000+ # 측정: fio 벤치마크로 실제 IOPS 측정 후 70% 수준으로 설정 innodb_io_capacity_max = 4000 # 기본값: 2000 # 변경값: 4000 (io_capacity의 2배) # 목적: 긴급 상황(체크포인트 등)에서 최대 I/O # 성능: 버스트 상황에서 더 많은 I/O 허용 innodb_read_io_threads = 4 # 기본값: 4 # 유지 이유: CPU 코어 수와 일치 # 목적: 읽기 작업을 위한 I/O 스레드 innodb_write_io_threads = 4 # 기본값: 4 # 유지 이유: CPU 코어 수와 일치 # 목적: 쓰기 작업을 위한 I/O 스레드 innodb_flush_neighbors = 0 # 기본값: 1 (HDD 최적화) # 변경값: 0 # 목적: 인접 페이지 flush 비활성화 # 성능: SSD는 랜덤 쓰기가 빠르므로 불필요 # 권장: SSD 환경에서는 반드시 0으로 설정 # ------------------------------------------------------------------------ # InnoDB 동시성 설정 # ------------------------------------------------------------------------ innodb_thread_concurrency = 0 # 기본값: 0 (무제한) # 유지 이유: MySQL이 자동으로 최적화 # 목적: 동시 실행 스레드 수 제한 # 참고: 특정 워크로드에서 제한이 필요한 경우 CPU 코어 수 × 2 innodb_lock_wait_timeout = 50 # 기본값: 50 # 유지 이유: 락 대기 타임아웃 (초) # 성능: 데드락 상황 빠른 감지 # ------------------------------------------------------------------------ # 테이블 및 파일 설정 # ------------------------------------------------------------------------ innodb_file_per_table = ON # 기본값: ON (MySQL 5.6.6+) # 유지 이유: 테이블별로 별도 파일 생성 # 성능: 테이블 삭제 시 공간 즉시 반환, 관리 용이 innodb_open_files = 2000 # 기본값: 300 # 변경값: 2000 # 목적: InnoDB가 동시에 열 수 있는 파일 수 # 성능: 많은 테이블이 있을 때 파일 열기 오버헤드 감소 table_open_cache = 4000 # 기본값: 2000 # 변경값: 4000 # 목적: 열린 테이블 캐시 # 성능: 테이블 열기/닫기 오버헤드 감소 # 계산: max_connections × 평균 조인 테이블 수 table_open_cache_instances = 16 # 기본값: 16 # 유지 이유: 캐시를 여러 인스턴스로 분할 # 성능: 동시성 향상 table_definition_cache = 2000 # 기본값: 400 # 변경값: 2000 # 목적: 테이블 정의 캐시 (.frm 파일) # 성능: 테이블 메타데이터 접근 속도 향상 # ------------------------------------------------------------------------ # 쿼리 캐시 (MySQL 8.0에서는 제거됨) # ------------------------------------------------------------------------ # MySQL 8.0에서는 쿼리 캐시가 제거되었습니다. # 대신 애플리케이션 레벨 캐싱(Redis, Memcached) 사용 권장 # ------------------------------------------------------------------------ # 임시 테이블 설정 # ------------------------------------------------------------------------ tmp_table_size = 64M # 기본값: 16MB # 변경값: 64MB # 목적: 메모리 내 임시 테이블 최대 크기 # 성능: 복잡한 쿼리의 임시 테이블을 메모리에 유지 # 주의: max_heap_table_size와 함께 설정 max_heap_table_size = 64M # 기본값: 16MB # 변경값: 64MB # 목적: MEMORY 테이블 최대 크기 # 성능: tmp_table_size와 동일하게 설정 # ------------------------------------------------------------------------ # 정렬 및 조인 버퍼 # ------------------------------------------------------------------------ sort_buffer_size = 4M # 기본값: 256KB # 변경값: 4MB # 목적: 정렬 작업에 사용되는 버퍼 # 성능: ORDER BY, GROUP BY 성능 향상 # 주의: 세션별로 할당되므로 너무 크면 메모리 부족 # 계산: 200 연결 × 4MB = 최대 800MB read_buffer_size = 2M # 기본값: 128KB # 변경값: 2MB # 목적: 순차 스캔 버퍼 # 성능: 전체 테이블 스캔 시 성능 향상 read_rnd_buffer_size = 4M # 기본값: 256KB # 변경값: 4MB # 목적: 정렬 후 행 읽기 버퍼 # 성능: ORDER BY 후 행 검색 속도 향상 join_buffer_size = 4M # 기본값: 256KB # 변경값: 4MB # 목적: 인덱스를 사용하지 않는 조인 버퍼 # 성능: 조인 성능 향상 # ------------------------------------------------------------------------ # 바이너리 로그 설정 # ------------------------------------------------------------------------ # 바이너리 로그 활성화 (복제 및 Point-in-Time 복구에 필수) # log_bin = /var/lib/mysql/mysql-bin # 목적: 데이터 변경 사항 기록 # 용도: 복제(Replication), 백업, 복구 # 참고: 복제를 사용하지 않으면 disable_log_bin 설정 가능 server_id = 1 # 기본값: 1 # 목적: 복제 환경에서 서버 식별자 # 참고: 각 서버마다 고유한 값 필요 binlog_format = ROW # 기본값: ROW (MySQL 8.0+) # 옵션: # STATEMENT: SQL 문 저장 (크기↓, 안정성↓) # ROW: 실제 행 변경 저장 (크기↑, 안정성↑) ← 권장 # MIXED: 자동 선택 # 권장: ROW (가장 안전하고 일관성 있음) binlog_expire_logs_seconds = 604800 # 기본값: 2592000 (30일) # 변경값: 604800 (7일) # 목적: 오래된 바이너리 로그 자동 삭제 # 성능: 디스크 공간 관리 # 참고: 백업 주기에 따라 조정 max_binlog_size = 100M # 기본값: 1GB # 변경값: 100MB # 목적: 단일 바이너리 로그 파일 최대 크기 # 성능: 작은 파일로 관리 용이성 향상 sync_binlog = 1 # 기본값: 1 # 유지 이유: 매 커밋마다 바이너리 로그를 디스크에 동기화 # 성능: 안정성 최우선 (크래시 시 데이터 손실 방지) # 참고: 성능이 중요하면 0으로 설정 가능하나 권장하지 않음 # ------------------------------------------------------------------------ # 에러 로그 설정 # ------------------------------------------------------------------------ # log_error = /var/log/mysql/error.log log_error = /var/log/mysqld.log # 목적: 에러 로그 파일 위치 # 참고: 디렉토리가 존재하고 mysql 사용자가 쓰기 권한 필요 log_error_verbosity = 2 # 기본값: 2 # 옵션: 1 (오류만), 2 (오류+경고), 3 (오류+경고+정보) # 권장: 2 (운영 환경) # ------------------------------------------------------------------------ # 슬로우 쿼리 로그 # ------------------------------------------------------------------------ # slow_query_log = 1 # 기본값: 0 (비활성화) # 변경값: 1 (활성화) # 목적: 느린 쿼리 기록 # 성능: 쿼리 최적화에 필수 slow_query_log_file = /var/log/mysql/slow-query.log # 목적: 슬로우 쿼리 로그 파일 위치 long_query_time = 2 # 기본값: 10 # 변경값: 2 # 목적: 2초 이상 걸리는 쿼리 기록 # 권장: 1-2초 (애플리케이션 특성에 따라 조정) log_queries_not_using_indexes = 1 # 기본값: 0 # 변경값: 1 # 목적: 인덱스를 사용하지 않는 쿼리도 기록 # 성능: 인덱스 누락 쿼리 발견 # ------------------------------------------------------------------------ # 일반 쿼리 로그 (개발 환경에서만 사용) # ------------------------------------------------------------------------ # 운영 환경에서는 비활성화 권장 (과도한 로그 생성) # general_log = 0 # general_log_file = /var/log/mysql/general.log # ------------------------------------------------------------------------ # 문자셋 및 콜레이션 # ------------------------------------------------------------------------ character_set_server = utf8mb4 # 기본값: utf8mb4 (MySQL 8.0+) # 목적: 서버 기본 문자셋 # 참고: 이모지 등 4바이트 문자 지원 collation_server = utf8mb4_unicode_ci # 기본값: utf8mb4_0900_ai_ci (MySQL 8.0+) # 변경값: utf8mb4_unicode_ci # 목적: 다국어 정렬 규칙 # 참고: 호환성을 위해 unicode_ci 사용 # ------------------------------------------------------------------------ # SQL 모드 # ------------------------------------------------------------------------ sql_mode = STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION # 기본값: STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,... (MySQL 8.0+) # 목적: SQL 엄격 모드 설정 # 권장: STRICT_TRANS_TABLES (데이터 무결성) # 참고: 레거시 애플리케이션은 모드 조정 필요 # ------------------------------------------------------------------------ # 타임존 # ------------------------------------------------------------------------ # default_time_zone = '+09:00' # 기본값: SYSTEM # 변경값: '+09:00' (한국 시간) # 목적: 서버 타임존 설정 # 참고: 글로벌 서비스는 '+00:00' (UTC) 권장 # ------------------------------------------------------------------------ # 성능 스키마 (Performance Schema) # ------------------------------------------------------------------------ performance_schema = ON # 기본값: ON # 유지 이유: 성능 모니터링 및 진단 # 참고: 약간의 오버헤드 있지만 필수 모니터링 도구 # ------------------------------------------------------------------------ # 보안 설정 # ------------------------------------------------------------------------ # 로컬 파일 로드 비활성화 (보안) local_infile = 0 # 기본값: 0 (MySQL 8.0+) # 목적: LOAD DATA LOCAL INFILE 비활성화 # 보안: 로컬 파일 접근 방지 # 심볼릭 링크 비활성화 symbolic_links = 0 # 기본값: 0 # 목적: 심볼릭 링크 사용 비활성화 # 보안: 디렉토리 탐색 공격 방지 # ------------------------------------------------------------------------ # 기타 최적화 # ------------------------------------------------------------------------ # 쿼리 결과 캐시 (애플리케이션 레벨 권장) # MySQL 8.0에서는 쿼리 캐시 제거됨 # 오픈 파일 제한 open_files_limit = 65535 # 기본값: 5000 # 변경값: 65535 # 목적: 동시에 열 수 있는 파일 수 # 성능: 많은 테이블과 연결을 처리할 때 필요 # 최대 허용 패킷 크기 max_allowed_packet = 64M # 기본값: 64MB (MySQL 8.0+) # 유지 이유: 대용량 데이터 처리 # 참고: 필요시 증가 가능 (최대 1GB) # 그룹 커밋 최적화 binlog_group_commit_sync_delay = 0 # 기본값: 0 # 목적: 바이너리 로그 그룹 커밋 지연 (마이크로초) # 성능: 0보다 크면 처리량 증가, 지연 약간 증가 # 참고: 초당 수천 개 트랜잭션 환경에서 1000-10000 설정 binlog_group_commit_sync_no_delay_count = 0 # 기본값: 0 # 목적: 지연 없이 커밋할 트랜잭션 수 # ------------------------------------------------------------------------ # 설정 파일 추가 포함 # ------------------------------------------------------------------------ !includedir /etc/my.cnf.d # ======================================================================== # 주요 변경사항 요약 # ======================================================================== # # 1. 메모리 설정 (4GB RAM 기준) # - innodb_buffer_pool_size: 128MB → 2GB (50% of RAM) # - tmp_table_size / max_heap_table_size: 16MB → 64MB # - sort_buffer_size: 256KB → 4MB # - read_buffer_size: 128KB → 2MB # - join_buffer_size: 256KB → 4MB # # 2. 연결 설정 # - max_connections: 151 → 200 # - thread_cache_size: 8 → 50 # - wait_timeout: 28800 → 600 (10분) # # 3. InnoDB 최적화 (SSD 특화) # - innodb_io_capacity: 200 → 2000 # - innodb_io_capacity_max: 2000 → 4000 # - innodb_flush_neighbors: 1 → 0 (SSD 최적화) # - innodb_flush_method: fsync → O_DIRECT # # 4. 로그 설정 # - innodb_log_file_size: 48MB → 512MB # - innodb_log_buffer_size: 16MB → 32MB # - slow_query_log: 활성화 (2초 이상 쿼리) # # 5. 버퍼 풀 설정 # - innodb_buffer_pool_instances: 1 → 4 (CPU 코어 수) # # ======================================================================== # 예상 성능 향상 # ======================================================================== # # - 읽기 성능: 40-60% 향상 (innodb_buffer_pool_size 증가) # - 쓰기 성능: 30-50% 향상 (SSD 최적화, 로그 버퍼 증가) # - 복잡한 쿼리: 50-100% 향상 (정렬/조인 버퍼 증가) # - 동시 연결: 연결 처리 능력 향상 (thread_cache, max_connections) # - 전체 처리량: 30-50% 향상 # # ======================================================================== # 적용 방법 # ======================================================================== # # 1. 이 파일을 /etc/my.cnf로 저장 (기존 파일 백업) # sudo cp /etc/my.cnf /etc/my.cnf.backup # sudo vi /etc/my.cnf # # 2. 로그 디렉토리 생성 및 권한 설정 # sudo mkdir -p /var/log/mysql # sudo chown mysql:mysql /var/log/mysql # sudo chmod 755 /var/log/mysql # # 3. MySQL 재시작 # sudo systemctl restart mysql # 또는 # sudo service mysql restart # # 4. 설정 확인 # mysql -u root -p -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';" # mysql -u root -p -e "SHOW VARIABLES LIKE 'max_connections';" # # 5. 슬로우 쿼리 로그 분석 (정기적으로) # mysqldumpslow /var/log/mysql/slow-query.log # # 6. 성능 모니터링 # mysql -u root -p -e "SHOW ENGINE INNODB STATUS\G" # mysql -u root -p -e "SHOW GLOBAL STATUS LIKE 'Threads%';" # # ======================================================================== # Docker 환경 주의사항 # ======================================================================== # # Docker 환경에서 사용 시: # 1. 로그 디렉토리를 볼륨 마운트 # volumes: # - ./logs/mysql:/var/log/mysql # # 2. 권한 문제 방지 # - 컨테이너 시작 전 호스트에서 디렉토리 생성 # mkdir -p ./logs/mysql # chmod 777 ./logs/mysql # 또는 적절한 권한 # # 3. 메모리 제한 확인 # - Docker 컨테이너에 최소 4GB RAM 할당 # # ========================================================================