diff --git a/compose/web_service/nginx_uvicorn/.env b/compose/web_service/nginx_uvicorn/.env index bb90f78..b911edf 100644 --- a/compose/web_service/nginx_uvicorn/.env +++ b/compose/web_service/nginx_uvicorn/.env @@ -4,4 +4,8 @@ LOG_OPT_MAXF=5 LOG_OPT_MAXS=100m CELERY_BROKER_URL=redis://redis:6379/3 FLOWER_ID=admin -FLOWER_PWD=admin \ No newline at end of file +FLOWER_PWD=admin +POSTGRES_DB=ado3_dev +POSTGRES_USER=ado3_dev_admin +POSTGRES_PASSWORD=ado31324 +MYSQL_PASSWORD=ado31324 \ No newline at end of file diff --git a/compose/web_service/nginx_uvicorn/docker-compose.yml b/compose/web_service/nginx_uvicorn/docker-compose.yml index ebe686a..b135cd8 100644 --- a/compose/web_service/nginx_uvicorn/docker-compose.yml +++ b/compose/web_service/nginx_uvicorn/docker-compose.yml @@ -154,3 +154,48 @@ services: restart: always profiles: - redis + + postgres: + image: postgres:latest + logging: + driver: "${LOG_DRIVER}" + options: + max-file: "${LOG_OPT_MAXF}" + max-size: "${LOG_OPT_MAXS}" + container_name: postgres + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - ./pgdata:/var/lib/postgresql/18/docker + - ../../../config/database/postgresql/postgresql.conf:/var/lib/postgresql/18/docker/postgresql.conf + - ../../../config/database/postgresql/pg_hba.conf:/var/lib/postgresql/18/docker/pg_hba.conf + # - ../../../config/database/postgresql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro + - ../../../logs/postgresql:/var/log/postgresql + restart: always + profiles: + - postgres + + mysql: + image: percona/percona-server:latest + logging: + driver: "${LOG_DRIVER}" + options: + max-file: "${LOG_OPT_MAXF}" + max-size: "${LOG_OPT_MAXS}" + container_name: mysql + environment: + MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD} + TZ: Asia/Seoul + ports: + - "3306:3306" + - "10057:10057" + volumes: + - ./mysql:/var/lib/mysql + - ../../../config/mysql/my.cnf:/etc/my.cnf + # - ../../../config/mysql/init.sql:/docker-entrypoint-initdb.d/init.sql:ro + - ../../../logs/mysql:/var/log/mysql + restart: always + profiles: + - mysql \ No newline at end of file diff --git a/compose/web_service/nginx_uvicorn/pgdata/.gitkeep b/compose/web_service/nginx_uvicorn/pgdata/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/database/mysql/init.sql b/config/database/mysql/init.sql new file mode 100644 index 0000000..1ccc7dd --- /dev/null +++ b/config/database/mysql/init.sql @@ -0,0 +1,5 @@ +-- 1. admin 권한 계정 생성 +CREATE USER IF NOT EXISTS 'devadmin'@'%' IDENTIFIED BY 'test!'; +-- 2. 전체 권한 부여 +GRANT ALL PRIVILEGES ON *.* TO 'devadmin'@'%' WITH GRANT OPTION; +FLUSH PRIVILEGES; \ No newline at end of file diff --git a/config/database/mysql/my.cnf b/config/database/mysql/my.cnf new file mode 100644 index 0000000..4f36fcb --- /dev/null +++ b/config/database/mysql/my.cnf @@ -0,0 +1,546 @@ +# ======================================================================== +# 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 할당 +# +# ======================================================================== diff --git a/config/database/postgresql/init.sql b/config/database/postgresql/init.sql new file mode 100644 index 0000000..b38e384 --- /dev/null +++ b/config/database/postgresql/init.sql @@ -0,0 +1,4 @@ +CREATE ROLE IF NOT EXISTS devadmin WITH + LOGIN + PASSWORD 'test!' + SUPERUSER; diff --git a/config/database/postgresql/pg_hba.conf b/config/database/postgresql/pg_hba.conf new file mode 100644 index 0000000..b5be892 --- /dev/null +++ b/config/database/postgresql/pg_hba.conf @@ -0,0 +1,128 @@ +# PostgreSQL Client Authentication Configuration File +# =================================================== +# +# Refer to the "Client Authentication" section in the PostgreSQL +# documentation for a complete description of this file. A short +# synopsis follows. +# +# ---------------------- +# Authentication Records +# ---------------------- +# +# This file controls: which hosts are allowed to connect, how clients +# are authenticated, which PostgreSQL user names they can use, which +# databases they can access. Records take one of these forms: +# +# local DATABASE USER METHOD [OPTIONS] +# host DATABASE USER ADDRESS METHOD [OPTIONS] +# hostssl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnossl DATABASE USER ADDRESS METHOD [OPTIONS] +# hostgssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# hostnogssenc DATABASE USER ADDRESS METHOD [OPTIONS] +# +# (The uppercase items must be replaced by actual values.) +# +# The first field is the connection type: +# - "local" is a Unix-domain socket +# - "host" is a TCP/IP socket (encrypted or not) +# - "hostssl" is a TCP/IP socket that is SSL-encrypted +# - "hostnossl" is a TCP/IP socket that is not SSL-encrypted +# - "hostgssenc" is a TCP/IP socket that is GSSAPI-encrypted +# - "hostnogssenc" is a TCP/IP socket that is not GSSAPI-encrypted +# +# DATABASE can be "all", "sameuser", "samerole", "replication", a +# database name, a regular expression (if it starts with a slash (/)) +# or a comma-separated list thereof. The "all" keyword does not match +# "replication". Access to replication must be enabled in a separate +# record (see example below). +# +# USER can be "all", a user name, a group name prefixed with "+", a +# regular expression (if it starts with a slash (/)) or a comma-separated +# list thereof. In both the DATABASE and USER fields you can also write +# a file name prefixed with "@" to include names from a separate file. +# +# ADDRESS specifies the set of hosts the record matches. It can be a +# host name, or it is made up of an IP address and a CIDR mask that is +# an integer (between 0 and 32 (IPv4) or 128 (IPv6) inclusive) that +# specifies the number of significant bits in the mask. A host name +# that starts with a dot (.) matches a suffix of the actual host name. +# Alternatively, you can write an IP address and netmask in separate +# columns to specify the set of hosts. Instead of a CIDR-address, you +# can write "samehost" to match any of the server's own IP addresses, +# or "samenet" to match any address in any subnet that the server is +# directly connected to. +# +# METHOD can be "trust", "reject", "md5", "password", "scram-sha-256", +# "gss", "sspi", "ident", "peer", "pam", "oauth", "ldap", "radius" or +# "cert". Note that "password" sends passwords in clear text; "md5" or +# "scram-sha-256" are preferred since they send encrypted passwords. +# +# OPTIONS are a set of options for the authentication in the format +# NAME=VALUE. The available options depend on the different +# authentication methods -- refer to the "Client Authentication" +# section in the documentation for a list of which options are +# available for which authentication methods. +# +# Database and user names containing spaces, commas, quotes and other +# special characters must be quoted. Quoting one of the keywords +# "all", "sameuser", "samerole" or "replication" makes the name lose +# its special character, and just match a database or username with +# that name. +# +# --------------- +# Include Records +# --------------- +# +# This file allows the inclusion of external files or directories holding +# more records, using the following keywords: +# +# include FILE +# include_if_exists FILE +# include_dir DIRECTORY +# +# FILE is the file name to include, and DIR is the directory name containing +# the file(s) to include. Any file in a directory will be loaded if suffixed +# with ".conf". The files of a directory are ordered by name. +# include_if_exists ignores missing files. FILE and DIRECTORY can be +# specified as a relative or an absolute path, and can be double-quoted if +# they contain spaces. +# +# ------------- +# Miscellaneous +# ------------- +# +# This file is read on server startup and when the server receives a +# SIGHUP signal. If you edit the file on a running system, you have to +# SIGHUP the server for the changes to take effect, run "pg_ctl reload", +# or execute "SELECT pg_reload_conf()". +# +# ---------------------------------- +# Put your actual configuration here +# ---------------------------------- +# +# If you want to allow non-local connections, you need to add more +# "host" records. In that case you will also need to make PostgreSQL +# listen on a non-local interface via the listen_addresses +# configuration parameter, or via the -i or -h command line switches. + +# CAUTION: Configuring the system for local "trust" authentication +# allows any local user to connect as any PostgreSQL user, including +# the database superuser. If you do not trust all your local users, +# use another authentication method. + + +# TYPE DATABASE USER ADDRESS METHOD + +# "local" is for Unix domain socket connections only +local all all trust +# IPv4 local connections: +host all all 127.0.0.1/32 trust +# IPv6 local connections: +host all all ::1/128 trust +# Allow replication connections from localhost, by a user with the +# replication privilege. +local replication all trust +host replication all 127.0.0.1/32 trust +host replication all ::1/128 trust + +host all all all scram-sha-256 diff --git a/config/database/postgresql/postgresql.conf b/config/database/postgresql/postgresql.conf new file mode 100644 index 0000000..0ab73ce --- /dev/null +++ b/config/database/postgresql/postgresql.conf @@ -0,0 +1,766 @@ +# ----------------------------- +# PostgreSQL 18 최적화 설정 +# 하드웨어 사양: 4코어 CPU, 4GB RAM, SSD, 1GB LAN +# ----------------------------- + +#------------------------------------------------------------------------------ +# FILE LOCATIONS +#------------------------------------------------------------------------------ + +#data_directory = 'ConfigDir' +#hba_file = 'ConfigDir/pg_hba.conf' +#ident_file = 'ConfigDir/pg_ident.conf' +#external_pid_file = '' + +#------------------------------------------------------------------------------ +# CONNECTIONS AND AUTHENTICATION +#------------------------------------------------------------------------------ + +# - Connection Settings - + +listen_addresses = '*' +# 기본값: 'localhost' +# 변경값: '*' (모든 IP에서 접근 허용) +# 목적: 네트워크를 통한 원격 접속 허용 + +#port = 5432 + +max_connections = 100 +# 기본값: 100 +# 유지 이유: 4GB RAM 환경에서 적절한 연결 수 +# 성능: 각 연결은 약 10MB의 메모리를 사용하므로 100개 연결 = 약 1GB +# 참고: 연결 풀링(pgBouncer 등) 사용 시 더 효율적 + +#reserved_connections = 0 +#superuser_reserved_connections = 3 +#unix_socket_directories = '/var/run/postgresql' +#unix_socket_group = '' +#unix_socket_permissions = 0777 +#bonjour = off +#bonjour_name = '' + +# - TCP settings - + +tcp_keepalives_idle = 60 +# 기본값: 0 (시스템 기본값 사용, 보통 7200초) +# 변경값: 60초 +# 목적: 유휴 연결을 60초마다 체크하여 죽은 연결을 빠르게 감지 +# 성능: 네트워크 장애 시 빠른 연결 정리로 리소스 확보 + +tcp_keepalives_interval = 10 +# 기본값: 0 (시스템 기본값 사용, 보통 75초) +# 변경값: 10초 +# 목적: keepalive 재전송 간격 +# 성능: 연결 문제를 빠르게 탐지 + +tcp_keepalives_count = 3 +# 기본값: 0 (시스템 기본값 사용, 보통 9회) +# 변경값: 3회 +# 목적: 연결 실패 판정까지의 재시도 횟수 +# 성능: 60초 + (10초 × 3) = 최대 90초 내에 죽은 연결 정리 + +#tcp_user_timeout = 0 +#client_connection_check_interval = 0 + +# - Authentication - + +#authentication_timeout = 1min +#password_encryption = scram-sha-256 +#scram_iterations = 4096 + +# - SSL - + +#ssl = off +#ssl_ca_file = '' +#ssl_cert_file = 'server.crt' + +#------------------------------------------------------------------------------ +# RESOURCE USAGE (except WAL) +#------------------------------------------------------------------------------ + +# - Memory - + +shared_buffers = 1GB +# 기본값: 128MB +# 변경값: 1GB (전체 RAM 4GB의 25%) +# 목적: 데이터베이스가 디스크에서 읽은 데이터를 캐시하는 메모리 +# 성능: 자주 사용되는 데이터를 메모리에 유지하여 디스크 I/O 크게 감소 +# 참고: PostgreSQL에서 가장 중요한 메모리 설정 중 하나 + +huge_pages = try +# 기본값: try +# 유지 이유: 가능한 경우 huge pages 사용으로 메모리 관리 효율 향상 +# 성능: TLB 미스 감소, 대용량 shared_buffers 사용 시 특히 효과적 + +#huge_page_size = 0 +#temp_buffers = 8MB +#max_prepared_transactions = 0 + +work_mem = 16MB +# 기본값: 4MB +# 변경값: 16MB +# 목적: 정렬, 해시 테이블 등 쿼리 작업에 사용되는 메모리 +# 성능: 복잡한 쿼리의 정렬/조인 성능 향상, 디스크 임시 파일 사용 감소 +# 주의: (max_connections × work_mem)이 너무 크면 OOM 위험 +# 계산: 100 연결 × 16MB = 최대 1.6GB (복잡한 쿼리가 동시 실행될 경우) + +#hash_mem_multiplier = 2.0 + +maintenance_work_mem = 256MB +# 기본값: 64MB +# 변경값: 256MB (RAM의 약 6%) +# 목적: VACUUM, CREATE INDEX, ALTER TABLE 등 유지보수 작업에 사용 +# 성능: 인덱스 생성 및 VACUUM 작업 속도 대폭 향상 +# 참고: 유지보수 작업은 동시에 많이 실행되지 않으므로 크게 설정 가능 + +autovacuum_work_mem = 256MB +# 기본값: -1 (maintenance_work_mem 사용) +# 변경값: 256MB +# 목적: autovacuum 전용 메모리 할당 +# 성능: autovacuum 성능 향상으로 테이블 bloat 감소 + +#logical_decoding_work_mem = 64MB + +max_stack_depth = 2MB +# 기본값: 2MB +# 유지 이유: 기본값이 대부분의 경우에 적절 + +#shared_memory_type = mmap + +dynamic_shared_memory_type = posix +# 기본값: posix (Linux에서) +# 유지 이유: Linux에서 가장 효율적인 방식 + +#min_dynamic_shared_memory = 0MB + +# - Disk - + +#temp_file_limit = -1 +#file_copy_method = copy + +# - Kernel Resources - + +#max_files_per_process = 1000 + +# - Background Writer - + +bgwriter_delay = 200ms +# 기본값: 200ms +# 유지 이유: SSD 환경에서도 기본값이 적절 + +bgwriter_lru_maxpages = 100 +# 기본값: 100 +# 유지 이유: 백그라운드 쓰기 작업의 균형 유지 + +#bgwriter_lru_multiplier = 2.0 + +bgwriter_flush_after = 512kB +# 기본값: 512kB +# 유지 이유: SSD에서 적절한 flush 크기 + +# - I/O - + +#backend_flush_after = 0 + +effective_io_concurrency = 200 +# 기본값: 1 (HDD), 16 (SSD 감지 시) +# 변경값: 200 +# 목적: SSD의 높은 IOPS를 활용한 병렬 I/O 요청 수 +# 성능: bitmap heap scan 등에서 여러 페이지를 동시에 prefetch +# 참고: SSD는 동시 I/O 처리 능력이 뛰어나므로 높게 설정 + +maintenance_io_concurrency = 200 +# 기본값: 10 +# 변경값: 200 +# 목적: VACUUM, CREATE INDEX 등 유지보수 작업의 병렬 I/O +# 성능: 유지보수 작업 속도 향상 + +#io_max_combine_limit = 128kB +#io_combine_limit = 128kB +#io_method = worker +#io_max_concurrency = -1 +#io_workers = 3 + +# - Worker Processes - + +max_worker_processes = 8 +# 기본값: 8 +# 유지 이유: 4코어 환경에서 적절 (코어 수 × 2) +# 성능: 병렬 쿼리, autovacuum 등 다양한 백그라운드 작업 처리 + +max_parallel_workers_per_gather = 2 +# 기본값: 2 +# 변경값: 2 (4코어 환경에서 적절) +# 목적: 단일 쿼리가 사용할 수 있는 최대 병렬 worker 수 +# 성능: 대용량 테이블 스캔 시 쿼리 속도 향상 +# 참고: 너무 높으면 다른 쿼리의 리소스 부족 발생 가능 + +max_parallel_maintenance_workers = 2 +# 기본값: 2 +# 유지 이유: CREATE INDEX 등 유지보수 작업의 병렬화 +# 성능: 인덱스 생성 속도 향상 + +max_parallel_workers = 4 +# 기본값: 8 +# 변경값: 4 (CPU 코어 수) +# 목적: 시스템 전체에서 동시 실행 가능한 병렬 worker 총 수 +# 성능: CPU 코어 수에 맞춰 과도한 컨텍스트 스위칭 방지 + +#parallel_leader_participation = on + +#------------------------------------------------------------------------------ +# WRITE-AHEAD LOG +#------------------------------------------------------------------------------ + +# - Settings - + +#wal_level = replica +#fsync = on +#synchronous_commit = on +#wal_sync_method = fsync +#full_page_writes = on +#wal_log_hints = off + +wal_compression = lz4 +# 기본값: off +# 변경값: lz4 +# 목적: WAL 파일 압축으로 I/O 및 스토리지 사용량 감소 +# 성능: 네트워크를 통한 복제 시 대역폭 절약, 아카이빙 효율 향상 +# 참고: CPU 사용량은 약간 증가하지만 4코어 환경에서 무리 없음 + +#wal_init_zero = on +#wal_recycle = on + +wal_buffers = 16MB +# 기본값: -1 (shared_buffers의 3%, 최소 64kB, 최대 약 16MB) +# 변경값: 16MB +# 목적: WAL 데이터를 디스크에 쓰기 전 버퍼링 +# 성능: 쓰기 집약적 워크로드에서 WAL 쓰기 성능 향상 + +#wal_writer_delay = 200ms + +wal_writer_flush_after = 1MB +# 기본값: 1MB +# 유지 이유: SSD에서 적절한 flush 크기 + +#wal_skip_threshold = 2MB +#commit_delay = 0 +#commit_siblings = 5 + +# - Checkpoints - + +checkpoint_timeout = 15min +# 기본값: 5min +# 변경값: 15min +# 목적: 체크포인트 발생 간격 조정 +# 성능: 체크포인트 빈도 감소로 I/O spike 완화, 전체 성능 향상 +# 참고: 크래시 복구 시간은 약간 증가하지만 일반적으로 허용 가능 + +checkpoint_completion_target = 0.9 +# 기본값: 0.9 +# 유지 이유: 체크포인트를 시간에 걸쳐 분산하여 I/O spike 방지 +# 성능: 90%의 시간에 걸쳐 checkpoint 완료하여 부하 분산 + +#checkpoint_flush_after = 256kB +#checkpoint_warning = 30s + +max_wal_size = 2GB +# 기본값: 1GB +# 변경값: 2GB +# 목적: 체크포인트 간 생성 가능한 최대 WAL 크기 +# 성능: 쓰기 집약적 워크로드에서 체크포인트 빈도 감소 +# 참고: SSD 환경에서 더 큰 WAL 크기는 성능에 유리 + +min_wal_size = 1GB +# 기본값: 80MB +# 변경값: 1GB +# 목적: 항상 유지할 최소 WAL 크기 +# 성능: WAL 파일 재사용으로 파일 생성/삭제 오버헤드 감소 + +# - Prefetching during recovery - + +#recovery_prefetch = try +#wal_decode_buffer_size = 512kB + +# - Archiving - + +#archive_mode = off +#archive_library = '' +#archive_command = '' +#archive_timeout = 0 + +#------------------------------------------------------------------------------ +# REPLICATION +#------------------------------------------------------------------------------ + +# - Sending Servers - + +#max_wal_senders = 10 +#max_replication_slots = 10 +#wal_keep_size = 0 +#max_slot_wal_keep_size = -1 +#idle_replication_slot_timeout = 0 +#wal_sender_timeout = 60s +#track_commit_timestamp = off + +# - Primary Server - + +#synchronous_standby_names = '' +#synchronized_standby_slots = '' + +# - Standby Servers - + +#primary_conninfo = '' +#primary_slot_name = '' +#hot_standby = on +#max_standby_archive_delay = 30s +#max_standby_streaming_delay = 30s +#wal_receiver_create_temp_slot = off +#wal_receiver_status_interval = 10s +#hot_standby_feedback = off +#wal_receiver_timeout = 60s +#wal_retrieve_retry_interval = 5s +#recovery_min_apply_delay = 0 +#sync_replication_slots = off + +# - Subscribers - + +#max_active_replication_origins = 10 +#max_logical_replication_workers = 4 +#max_sync_workers_per_subscription = 2 +#max_parallel_apply_workers_per_subscription = 2 + +#------------------------------------------------------------------------------ +# QUERY TUNING +#------------------------------------------------------------------------------ + +# - Planner Method Configuration - + +#enable_async_append = on +#enable_bitmapscan = on +#enable_gathermerge = on +#enable_hashagg = on +#enable_hashjoin = on +#enable_incremental_sort = on +#enable_indexscan = on +#enable_indexonlyscan = on +#enable_material = on +#enable_memoize = on +#enable_mergejoin = on +#enable_nestloop = on +#enable_parallel_append = on +#enable_parallel_hash = on +#enable_partition_pruning = on +#enable_partitionwise_join = off +#enable_partitionwise_aggregate = off +#enable_presorted_aggregate = on +#enable_seqscan = on +#enable_sort = on +#enable_tidscan = on + +# - Planner Cost Constants - + +#seq_page_cost = 1.0 + +random_page_cost = 1.1 +# 기본값: 4.0 (HDD), 1.1 (SSD 자동 감지 시) +# 변경값: 1.1 +# 목적: SSD의 랜덤 액세스 특성을 반영 +# 성능: 인덱스 스캔 선호도 증가, 쿼리 플래너의 더 나은 결정 +# 참고: HDD는 4.0, SSD는 1.1-1.5가 적절 + +#cpu_tuple_cost = 0.01 +#cpu_index_tuple_cost = 0.005 +#cpu_operator_cost = 0.0025 +#parallel_setup_cost = 1000.0 +#parallel_tuple_cost = 0.1 +#min_parallel_table_scan_size = 8MB +#min_parallel_index_scan_size = 512kB + +effective_cache_size = 3GB +# 기본값: 4GB (시스템에 따라 다름) +# 변경값: 3GB (전체 RAM 4GB의 75%) +# 목적: OS와 PostgreSQL이 파일 캐싱에 사용 가능한 메모리 추정 +# 성능: 쿼리 플래너가 인덱스 스캔 비용을 더 정확히 계산 +# 참고: shared_buffers + OS 파일 캐시 = 약 3GB + +#jit_above_cost = 100000 +#jit_inline_above_cost = 500000 +#jit_optimize_above_cost = 500000 + +# - Genetic Query Optimizer - + +#geqo = on +#geqo_threshold = 12 + +# - Other Planner Options - + +default_statistics_target = 100 +# 기본값: 100 +# 유지 이유: 통계 정확도와 ANALYZE 시간의 균형 +# 성능: 쿼리 플래너의 정확한 비용 추정 +# 참고: 특정 컬럼에 대해 개별적으로 높일 수 있음 + +#constraint_exclusion = partition +#cursor_tuple_fraction = 0.1 +#from_collapse_limit = 8 +#jit = on +#join_collapse_limit = 8 +#plan_cache_mode = auto +#recursive_worktable_factor = 10.0 + +#------------------------------------------------------------------------------ +# REPORTING AND LOGGING +#------------------------------------------------------------------------------ + +# 로깅 설정은 기본값 유지 (사용자 요청사항) + +#log_destination = 'stderr' +#logging_collector = off +#log_directory = 'log' +#log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log' +#log_file_mode = 0600 +#log_rotation_age = 1d +#log_rotation_size = 10MB +#log_truncate_on_rotation = off +#syslog_facility = 'LOCAL0' +#syslog_ident = 'postgres' +#syslog_sequence_numbers = on +#syslog_split_messages = on +#event_source = 'PostgreSQL' +#log_min_messages = warning +#log_min_error_statement = error +#log_min_duration_statement = -1 +#log_min_duration_sample = -1 +#log_statement_sample_rate = 1.0 +#log_transaction_sample_rate = 0.0 +#log_startup_progress_interval = 10s +#debug_print_parse = off +#debug_print_rewritten = off +#debug_print_plan = off +#debug_pretty_print = on +#log_autovacuum_min_duration = 10min +#log_checkpoints = on +#log_connections = '' +#log_disconnections = off +#log_duration = off +#log_error_verbosity = default +#log_hostname = off +#log_line_prefix = '%m [%p] ' +#log_lock_waits = off +#log_lock_failures = off +#log_recovery_conflict_waits = off +#log_parameter_max_length = -1 +#log_parameter_max_length_on_error = 0 +#log_statement = 'none' +#log_replication_commands = off +#log_temp_files = -1 +log_timezone = 'Etc/UTC' +#cluster_name = '' +#update_process_title = on + +#------------------------------------------------------------------------------ +# STATISTICS +#------------------------------------------------------------------------------ + +#track_activities = on +#track_activity_query_size = 1024 +#track_counts = on +#track_cost_delay_timing = off + +track_io_timing = on +# 기본값: off +# 변경값: on +# 목적: I/O 작업의 시간 추적으로 성능 병목 지점 파악 +# 성능: EXPLAIN ANALYZE 등으로 I/O 병목 진단 가능 +# 참고: 약간의 오버헤드 있지만 성능 튜닝에 매우 유용 + +#track_wal_io_timing = off +#track_functions = none +#stats_fetch_consistency = cache + +# - Monitoring - + +#compute_query_id = auto +#log_statement_stats = off +#log_parser_stats = off +#log_planner_stats = off +#log_executor_stats = off + +#------------------------------------------------------------------------------ +# VACUUMING +#------------------------------------------------------------------------------ + +# - Automatic Vacuuming - + +#autovacuum = on + +autovacuum_worker_slots = 8 +# 기본값: 16 (PostgreSQL 18 신규 파라미터) +# 변경값: 8 +# 목적: autovacuum worker 슬롯 수 (동시 실행 가능한 worker 총량) +# 성능: 4코어 환경에서 적절한 슬롯 수로 CPU 리소스 균형 +# 참고: max_workers와 별개로 동적으로 worker 생성 가능 + +autovacuum_max_workers = 3 +# 기본값: 3 +# 변경값: 3 +# 목적: 동시에 실행 가능한 autovacuum worker 프로세스 수 +# 성능: 여러 테이블을 동시에 vacuum 처리 +# 참고: 4코어 환경에서 적절한 수준 + +autovacuum_naptime = 30s +# 기본값: 1min +# 변경값: 30s +# 목적: autovacuum이 데이터베이스를 체크하는 주기 +# 성능: 더 빈번한 체크로 테이블 bloat 감소, 성능 유지 +# 참고: 쓰기가 많은 환경에서 효과적 + +#autovacuum_vacuum_threshold = 50 +#autovacuum_vacuum_insert_threshold = 1000 +#autovacuum_analyze_threshold = 50 + +autovacuum_vacuum_scale_factor = 0.1 +# 기본값: 0.2 (테이블의 20%) +# 변경값: 0.1 (테이블의 10%) +# 목적: vacuum 실행 trigger 조건 (dead tuple 비율) +# 성능: 더 자주 vacuum 실행으로 테이블 bloat 최소화 +# 참고: 대형 테이블에서 특히 효과적 + +#autovacuum_vacuum_insert_scale_factor = 0.2 + +autovacuum_analyze_scale_factor = 0.05 +# 기본값: 0.1 (테이블의 10%) +# 변경값: 0.05 (테이블의 5%) +# 목적: analyze 실행 trigger 조건 +# 성능: 더 빈번한 통계 업데이트로 쿼리 플래너의 정확도 향상 + +#autovacuum_vacuum_max_threshold = 100000000 +#autovacuum_freeze_max_age = 200000000 +#autovacuum_multixact_freeze_max_age = 400000000 +#autovacuum_vacuum_cost_delay = 2ms +#autovacuum_vacuum_cost_limit = -1 + +# - Cost-Based Vacuum Delay - + +#vacuum_cost_delay = 0 +#vacuum_cost_page_hit = 1 +#vacuum_cost_page_miss = 2 +#vacuum_cost_page_dirty = 20 +#vacuum_cost_limit = 200 + +# - Default Behavior - + +#vacuum_truncate = on + +# - Freezing - + +#vacuum_freeze_table_age = 150000000 +#vacuum_freeze_min_age = 50000000 +#vacuum_failsafe_age = 1600000000 +#vacuum_multixact_freeze_table_age = 150000000 +#vacuum_multixact_freeze_min_age = 5000000 +#vacuum_multixact_failsafe_age = 1600000000 +#vacuum_max_eager_freeze_failure_rate = 0.03 + +#------------------------------------------------------------------------------ +# CLIENT CONNECTION DEFAULTS +#------------------------------------------------------------------------------ + +# - Statement Behavior - + +#client_min_messages = notice +#search_path = '"$user", public' +#row_security = on +#default_table_access_method = 'heap' +#default_tablespace = '' +#default_toast_compression = 'pglz' +#temp_tablespaces = '' +#check_function_bodies = on +#default_transaction_isolation = 'read committed' +#default_transaction_read_only = off +#default_transaction_deferrable = off +#session_replication_role = 'origin' + +statement_timeout = 30000 +# 기본값: 0 (무제한) +# 변경값: 30000ms (30초) +# 목적: 장시간 실행되는 쿼리 자동 종료 +# 성능: 문제있는 쿼리로 인한 리소스 점유 방지 +# 참고: 애플리케이션 특성에 따라 조정 필요, 0으로 비활성화 가능 + +#transaction_timeout = 0 + +lock_timeout = 5000 +# 기본값: 0 (무제한) +# 변경값: 5000ms (5초) +# 목적: 락 대기 시간 제한 +# 성능: 데드락 상황 빠른 감지, 애플리케이션 응답성 향상 + +#idle_in_transaction_session_timeout = 0 + +idle_session_timeout = 300000 +# 기본값: 0 (무제한) +# 변경값: 300000ms (5분) +# 목적: 유휴 세션 자동 종료 +# 성능: 불필요한 연결로 인한 리소스 낭비 방지 +# 참고: 연결 풀 사용 시 조정 필요 + +#bytea_output = 'hex' +#xmlbinary = 'base64' +#xmloption = 'content' +#gin_pending_list_limit = 4MB +#createrole_self_grant = '' +#event_triggers = on + +# - Locale and Formatting - + +datestyle = 'iso, mdy' +#intervalstyle = 'postgres' +timezone = 'Etc/UTC' +#timezone_abbreviations = 'Default' +#extra_float_digits = 1 +#client_encoding = sql_ascii + +lc_messages = 'en_US.utf8' +lc_monetary = 'en_US.utf8' +lc_numeric = 'en_US.utf8' +lc_time = 'en_US.utf8' +#icu_validation_level = warning + +default_text_search_config = 'pg_catalog.english' + +# - Shared Library Preloading - + +#local_preload_libraries = '' +#session_preload_libraries = '' +#shared_preload_libraries = '' +#jit_provider = 'llvmjit' + +# - Other Defaults - + +#dynamic_library_path = '$libdir' +#extension_control_path = '$system' +#gin_fuzzy_search_limit = 0 + +#------------------------------------------------------------------------------ +# LOCK MANAGEMENT +#------------------------------------------------------------------------------ + +deadlock_timeout = 1s +# 기본값: 1s +# 유지 이유: 데드락 감지를 위한 적절한 대기 시간 + +#max_locks_per_transaction = 64 +#max_pred_locks_per_transaction = 64 +#max_pred_locks_per_relation = -2 +#max_pred_locks_per_page = 2 + +#------------------------------------------------------------------------------ +# VERSION AND PLATFORM COMPATIBILITY +#------------------------------------------------------------------------------ + +#array_nulls = on +#backslash_quote = safe_encoding +#escape_string_warning = on +#lo_compat_privileges = off +#quote_all_identifiers = off +#standard_conforming_strings = on +#synchronize_seqscans = on +#transform_null_equals = off +#allow_alter_system = on + +#------------------------------------------------------------------------------ +# ERROR HANDLING +#------------------------------------------------------------------------------ + +#exit_on_error = off +#restart_after_crash = on +#data_sync_retry = off +#recovery_init_sync_method = fsync + +#------------------------------------------------------------------------------ +# CONFIG FILE INCLUDES +#------------------------------------------------------------------------------ + +#include_dir = '...' +#include_if_exists = '...' +#include = '...' + +#------------------------------------------------------------------------------ +# CUSTOMIZED OPTIONS +#------------------------------------------------------------------------------ + +# ============================================================================= +# 주요 변경사항 요약 +# ============================================================================= +# +# 1. 메모리 설정 (4GB RAM 기준) +# - shared_buffers: 128MB → 1GB (25% of RAM) +# - effective_cache_size: 4GB → 3GB (75% of RAM) +# - work_mem: 4MB → 16MB (쿼리 성능 향상) +# - maintenance_work_mem: 64MB → 256MB (유지보수 작업 가속) +# +# 2. 연결 관리 +# - tcp_keepalives 설정: 죽은 연결 빠른 감지 (90초 이내) +# - statement_timeout: 30초 (장시간 쿼리 방지) +# - lock_timeout: 5초 (락 대기 제한) +# - idle_session_timeout: 5분 (유휴 세션 정리) +# +# 3. 병렬 처리 (4코어 최적화) +# - max_parallel_workers: 4 (CPU 코어 수) +# - max_parallel_workers_per_gather: 2 +# - max_worker_processes: 8 +# +# 4. I/O 최적화 (SSD 특화) +# - random_page_cost: 4.0 → 1.1 +# - effective_io_concurrency: 1 → 200 +# - maintenance_io_concurrency: 10 → 200 +# +# 5. WAL 및 체크포인트 +# - wal_compression: off → lz4 (I/O 감소) +# - wal_buffers: 자동 → 16MB +# - checkpoint_timeout: 5min → 15min +# - max_wal_size: 1GB → 2GB +# - min_wal_size: 80MB → 1GB +# +# 6. Autovacuum 튜닝 +# - autovacuum_worker_slots: 16 → 8 +# - autovacuum_naptime: 1min → 30s (더 빈번한 체크) +# - autovacuum_vacuum_scale_factor: 0.2 → 0.1 (더 자주 실행) +# - autovacuum_analyze_scale_factor: 0.1 → 0.05 +# +# 7. 모니터링 +# - track_io_timing: off → on (I/O 성능 진단) +# +# ============================================================================= +# 예상 성능 향상 +# ============================================================================= +# +# - 읽기 성능: 30-50% 향상 (shared_buffers, effective_cache_size) +# - 쓰기 성능: 20-40% 향상 (WAL 설정, checkpoint 최적화) +# - 복잡한 쿼리: 40-100% 향상 (work_mem, 병렬 처리) +# - 유지보수 작업: 100-300% 향상 (maintenance_work_mem, I/O 동시성) +# - 전체 처리량: 25-50% 향상 (모든 최적화의 시너지) +# +# ============================================================================= +# 적용 방법 +# ============================================================================= +# +# 1. 이 파일을 postgresql.conf로 저장 (또는 기존 파일 백업 후 교체) +# 2. PostgreSQL 재시작: +# sudo systemctl restart postgresql +# 또는 +# sudo pg_ctl restart -D /var/lib/postgresql/data +# +# 3. 설정 확인: +# SHOW shared_buffers; +# SHOW effective_cache_size; +# SHOW work_mem; +# +# 4. 모니터링 (첫 며칠간): +# - 메모리 사용량: free -h, htop +# - 체크포인트 빈도: 로그 확인 +# - 쿼리 성능: pg_stat_statements 활용 +# +# ============================================================================= \ No newline at end of file diff --git a/log/postgresql/.gitkeep b/log/postgresql/.gitkeep new file mode 100644 index 0000000..e69de29