앞선 글 [OCI·Cloudflare를 이용한 WordPress CDN 구성]에서는 Cloudflare CDN 연동을 다뤘습니다.
이 글은 사례 환경의 WordPress 서버 구성과 성능 진단을 정리한 글입니다. Oracle Linux 8에서 기록한 설정을 바탕으로 점검 항목과 적용 조건을 설명합니다. 연결 끊김이나 응답 지연이 발생하면 웹 서버, PHP-FPM, 데이터베이스와 애플리케이션 로그를 같은 시각 기준으로 대조해야 합니다. 아래 예제는 현재 환경에서 재검증해야 하며, 특정 값이나 스크립트만으로 장애 해결이나 성능 향상을 보장하지 않습니다.
Contents
ToggleWordPress 서버 환경 분석과 성능 진단
설정부터 바꾸기보다 증상 발생 시각, 요청량, 응답 지연과 자원 사용량을 먼저 기록합니다. 변경 전 기준값이 있어야 어느 계층이 병목인지 좁히고 적용 결과를 비교할 수 있습니다.
시스템 구성 요소별 성능 지표 확인
PHP-FPM은 PHP 요청을 처리하는 프로세스를 관리합니다. 웹 서버가 받은 요청이 PHP 처리 구간에서 기다리는지 알아보려면 같은 시각의 두 기록을 대조해야 합니다.
아래 버전과 메모리 수치는 글 작성 당시의 환경 기록이며 현재 서버 상태나 최신 권장 버전을 뜻하지 않습니다. 적용 전 WordPress 요구사항, PHP 지원 수명과 각 패키지의 지원·호환성을 확인하세요. 단일 메모리 스냅샷만으로 I/O 최적화나 메모리 부족 부재를 판정할 수 없습니다.
글에 기록된 사례 환경은 다음과 같습니다:
기본 환경:
운영체제: Oracle Linux 8
웹 서버: Apache (httpd)
PHP 버전: 8.2.25
MySQL 버전: MySQL Enterprise - Cloud v9.1.1
WordPress 버전: 6.7.1
하드웨어 리소스:
총 물리적 메모리(RAM): 11GB
실제 사용 중인 메모리: 1GB
버퍼/캐시 사용 메모리: 7GB
실제 가용 메모리: 9GB
스왑 메모리: 7GB (미사용)
이러한 구성이 의미하는 바는:
- 측정 시점의 가용 메모리 기록이며 피크 부하에서의 여유를 보장하지 않습니다
- 버퍼/캐시에 상당한 메모리가 할당되어 I/O 상태는 별도 측정이 필요합니다
- 스왑 메모리가 사용되지 않아 측정 시점에는 스왑 사용이 없었지만 메모리 부족 여부는 별도 관찰해야 합니다
WordPress 서버 최적화에 영향을 미치는 설정값 분석
사례의 PHP·WordPress 설정:
PHP 메모리 한도: 256M
WordPress 메모리 한도: 40M
WordPress 최대 메모리 한도: 256M
PHP 최대 입력 변수: 1000
PHP 최대 POST 크기: 64M
이 기록에서 확인할 항목은 다음과 같습니다. 값의 차이만으로 병목이나 장애 원인을 확정하지는 않습니다.
PHP·WordPress 메모리 한도 점검
메모리 한도는 실제 사용량이나 시스템 메모리의 할당 비율과 구분해야 합니다:
- WordPress와 PHP의 설정값 비교:
- 시스템 메모리: 11GB
- WordPress 메모리 한도: 40M. 이 상수와 11GB RAM의 비율은 실제 메모리 사용률이 아닙니다.
- 웹 요청에 적용되는 실제 PHP 한도 확인:
- PHP 메모리 한도: 256M
- WordPress 메모리 한도: 40M. WordPress는 기존 PHP 한도가 더 높으면 이를 낮추지 않으므로, 실제 웹 요청의 유효 한도와 메모리 부족 오류를 함께 확인해야 합니다.
- WordPress와 PHP의 설정값 비교:
입력·업로드 한도 점검
저장 실패나 업로드 오류가 있을 때 요청 내용과 다음 한도를 대조합니다:
- 입력 변수 수:
- 현재 설정: max_input_vars = 1000
- max_input_vars는 GET·POST·COOKIE 입력 변수 수를 제한합니다. 전송 형식과 실제 변수 수를 먼저 확인해야 합니다.
- 폼 변수가 한도를 넘으면 일부 입력이 잘릴 수 있습니다. 모든 JSON 기반 저장 오류를 이 설정으로 설명할 수는 없습니다.
- POST 전체 크기:
- 현재 설정: post_max_size = 64M
- post_max_size는 POST 전체 크기의 한도입니다. upload_max_filesize와 multipart 부가 데이터, 웹 서버·프록시의 요청 크기 제한도 함께 확인하세요.
- 입력 변수 수:
WordPress 성능 튜닝을 위한 서버 설정
Apache의 동시 처리 한도, PHP-FPM 프로세스 수와 데이터베이스 대기열은 서로 영향을 줍니다. 한 계층의 한도를 높이기 전에는 전체 자원 예산부터 확인해야 합니다. 그다음 변경 항목을 구분해 제한된 부하에서 비교합니다.
설정 파일 백업
변경 전에는 실제 적용 중인 설정 파일과 포함 파일을 확인하고, 권한을 제한한 위치에 복사본을 보관합니다. 아래 스크립트는 일부 경로를 복사하는 예시이며 전체 설정을 빠짐없이 백업하거나 복원을 검증하는 도구는 아닙니다. 복사 실패·소유권·접근 권한과 복원 절차를 별도로 확인하세요.
#!/bin/bash # backup_configs.sh # 백업 디렉토리 생성 BACKUP_DIR="/root/config_backups/$(date +%Y%m%d_%H%M%S)" mkdir -p $BACKUP_DIR # Apache 설정 백업 cp -r /etc/httpd $BACKUP_DIR/ echo "Apache 설정 백업 완료" # PHP 설정 백업 cp /etc/php.ini $BACKUP_DIR/ cp -r /etc/php.d $BACKUP_DIR/ cp -r /etc/php-fpm.d $BACKUP_DIR/ echo "PHP 설정 백업 완료" # WordPress 설정 백업 cp /var/www/html/wordpress/wp-config.php $BACKUP_DIR/ echo "WordPress 설정 백업 완료"
Apache 웹 서버 성능 튜닝 방법
Apache에서는 요청 처리량, 대기 시간과 연결 상태를 확인해 병목을 판단합니다.
1. MPM 모듈 선택과 설정
Apache 2.4의 주요 Unix MPM에는 event·worker·prefork가 있습니다. 실제 패키지와 로드된 MPM, PHP 실행 방식을 확인하세요. 아래 event 설정은 예시이며 모든 환경에 적합한 권장값은 아닙니다:
# 환경별 측정이 필요한 예시 값입니다. 그대로 적용하지 마세요.
# /etc/httpd/conf.modules.d/00-mpm.conf
# Event MPM (권장)
<IfModule mpm_event_module>
StartServers 3
MinSpareThreads 25
MaxSpareThreads 75
ThreadLimit 64
ThreadsPerChild 25
MaxRequestWorkers 400
MaxConnectionsPerChild 0
</IfModule>
적용 조건: 아래 Apache/PHP 값은 이 글의 Oracle Linux 8, Apache 2.4, PHP 8.2.25 환경을 설명하는 예시이며 보편적인 권장값이 아닙니다. 최대 부하에서 PHP-FPM 프로세스의 RSS/PSS와 지연·대기열을 측정하고, OS·Apache·DB·캐시 및 안전 여유분을 제외한 메모리 예산으로 동시 처리 한도를 정하세요.
MaxRequestWorkers, ThreadsPerChild, ServerLimit의 관계와 FPM pm.max_children을 함께 검토해야 합니다.
memory_limit × 프로세스 수는 실제 예약 메모리가 아닙니다.
PHP의 php_admin_value[memory_limit] 제한은 WordPress의 WP_MAX_MEMORY_LIMIT 요청으로 높일 수 없습니다. 설정 백업과 구성 검사, 제한된 부하 시험을 통과한 값만 적용하고 메모리 부족·지연 증가 시 복원하세요.
각 설정값의 의미와 영향:
- StartServers: 시작 시 생성할 자식 프로세스 수. 부하와 선택한 MPM에 맞춰 검토
- ThreadsPerChild: 자식 프로세스당 스레드 수. ThreadLimit 및 전체 처리 한도와 함께 검토
- MaxRequestWorkers: 동시에 처리할 요청의 상한. MPM별 의미와 ServerLimit·ThreadsPerChild 관계를 확인
2. WordPress 가상 호스트 설정
# /etc/httpd/conf.d/wordpress.conf <VirtualHost *:80> ServerName datainhands.com ServerAlias www.datainhands.com DocumentRoot /var/www/html/wordpress # 로그 설정 LogLevel warn ErrorLog logs/datainhands.com-error.log CustomLog logs/datainhands.com-access.log combined # HTTPS 리다이렉션 RewriteEngine On RewriteCond %{HTTPS} off RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301] </VirtualHost> <VirtualHost *:443> ServerName datainhands.com ServerAlias www.datainhands.com DocumentRoot /var/www/html/wordpress # SSL 설정 SSLEngine on SSLCertificateFile /etc/letsencrypt/live/datainhands.com/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/datainhands.com/privkey.pem # SSL 보안 강화 SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1 SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256 SSLHonorCipherOrder off # WordPress 디렉토리 설정 <Directory /var/www/html/wordpress> Options Indexes FollowSymLinks MultiViews AllowOverride All Require all granted # 성능 최적화 EnableSendfile On FileETag None </Directory> </VirtualHost>
PHP-FPM 최적화로 WordPress 속도 개선
PHP-FPM에서는 프로세스별 메모리와 처리 시간, 대기열을 함께 확인합니다. 설정값을 늘리는 것만으로 성능이 좋아지는 것은 아닙니다.
1. PHP 기본 설정
# /etc/php.ini ; 메모리 설정 memory_limit = 512M max_execution_time = 300 max_input_time = 300 max_input_vars = 3000 ; 파일 업로드 설정 upload_max_filesize = 128M post_max_size = 128M max_file_uploads = 50 ; 세션 설정 session.gc_maxlifetime = 1440 session.gc_probability = 1 session.gc_divisor = 100 ; 오류 처리 (운영 환경) error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT display_errors = Off log_errors = On error_log = /var/log/php_errors.log
2. PHP-FPM 설정
# /etc/php.ini ; 메모리 설정 memory_limit = 512M max_execution_time = 300 max_input_time = 300 max_input_vars = 3000 ; 파일 업로드 설정 upload_max_filesize = 128M post_max_size = 128M max_file_uploads = 50 ; 세션 설정 session.gc_maxlifetime = 1440 session.gc_probability = 1 session.gc_divisor = 100 ; 오류 처리 (운영 환경) error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT display_errors = Off log_errors = On error_log = /var/log/php_errors.log
WordPress 메모리 설정 최적화
WordPress 상수는 요청 한도를 조정하는 항목과 캐시·예약 작업의 동작을 바꾸는 항목으로 나눠 확인합니다. WP_CACHE만으로 캐시가 활성화되는 것은 아니며, WP_MEMORY_LIMIT를 시스템 전체의 메모리 할당값으로 해석하면 안 됩니다.
적용 조건: 시스템 cron 또는 관리형 스케줄러가 이 사이트의 wp-cron.php를 주기적으로 호출하도록 먼저 구성하세요.
실제 설치 경로·사이트 URL·실행 계정·PHP 환경을 확인하고 예약 발행과 플러그인 예약 작업이 해당 스케줄러로 실행되는지 검증한 뒤에만 아래 주석을 해제합니다. 검증 전에는 방문 기반 WP-Cron을 유지하세요.
장애 시 이 상수를 제거하거나 false로 되돌리고 밀린 작업을 확인합니다.
# /var/www/html/wordpress/wp-config.php
// 메모리 설정
define('WP_MEMORY_LIMIT', '512M');
define('WP_MAX_MEMORY_LIMIT', '1024M');
// 성능 최적화
// 대체 스케줄러 구성·검증 후에만 활성화
// define('DISABLE_WP_CRON', true);
define('WP_CACHE', true);
define('EMPTY_TRASH_DAYS', 7);
define('WP_POST_REVISIONS', 5);
// 디버깅 설정 (운영 환경)
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);
WordPress 설정 변경과 서비스 재시작
설정 변경 전에는 백업, 구성 검사와 복원 절차를 준비합니다. 아래 예제는 PHP-FPM과 Apache를 재시작하므로 진행 중인 요청에 영향을 줄 수 있습니다. 구성 검사나 서비스 active 상태만으로 WordPress 정상 동작이 입증되지는 않습니다. 적용 후 실제 요청과 오류 로그를 확인하고, reload·graceful 사용 가능 여부도 환경별로 검토하세요.
WordPress 서비스 재시작 스크립트
#!/bin/bash # 서비스 재시작 스크립트 # 색상 정의 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # 로그 파일 설정 LOG_FILE="/var/log/service_restart.log" exec 1> >(tee -a "$LOG_FILE") 2>&1 echo "$(date): 서비스 재시작 시작" # 설정 파일 문법 검사 echo -e "${YELLOW}설정 파일 문법 검사 중...${NC}" httpd -t && php-fpm -t || exit 1 # 서비스 재시작 services=("php-fpm" "httpd") for service in "${services[@]}"; do echo -e "${YELLOW}${service} 재시작 중...${NC}" systemctl restart $service if systemctl is-active --quiet $service; then echo -e "${GREEN}${service} 재시작 성공${NC}" else echo -e "${RED}${service} 재시작 실패${NC}" exit 1 fi sleep 2 done # 로그 확인 echo -e "${YELLOW}에러 로그 확인 중...${NC}" tail -n 10 /var/log/httpd/error_log tail -n 10 /var/log/php-fpm/error.log echo "$(date): 서비스 재시작 완료"
WordPress 최적화 설정 적용 순서
- Apache 설정 변경:
# 설정 변경 sudo vi /etc/httpd/conf/httpd.conf sudo vi /etc/httpd/conf.d/wordpress.conf # 설정 검사 sudo httpd -t
- PHP 설정 변경:
# PHP 설정 변경 sudo vi /etc/php.ini sudo vi /etc/php-fpm.d/www.conf # 설정 검사 sudo php-fpm -t
- WordPress 설정 변경:
# wp-config.php 수정 sudo vi /var/www/html/wordpress/wp-config.php
- 서비스 재시작:
# 재시작 스크립트 실행 sudo ./restart_services.sh
SELinux를 활용한 WordPress 보안 설정 강화
SELinux는 접근 통제 정책입니다. 성능 문제를 해결한다는 이유로 보호 기능을 낮추지 마세요. 아래 예제의 wp-content 전체 쓰기 허용과 네트워크 접속 boolean은 범위가 넓으므로, 실제 쓰기 디렉터리와 연결 대상에 필요한 최소 권한을 검토한 뒤 사용해야 합니다. 현재 서버 정책의 검증 결과를 뜻하지 않습니다.
# WordPress 디렉토리 컨텍스트 설정 sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/html/wordpress(/.*)?" sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/wordpress/wp-content(/.*)?" sudo restorecon -Rv /var/www/html/wordpress # 추가 SELinux 설정 sudo setsebool -P httpd_can_network_connect on sudo setsebool -P httpd_can_network_connect_db on sudo setsebool -P httpd_unified on # SELinux 상태 확인 sestatus getsebool -a | grep httpd
WordPress 서버 모니터링과 유지보수
효율적인 시스템 모니터링 전략
WordPress 서버를 운영할 때는 자원 사용량과 서비스 상태를 함께 기록해야 합니다. 아래에서는 이 글에서 다루는 모니터링 항목과 도구 설정 예시를 정리합니다.
실시간 리소스 모니터링 도구 설정
아래는 자원 측정 함수의 예시입니다. 80·90% 경계는 환경별 기준을 정해야 하는 예시 값이며, 한 번의 used 비율이나 top 출력만으로 메모리 압박·전체 CPU 사용률을 판정하지 마세요. 출력 형식·로케일과 함수 호출을 확인하고, 인용부호를 포함한 Bash 문법 검증을 거친 뒤 별도 시험 환경에서 평가해야 합니다.
#!/bin/bash # monitor_system_resources.sh # 색상 정의 GREEN='\033[0;32m' YELLOW='\033[1;33m' RED='\033[0;31m' NC='\033[0m' # 메모리 모니터링 monitor_memory() { free -m | awk ' NR==2{ used=$3 total=$2 pct=used*100/total printf "메모리 사용량: %d/%dMB (%.1f%%)\n", used, total, pct if (pct > 90) { exit 1 } else if (pct > 80) { exit 2 } }' return $? } # CPU 모니터링 monitor_cpu() { cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d. -f1) echo "CPU 사용량: ${cpu_usage}%” if [ $cpu_usage -gt 90 ]; then return 1 elif [ $cpu_usage -gt 80 ]; then return 2 else return 0 fi } # 디스크 모니터링 monitor_disk() { disk_usage=$(df -h / | awk 'NR==2{print $5}' | cut -d% -f1) echo "디스크 사용량: ${disk_usage}%” if [ $disk_usage -gt 90 ]; then return 1 elif [ $disk_usage -gt 80 ]; then return 2 else return 0 fi }
주요 성능 지표 (KPI) 설정과 추적
아래 예제의 grep 기반 프로세스 수에는 grep 자체나 다른 일치 항목이 포함될 수 있습니다. curl의 time_total은 해당 HTTP 요청의 총 소요 시간이며 브라우저 페이지 로딩 시간은 아닙니다. CLI PHP의 memory_get_usage는 웹 요청이나 PHP-FPM 전체 사용량을 측정하지 않습니다. 실행 대상·인증·실제 지표 수집 방식을 별도로 확인하세요.
#!/bin/bash # monitor_wordpress_kpi.sh # WordPress 프로세스 모니터링 monitor_wordpress_processes() { echo "=== WordPress 프로세스 상태 ===" # PHP-FPM 프로세스 상태 php_proc=$(ps aux | grep php-fpm | wc -l) echo "PHP-FPM 프로세스 수: $php_proc" # Apache 프로세스 상태 apache_proc=$(ps aux | grep httpd | wc -l) echo "Apache 프로세스 수: $apache_proc" # MySQL 연결 상태 mysql_conn=$(mysqladmin status | awk '{print $4}') echo "MySQL 활성 연결 수: $mysql_conn" } # 성능 메트릭 수집 collect_performance_metrics() { echo "=== 성능 메트릭 ===" # 페이지 로드 시간 체크 curl -w "페이지 로드 시간: %{time_total}초\n" -o /dev/null -s your-domain.com # PHP 메모리 사용량 memory_usage=$(php -r "echo memory_get_usage(true);") echo "PHP 메모리 사용량: "$((memory_usage/1024/1024))"MB" }
모니터링 대시보드 구축
아래 예제는 CPU·메모리 상태를 비공개 HTML 보고서로 저장합니다. 연속 수집·인증된 웹 대시보드 기능을 구현한 예제는 아닙니다.
적용 조건: 이 예시는 웹 대시보드 대신 비공개 HTML 운영 보고서를 만듭니다.
PRIVATE_REPORT_DIR는 운영 계정 소유의 권한 0700 디렉터리로 미리 준비하고, 모든 DocumentRoot·Alias·정적 파일 공개 경로 밖인지 확인하세요. 생성 파일은 0600이며 로컬 또는 접근 통제된 운영 채널에서만 확인합니다. 원시 오류 로그는 포함하지 않습니다.
공개 대시보드가 필요하면 인증·접근 제한·민감정보 제거·출력 이스케이프를 별도로 설계해야 합니다.
#!/bin/bash
# dashboard_generator.sh — 비공개 보고서 전용
html_escape() {
sed -e 's/&/\&/g' -e 's/</\</g' -e 's/>/\>/g'
}
generate_dashboard() (
set -euo pipefail
umask 077
: "${PRIVATE_REPORT_DIR:?모든 웹 공개 경로 밖의 검증된 비공개 디렉터리를 지정하세요}"
test -d "$PRIVATE_REPORT_DIR"
REPORT_FILE=$(mktemp --suffix=.html "$PRIVATE_REPORT_DIR/status.XXXXXXXX")
{
printf '%s\n' '<!doctype html><html><head><meta charset="utf-8"><title>비공개 서버 상태</title></head><body><h1>비공개 서버 상태</h1><pre>'
LC_ALL=C uptime | html_escape
LC_ALL=C free -m | html_escape
printf '%s\n' '</pre></body></html>'
} > "$REPORT_FILE"
printf '비공개 보고서: %s\n' "$REPORT_FILE"
)
핵심 로그 분석과 관리
서버 로그의 효율적인 관리와 분석은 문제 해결과 성능 최적화의 핵심입니다.
중요 로그 파일 위치와 용도
주요 로그 파일들의 위치와 모니터링 방법:
# 로그 위치 설정 LOG_PATHS=( "/var/log/httpd/error_log" # Apache 에러 로그 "/var/log/httpd/access_log" # Apache 접근 로그 "/var/log/php-fpm/error.log" # PHP-FPM 에러 로그 "/var/log/php-fpm/www-slow.log" # PHP 느린 스크립트 로그 "/var/www/html/wordpress/wp-content/debug.log" # WordPress 디버그 로그 )
로그 로테이션과 보관 정책
로그 파일의 효율적인 관리를 위한 로테이션 설정:
# /etc/logrotate.d/wordpress /var/log/httpd/*log { daily rotate 14 compress delaycompress missingok notifempty create 640 apache apache sharedscripts postrotate /bin/systemctl reload httpd.service > /dev/null 2>/dev/null || true endscript }
로그 분석 자동화 스크립트
로그 파일을 자동으로 분석하고 중요 이벤트를 추출하는 스크립트:
#!/bin/bash # analyze_logs.sh # 오류 패턴 정의 ERROR_PATTERNS=( "PHP Fatal error" "ERROR" "failed" "Connection refused" "Permission denied" ) # 로그 분석 함수 analyze_logs() { local log_file=$1 echo "=== 분석: $log_file ===" for pattern in "${ERROR_PATTERNS[@]}"; do count=$(grep -c "$pattern" "$log_file") if [ $count -gt 0 ]; then echo "$pattern: $count회 발생" grep "$pattern" "$log_file" | tail -n 3 fi done }
체계적인 유지보수 프로세스
일일/주간/월간 점검 항목
정기적인 서버 점검을 위한 체크리스트와 자동화 스크립트:
#!/bin/bash # maintenance_checklist.sh # 일일 점검 daily_check() { # 서비스 상태 확인 for service in httpd php-fpm mysqld; do systemctl status $service done # 디스크 공간 확인 df -h du -sh /var/log/* } # 주간 점검 weekly_check() { # 데이터베이스 최적화 mysql -e "OPTIMIZE TABLE wp_posts, wp_postmeta, wp_options;" # 오래된 로그 파일 정리 find /var/log/httpd/ -name "*.log" -mtime +30 -delete } # 월간 점검 monthly_check() { # 데이터베이스 완전 분석 mysqlcheck -A --analyze # 시스템 업데이트 확인 yum check-update }
데이터베이스 최적화 일정
아래 예제는 데이터베이스의 작업 대상을 확인하는 용도입니다. 정기 최적화나 복구를 자동 실행하지 않으며, 진단 결과에 따라 필요한 작업을 별도로 검토합니다.
적용 조건: 일상 유지보수에서 binary log/GTID 이력을 초기화하지 않습니다. 기존 RESET MASTER는 MySQL 8.0에서 이력을 삭제하며 8.4에서 제거되었으므로 이 글의 9.1.1 안내에도 맞지 않습니다. 다른 RESET 문으로 대체하지 마세요. 로그 보존은 복제·PITR·검증된 백업 정책에 따라 별도로 설계합니다.
먼저 실제 DB와 테이블 접두사·엔진을 확인하세요.
REPAIR TABLE은 MyISAM/ARCHIVE/CSV용이며 InnoDB 복구 절차가 아닙니다. ANALYZE/OPTIMIZE도 백업과 잠금·부하 평가 후 별도 점검 시간에 검토합니다. 아래는 대상 확인용이며 글·댓글을 삭제하지 않습니다.
영구 삭제는 목록·보존기간·복원 가능한 백업과 담당자의 삭제 의사를 확인한 별도 작업으로 분리하세요.
#!/bin/bash
# optimize_database.sh — 대상 확인 전용
inspect_wordpress_db() {
# 확인한 WordPress 설치 경로에서 지정된 실행 계정으로 사용합니다.
# 설정된 테이블 접두사를 확인한 후 wp_posts를 맞춥니다.
wp db query "SHOW TABLE STATUS WHERE Name = 'wp_posts';" || return 1
wp post list --post_status=trash --fields=ID,post_title,post_date --format=table || return 1
wp comment list --status=spam --fields=comment_ID,comment_date --format=table
}
백업 및 복구 전략
데이터 안전성을 위한 백업 자동화 스크립트:
적용 조건: 아래는 백업 생성 단계의 예시이며 자동 삭제 기능은 없습니다. 경로·DB 이름·권한과 보호된 MySQL login-path를 먼저 구성·검증하고 비밀번호를 스크립트에 넣지 마세요.
single-transaction은 InnoDB에 한정되며 DDL과 파일 변경을 통제해 DB/파일 간 일관성을 확보해야 합니다. 명령 실패 시 즉시 중단하며 기존 정상 백업은 유지합니다. 비어 있지 않은 SQL과 읽을 수 있는 압축 파일만으로 복구 가능성을 보장할 수 없습니다.
새 백업을 격리 환경에서 복원하고 DB·파일·사이트 동작을 검증한 뒤에만 정상 백업으로 확정하세요.
보존기간(예: 30일)에 따른 정리는 그 검증이 성공하고 독립 사본과 최소 정상 백업 세트가 남는 경우에만 별도 검토합니다. 실패하거나 검증 전이면 기존 백업을 삭제하지 않습니다.
#!/bin/bash
# backup_wordpress.sh — 생성 단계; 보존기간 자동 삭제 없음
backup_wordpress() (
set -euo pipefail
umask 077
BACKUP_DIR="/backup/wordpress"
WP_DIR="/var/www/html/wordpress"
DB_NAME="wordpress"
DB_LOGIN_PATH="wordpress_backup"
mkdir -p -- "$BACKUP_DIR"
STAGING=$(mktemp -d "$BACKUP_DIR/.pending.XXXXXXXX")
mysqldump --login-path="$DB_LOGIN_PATH" --single-transaction \
--routines --events --triggers "$DB_NAME" > "$STAGING/db.sql"
test -s "$STAGING/db.sql"
tar -czf "$STAGING/files.tar.gz" -C "$WP_DIR" .
tar -tzf "$STAGING/files.tar.gz" > /dev/null
printf '생성 완료, 복원 검증 전: %s\n' "$STAGING"
# 기존 백업을 모두 유지합니다. 격리 복원 검증 후에만 보존기간 정리를 검토합니다.
)
WordPress 서버 문제 해결 가이드
연결 문제 진단과 해결
연결 오류는 DNS·네트워크·서비스 리스너·애플리케이션 응답을 구분해 조사합니다. 아래 함수 예제는 호출·출력 형식과 실제 대상 확인이 필요하며, 한 번의 ping이나 netstat 결과만으로 원인을 확정할 수는 없습니다.
연결 끊김 현상 진단 도구
#!/bin/bash # connection_diagnosis.sh # 색상 정의 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # 로그 파일 경로 설정 APACHE_ERROR_LOG="/var/log/httpd/error_log" PHP_ERROR_LOG="/var/log/php-fpm/error.log" SYSTEM_LOG="/var/log/messages" # 연결 상태 진단 함수 check_connections() { echo -e "${YELLOW}=== 현재 연결 상태 분석 ===${NC}" # 활성 연결 수 확인 active_connections=$(netstat -an | grep ESTABLISHED | wc -l) echo "활성 연결 수: $active_connections" # Apache 워커 상태 apache_workers=$(ps aux | grep httpd | wc -l) echo "Apache 워커 수: $apache_workers" # PHP-FPM 프로세스 상태 php_processes=$(ps aux | grep php-fpm | wc -l) echo "PHP-FPM 프로세스 수: $php_processes" } # 로그 분석 함수 analyze_logs() { echo -e "${YELLOW}=== 최근 오류 로그 분석 ===${NC}" echo "Apache 오류:" tail -n 20 $APACHE_ERROR_LOG | grep -i "error\|failed\|timeout" echo -e "\nPHP-FPM 오류:" tail -n 20 $PHP_ERROR_LOG | grep -i "error\|failed\|timeout" echo -e "\n시스템 메시지:" tail -n 20 $SYSTEM_LOG | grep -i "error\|failed\|oom" }
성능 저하 분석과 대응
적용 조건: defunct는 실행 파일 이름이 아니라 종료 후 부모가 아직 회수하지 않은 좀비 상태입니다. 아래 PID/PPID/STAT 진단 결과에서 부모 프로세스를 식별하고 wait/waitpid 처리와 서비스 로그를 조사하세요. 좀비에 SIGKILL을 보내도 회수되지 않습니다.
부모 서비스 재시작은 영향·복구 절차를 검토한 뒤 필요한 경우에만 수행하며, 이 진단 자체가 일괄 재시작을 요구하지 않습니다.
#!/bin/bash
# performance_troubleshoot.sh
# 성능 지표 수집 함수
collect_performance_metrics() {
echo "=== 시스템 성능 지표 ==="
# CPU 사용량
echo "CPU 사용률:"
top -bn1 | grep "Cpu(s)" | awk '{print $2}'
# 메모리 사용량
echo -e "\n메모리 사용량:"
free -m
# 디스크 I/O
echo -e "\n디스크 I/O 상태:"
iostat -x 1 3
# MySQL 상태
echo -e "\nMySQL 상태:"
mysqladmin status
}
# 즉각적인 성능 개선 조치
improve_performance() {
echo "=== 성능 개선 조치 실행 ==="
# 캐시 초기화
echo "PHP OPCache 초기화..."
php -r 'opcache_reset();'
# WordPress 캐시 정리
echo "WordPress 캐시 정리..."
wp cache flush
# 좀비 상태 진단 (읽기 전용)
echo "좀비 상태와 부모 PID 확인..."
ps -eo pid,ppid,stat,comm | awk 'NR == 1 || $3 ~ /^Z/'
# 부모 서비스 조치는 영향 검토 후 별도로 결정합니다.
}
자동 복구 예제의 적용 한계
#!/bin/bash # auto_recovery.sh # 임계값 설정 MAX_LOAD=10 MAX_MEMORY_USAGE=90 MAX_CONNECTIONS=200 # 시스템 상태 체크 함수 check_system_health() { # 로드 애버리지 확인 load_average=$(uptime | awk '{print $(NF-2)}' | cut -d. -f1) # 메모리 사용률 확인 memory_usage=$(free | grep Mem | awk '{print $3/$2 * 100.0}') # 연결 수 확인 connections=$(netstat -an | grep ESTABLISHED | wc -l) # 상태 평가 및 조치 if [ $load_average -gt $MAX_LOAD ] || [ ${memory_usage%.*} -gt $MAX_MEMORY_USAGE ] || [ $connections -gt $MAX_CONNECTIONS ]; then return 1 fi return 0 } # 복구 프로세스 execute_recovery() { echo "$(date): 복구 프로세스 시작" # 캐시 초기화 php -r 'opcache_reset();' wp cache flush # 서비스 재시작 systemctl restart php-fpm systemctl restart httpd # 이메일 알림 mail -s "WordPress 서버 자동 복구 실행" admin@example.com << EOF 서버 자동 복구가 실행되었습니다. 시간: $(date) 조치: 캐시 초기화 및 서비스 재시작 현재 상태: $(collect_performance_metrics) EOF }
결론과 주요 가이드라인
효율적인 문제 해결을 위한 체크리스트
- 사전 준비
- 모든 설정 파일 백업
- 성능 기준치(베이스라인) 문서화
- 긴급 연락망 준비
- 문제 해결 프로세스
- 증상 정확히 파악
- 로그 분석으로 근본 원인 파악
- 단계적 해결 방안 적용
- 변경 사항 문서화
- 사후 관리
- 해결 과정 문서화
- 재발 방지 대책 수립
- 모니터링 시스템 개선
지속적인 개선을 위한 권장사항
- 정기적인 성능 테스트 실시
- 보안 업데이트 적용 계획 수립
- 백업 및 복구 절차 정기 점검
- 팀원 교육 및 기술 문서 최신화
기준값과 변경 이력을 남기고 같은 부하에서 결과를 비교해야 개선 여부를 판단할 수 있습니다. 아래 자동 복구 예제는 앞서 정의한 함수와 실행 흐름을 별도로 연결해야 하며, 임계값을 넘었다는 이유만으로 서비스를 재시작해서는 안 됩니다. CLI의 OPcache 초기화가 PHP-FPM 캐시를 초기화한다고 가정하지 마세요.
반복 재시작 방지, 중단 기준과 조치 후 서비스 검증을 설계하기 전에는 운영 자동 복구로 사용하지 않습니다.
