8.2 運用管理

安定した監視環境を維持するためのZabbix運用管理の包括的手法とベストプラクティス

概要

Zabbix運用管理は、監視システムの継続的な安定性・可用性・性能を確保するための体系的な管理活動です。適切な運用管理により、障害の未然防止、迅速な問題解決、そして監視品質の継続的向上を実現できます。

運用管理の重要性

要素影響管理効果
日常運用サービス品質・稼働率安定運用・早期発見
バックアップデータ保護・事業継続災害対策・復旧保証
アップグレードセキュリティ・機能向上最新化・脆弱性対策
ログ管理問題分析・コンプライアンス証跡保持・分析精度
容量管理性能・拡張性適切な成長・投資計画

日常運用タスク

定期監視項目

システムヘルスチェック

yaml
# 日次チェックリスト
日次チェック:
  Zabbixサーバー:
    - [ ] プロセス稼働状況確認
    - [ ] CPU使用率 (<80%)
    - [ ] メモリ使用率 (<85%)
    - [ ] ディスク使用率 (<90%)
    - [ ] データベース接続数 (<max_connections * 0.8)
    - [ ] キュー状況確認
    
  データベース:
    - [ ] レプリケーション状況
    - [ ] ログファイル容量
    - [ ] スロークエリ確認
    - [ ] テーブルロック状況
    - [ ] バックアップ成功確認
    
  ネットワーク:
    - [ ] エージェント接続性
    - [ ] ネットワーク遅延 (<100ms)
    - [ ] パケットロス率 (<0.1%)
    - [ ] 帯域使用率 (<70%)
    
  アプリケーション:
    - [ ] Webインターフェース応答
    - [ ] API応答時間 (<2秒)
    - [ ] ログエラー確認
    - [ ] セッション数監視

# 週次チェックリスト  
週次チェック:
  パフォーマンス:
    - [ ] トレンド分析レポート確認
    - [ ] 容量使用率推移確認
    - [ ] アラート頻度分析
    - [ ] レスポンス時間分析
    
  データ品質:
    - [ ] データ欠損確認
    - [ ] 異常値検出
    - [ ] 監視対象稼働率確認
    - [ ] SLA達成率確認
    
  セキュリティ:
    - [ ] 不正アクセス試行確認
    - [ ] ユーザーアクティビティ確認
    - [ ] 脆弱性スキャン結果確認
    - [ ] セキュリティパッチ状況確認

# 月次チェックリスト
月次チェック:
  容量計画:
    - [ ] ストレージ使用量予測
    - [ ] データ保持期間の見直し
    - [ ] アーカイブ戦略確認
    - [ ] 性能限界分析
    
  運用効率:
    - [ ] 監視ルール最適化
    - [ ] アラート精度確認
    - [ ] ダッシュボード活用状況
    - [ ] 自動化余地の検討
    
  災害対策:
    - [ ] バックアップ復旧テスト
    - [ ] BCP訓練実施
    - [ ] 冗長化状況確認
    - [ ] RTO/RPO確認

自動化運用スクリプト

bash
#!/bin/bash
# Zabbix日常運用自動チェックスクリプト

SCRIPT_DIR="/opt/zabbix/scripts"
LOG_DIR="/var/log/zabbix/operations"
CONFIG_FILE="/etc/zabbix/operations.conf"
REPORT_FILE="$LOG_DIR/daily_report_$(date +%Y%m%d).txt"

# 設定読み込み
source "$CONFIG_FILE"

# ログ出力関数
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$REPORT_FILE"
}

# Zabbixサーバーステータス確認
check_zabbix_server() {
    log_message "=== Zabbix Server Status Check ==="
    
    # プロセス確認
    if pgrep -f zabbix_server > /dev/null; then
        log_message "✓ Zabbix server process is running"
    else
        log_message "✗ Zabbix server process is not running"
        return 1
    fi
    
    # ポート確認
    if netstat -ln | grep -q ":10051.*LISTEN"; then
        log_message "✓ Zabbix server port 10051 is listening"
    else
        log_message "✗ Zabbix server port 10051 is not listening"
        return 1
    fi
    
    # 設定ファイル確認
    if zabbix_server -t; then
        log_message "✓ Zabbix server configuration is valid"
    else
        log_message "✗ Zabbix server configuration has errors"
        return 1
    fi
    
    return 0
}

# データベース状況確認
check_database() {
    log_message "=== Database Status Check ==="
    
    # 接続確認
    if mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;" "$DB_NAME" &>/dev/null; then
        log_message "✓ Database connection successful"
    else
        log_message "✗ Database connection failed"
        return 1
    fi
    
    # データベースサイズ確認
    DB_SIZE=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS 'DB Size MB'
        FROM information_schema.tables 
        WHERE table_schema='$DB_NAME';" -s -N)
    
    log_message "Database size: ${DB_SIZE} MB"
    
    # テーブルサイズ確認(上位5つ)
    log_message "Largest tables:"
    mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT table_name, 
               ROUND(((data_length + index_length) / 1024 / 1024), 2) AS 'Size MB'
        FROM information_schema.TABLES 
        WHERE table_schema = '$DB_NAME'
        ORDER BY (data_length + index_length) DESC 
        LIMIT 5;" | while read line; do
        log_message "  $line"
    done
    
    # 接続数確認
    CONNECTIONS=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "SHOW STATUS LIKE 'Threads_connected';" -s -N | awk '{print $2}')
    MAX_CONNECTIONS=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "SHOW VARIABLES LIKE 'max_connections';" -s -N | awk '{print $2}')
    CONNECTION_USAGE=$(echo "scale=2; $CONNECTIONS * 100 / $MAX_CONNECTIONS" | bc)
    
    log_message "Database connections: $CONNECTIONS/$MAX_CONNECTIONS (${CONNECTION_USAGE}%)"
    
    if (( $(echo "$CONNECTION_USAGE > 80" | bc -l) )); then
        log_message "⚠ High connection usage detected"
    fi
    
    return 0
}

# 監視対象ヘルス確認
check_monitored_hosts() {
    log_message "=== Monitored Hosts Health Check ==="
    
    # エージェント接続確認
    AGENT_COUNT=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT COUNT(*) FROM hosts h
        JOIN interface i ON h.hostid = i.hostid
        WHERE h.status = 0 AND i.available = 1 AND i.type = 1;" -s -N "$DB_NAME")
    
    TOTAL_AGENT_COUNT=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT COUNT(*) FROM hosts h
        JOIN interface i ON h.hostid = i.hostid
        WHERE h.status = 0 AND i.type = 1;" -s -N "$DB_NAME")
    
    AGENT_AVAILABILITY=$(echo "scale=2; $AGENT_COUNT * 100 / $TOTAL_AGENT_COUNT" | bc)
    log_message "Agent availability: $AGENT_COUNT/$TOTAL_AGENT_COUNT (${AGENT_AVAILABILITY}%)"
    
    # 問題ホスト一覧
    log_message "Hosts with problems:"
    mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT h.host, p.name, p.severity, FROM_UNIXTIME(p.clock) as problem_time
        FROM hosts h
        JOIN problem p ON h.hostid = p.objectid
        WHERE p.source = 0 AND p.object = 0
        ORDER BY p.severity DESC, p.clock DESC
        LIMIT 10;" "$DB_NAME" | while read line; do
        log_message "  $line"
    done
    
    return 0
}

# システムリソース確認
check_system_resources() {
    log_message "=== System Resources Check ==="
    
    # CPU使用率
    CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
    log_message "CPU usage: ${CPU_USAGE}%"
    
    if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then
        log_message "⚠ High CPU usage detected"
    fi
    
    # メモリ使用率
    MEMORY_INFO=$(free | grep Mem)
    TOTAL_MEM=$(echo $MEMORY_INFO | awk '{print $2}')
    USED_MEM=$(echo $MEMORY_INFO | awk '{print $3}')
    MEMORY_USAGE=$(echo "scale=2; $USED_MEM * 100 / $TOTAL_MEM" | bc)
    
    log_message "Memory usage: ${MEMORY_USAGE}%"
    
    if (( $(echo "$MEMORY_USAGE > 85" | bc -l) )); then
        log_message "⚠ High memory usage detected"
    fi
    
    # ディスク使用率
    log_message "Disk usage:"
    df -h | grep -E '^/dev/' | while read line; do
        USAGE=$(echo $line | awk '{print $5}' | sed 's/%//')
        MOUNT=$(echo $line | awk '{print $6}')
        log_message "  $MOUNT: ${USAGE}%"
        
        if [ "$USAGE" -gt 90 ]; then
            log_message "  ⚠ High disk usage on $MOUNT"
        fi
    done
    
    return 0
}

# Zabbix内部メトリクス確認
check_zabbix_internals() {
    log_message "=== Zabbix Internal Metrics ==="
    
    # キュー状況確認
    QUEUE_INFO=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT 
            SUM(CASE WHEN i.type = 0 THEN 1 ELSE 0 END) as 'Zabbix agent items',
            SUM(CASE WHEN i.type = 7 THEN 1 ELSE 0 END) as 'Zabbix agent active items',
            SUM(CASE WHEN i.type = 4 THEN 1 ELSE 0 END) as 'SNMP items',
            COUNT(*) as 'Total items'
        FROM items i
        JOIN hosts h ON i.hostid = h.hostid
        WHERE i.status = 0 AND h.status = 0;" -s -N "$DB_NAME")
    
    log_message "Item counts: $QUEUE_INFO"
    
    # 値更新状況
    LATEST_DATA=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT 
            COUNT(*) as items_updated_last_hour
        FROM items i
        JOIN hosts h ON i.hostid = h.hostid
        WHERE i.status = 0 AND h.status = 0 
        AND i.lastvalue_ts > UNIX_TIMESTAMP() - 3600;" -s -N "$DB_NAME")
    
    log_message "Items updated in last hour: $LATEST_DATA"
    
    # トリガー状況
    TRIGGER_INFO=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT 
            COUNT(CASE WHEN value = 1 THEN 1 END) as 'Problem triggers',
            COUNT(CASE WHEN value = 0 THEN 1 END) as 'OK triggers',
            COUNT(*) as 'Total enabled triggers'
        FROM triggers t
        JOIN hosts h ON t.hostid = h.hostid
        WHERE t.status = 0 AND h.status = 0;" -s -N "$DB_NAME")
    
    log_message "Trigger status: $TRIGGER_INFO"
    
    return 0
}

# アラート統計
generate_alert_statistics() {
    log_message "=== Alert Statistics (Last 24h) ==="
    
    # 深刻度別問題数
    mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT 
            CASE severity
                WHEN 0 THEN 'Not classified'
                WHEN 1 THEN 'Information'
                WHEN 2 THEN 'Warning'
                WHEN 3 THEN 'Average'
                WHEN 4 THEN 'High'
                WHEN 5 THEN 'Disaster'
            END as 'Severity',
            COUNT(*) as 'Count'
        FROM problem
        WHERE clock > UNIX_TIMESTAMP() - 86400
        GROUP BY severity
        ORDER BY severity DESC;" "$DB_NAME" | while read line; do
        log_message "  $line"
    done
    
    # 上位問題ホスト
    log_message "Top 5 hosts with most problems (Last 24h):"
    mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT h.host, COUNT(*) as problem_count
        FROM problem p
        JOIN hosts h ON p.objectid = h.hostid
        WHERE p.clock > UNIX_TIMESTAMP() - 86400
        AND p.source = 0 AND p.object = 0
        GROUP BY h.hostid, h.host
        ORDER BY problem_count DESC
        LIMIT 5;" "$DB_NAME" | while read line; do
        log_message "  $line"
    done
}

# 総合評価
generate_summary() {
    log_message "=== Daily Operation Summary ==="
    
    # 全体的な健康度スコア計算
    local score=100
    local issues=0
    
    # システムリソースチェック
    CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
    if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then
        score=$((score - 20))
        issues=$((issues + 1))
    fi
    
    # メモリ使用率チェック
    MEMORY_INFO=$(free | grep Mem)
    TOTAL_MEM=$(echo $MEMORY_INFO | awk '{print $2}')
    USED_MEM=$(echo $MEMORY_INFO | awk '{print $3}')
    MEMORY_USAGE=$(echo "scale=2; $USED_MEM * 100 / $TOTAL_MEM" | bc)
    
    if (( $(echo "$MEMORY_USAGE > 85" | bc -l) )); then
        score=$((score - 15))
        issues=$((issues + 1))
    fi
    
    # 問題数チェック
    PROBLEM_COUNT=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT COUNT(*) FROM problem 
        WHERE source = 0 AND object = 0;" -s -N "$DB_NAME")
    
    if [ "$PROBLEM_COUNT" -gt 10 ]; then
        score=$((score - 20))
        issues=$((issues + 1))
    elif [ "$PROBLEM_COUNT" -gt 5 ]; then
        score=$((score - 10))
        issues=$((issues + 1))
    fi
    
    # 健康度判定
    if [ "$score" -ge 90 ]; then
        status="EXCELLENT"
        emoji="🟢"
    elif [ "$score" -ge 70 ]; then
        status="GOOD"
        emoji="🟡"
    elif [ "$score" -ge 50 ]; then
        status="WARNING"
        emoji="🟠"
    else
        status="CRITICAL"
        emoji="🔴"
    fi
    
    log_message "$emoji Overall Health Score: $score/100 ($status)"
    log_message "Issues detected: $issues"
    
    # 推奨アクション
    if [ "$issues" -gt 0 ]; then
        log_message "Recommended actions:"
        if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then
            log_message "  - Investigate high CPU usage"
        fi
        if (( $(echo "$MEMORY_USAGE > 85" | bc -l) )); then
            log_message "  - Investigate high memory usage"
        fi
        if [ "$PROBLEM_COUNT" -gt 5 ]; then
            log_message "  - Review and resolve active problems"
        fi
    fi
}

# 通知送信
send_notification() {
    local status="$1"
    local score="$2"
    
    # Slack通知
    if [ -n "$SLACK_WEBHOOK_URL" ]; then
        curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"📊 Zabbix Daily Health Report\\nScore: $score/100 ($status)\\nDetailed report: $REPORT_FILE\"}" \
            "$SLACK_WEBHOOK_URL"
    fi
    
    # メール通知(重要な問題がある場合のみ)
    if [ "$score" -lt 70 ] && [ -n "$ADMIN_EMAIL" ]; then
        mail -s "Zabbix Health Alert: $status ($score/100)" "$ADMIN_EMAIL" < "$REPORT_FILE"
    fi
}

# メイン実行
main() {
    # ログディレクトリ作成
    mkdir -p "$LOG_DIR"
    
    log_message "Starting Zabbix daily operations check..."
    
    # 各チェック実行
    check_zabbix_server
    check_database
    check_monitored_hosts
    check_system_resources
    check_zabbix_internals
    generate_alert_statistics
    
    # 総合評価
    generate_summary
    
    # 通知送信
    CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | sed 's/%us,//')
    MEMORY_INFO=$(free | grep Mem)
    TOTAL_MEM=$(echo $MEMORY_INFO | awk '{print $2}')
    USED_MEM=$(echo $MEMORY_INFO | awk '{print $3}')
    MEMORY_USAGE=$(echo "scale=2; $USED_MEM * 100 / $TOTAL_MEM" | bc)
    PROBLEM_COUNT=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT COUNT(*) FROM problem 
        WHERE source = 0 AND object = 0;" -s -N "$DB_NAME")
    
    # スコア再計算(通知用)
    score=100
    if (( $(echo "$CPU_USAGE > 80" | bc -l) )); then score=$((score - 20)); fi
    if (( $(echo "$MEMORY_USAGE > 85" | bc -l) )); then score=$((score - 15)); fi
    if [ "$PROBLEM_COUNT" -gt 10 ]; then score=$((score - 20)); fi
    
    if [ "$score" -ge 90 ]; then
        status="EXCELLENT"
    elif [ "$score" -ge 70 ]; then
        status="GOOD"
    elif [ "$score" -ge 50 ]; then
        status="WARNING"
    else
        status="CRITICAL"
    fi
    
    send_notification "$status" "$score"
    
    log_message "Daily operations check completed"
}

# スクリプト実行
main "$@"

バックアップ管理

包括的バックアップ戦略

バックアップ設計

yaml
# バックアップ戦略設計
バックアップ分類:
  設定バックアップ:
    対象:
      - Zabbix設定ファイル
      - SSL証明書
      - カスタムスクリプト
      - テンプレート定義
    頻度: "日次"
    保持期間: "30日"
    
  データベース完全バックアップ:
    対象:
      - 全データベース内容
      - スキーマとデータ
      - ストアドプロシージャ
      - インデックス定義
    頻度: "週次"
    保持期間: "12週間"
    
  データベース増分バックアップ:
    対象:
      - バイナリログ
      - 変更データのみ
      - トランザクションログ
    頻度: "15分間隔"
    保持期間: "7日"
    
  監視データバックアップ:
    対象:
      - 履歴データ
      - トレンドデータ
      - イベント履歴
    頻度: "日次"
    保持期間: "3ヶ月"
    
  システムイメージバックアップ:
    対象:
      - OS全体
      - アプリケーション
      - 設定込み完全環境
    頻度: "月次"
    保持期間: "6ヶ月"

# 3-2-1バックアップルール
3-2-1原則:
  コピー数: "3つのコピー"
  保存媒体: "2つの異なる媒体"
  オフサイト: "1つは異なる場所"
  
  実装例:
    1次: "ローカルストレージ(高速アクセス)"
    2次: "ネットワークストレージ(冗長化)"
    3次: "クラウドストレージ(オフサイト)"

自動バックアップシステム

bash
#!/bin/bash
# Zabbix包括的バックアップシステム

BACKUP_CONFIG="/etc/zabbix/backup.conf"
LOG_FILE="/var/log/zabbix/backup.log"
NOTIFICATION_CONFIG="/etc/zabbix/notifications.conf"

# 設定読み込み
source "$BACKUP_CONFIG"
source "$NOTIFICATION_CONFIG"

# ログ関数
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 通知関数
send_notification() {
    local status="$1"
    local message="$2"
    local severity="$3"
    
    # Slack通知
    if [ -n "$SLACK_WEBHOOK_URL" ]; then
        local emoji
        case "$severity" in
            "success") emoji="✅" ;;
            "warning") emoji="⚠️" ;;
            "error") emoji="❌" ;;
            *) emoji="ℹ️" ;;
        esac
        
        curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"$emoji Zabbix Backup Report\\nStatus: $status\\n$message\"}" \
            "$SLACK_WEBHOOK_URL"
    fi
    
    # メール通知(エラー時のみ)
    if [ "$severity" = "error" ] && [ -n "$ADMIN_EMAIL" ]; then
        echo "$message" | mail -s "Zabbix Backup Error: $status" "$ADMIN_EMAIL"
    fi
}

# ディスク容量確認
check_disk_space() {
    local backup_dir="$1"
    local required_space="$2"  # GB単位
    
    local available_space=$(df "$backup_dir" | awk 'NR==2 {print int($4/1024/1024)}')
    
    if [ "$available_space" -lt "$required_space" ]; then
        log_message "ERROR: Insufficient disk space. Required: ${required_space}GB, Available: ${available_space}GB"
        return 1
    fi
    
    log_message "Disk space check passed: ${available_space}GB available"
    return 0
}

# 設定ファイルバックアップ
backup_configuration() {
    log_message "Starting configuration backup..."
    
    local config_backup_dir="$BACKUP_DIR/config/$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$config_backup_dir"
    
    # Zabbix設定
    if [ -d /etc/zabbix ]; then
        tar -czf "$config_backup_dir/zabbix_config.tar.gz" /etc/zabbix/
        log_message "Zabbix configuration backed up"
    fi
    
    # Apache/Nginx設定
    if [ -d /etc/apache2 ]; then
        tar -czf "$config_backup_dir/apache_config.tar.gz" /etc/apache2/
        log_message "Apache configuration backed up"
    fi
    
    if [ -d /etc/nginx ]; then
        tar -czf "$config_backup_dir/nginx_config.tar.gz" /etc/nginx/
        log_message "Nginx configuration backed up"
    fi
    
    # SSL証明書
    if [ -d /etc/ssl ]; then
        tar -czf "$config_backup_dir/ssl_certs.tar.gz" /etc/ssl/
        log_message "SSL certificates backed up"
    fi
    
    # カスタムスクリプト
    if [ -d /opt/zabbix ]; then
        tar -czf "$config_backup_dir/custom_scripts.tar.gz" /opt/zabbix/
        log_message "Custom scripts backed up"
    fi
    
    # メタデータファイル作成
    cat > "$config_backup_dir/backup_metadata.txt" << EOF
Backup Type: Configuration
Backup Date: $(date)
Hostname: $(hostname)
Zabbix Version: $(zabbix_server --version | head -1)
Database Type: $DB_TYPE
Backup Size: $(du -sh "$config_backup_dir" | cut -f1)
EOF
    
    log_message "Configuration backup completed: $config_backup_dir"
    return 0
}

# データベース完全バックアップ
backup_database_full() {
    log_message "Starting full database backup..."
    
    local db_backup_dir="$BACKUP_DIR/database/full/$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$db_backup_dir"
    
    # 容量確認
    local db_size=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT ROUND(SUM(data_length + index_length) / 1024 / 1024 / 1024, 2) 
        FROM information_schema.tables 
        WHERE table_schema='$DB_NAME';" -s -N)
    
    local required_space=$(echo "$db_size * 1.5" | bc | cut -d. -f1)
    required_space=${required_space:-5}  # デフォルト5GB
    
    if ! check_disk_space "$BACKUP_DIR" "$required_space"; then
        return 1
    fi
    
    # MySQL完全バックアップ
    if [ "$DB_TYPE" = "mysql" ]; then
        log_message "Creating MySQL full backup..."
        
        mysqldump \
            --user="$DB_USER" \
            --password="$DB_PASSWORD" \
            --host="$DB_HOST" \
            --port="$DB_PORT" \
            --single-transaction \
            --routines \
            --triggers \
            --events \
            --hex-blob \
            --complete-insert \
            --add-drop-table \
            --add-locks \
            --create-options \
            --disable-keys \
            --extended-insert \
            --quick \
            --lock-tables=false \
            "$DB_NAME" | gzip > "$db_backup_dir/zabbix_full_backup.sql.gz"
        
        if [ ${PIPESTATUS[0]} -eq 0 ]; then
            log_message "MySQL full backup completed successfully"
        else
            log_message "ERROR: MySQL full backup failed"
            return 1
        fi
    fi
    
    # PostgreSQL完全バックアップ
    if [ "$DB_TYPE" = "postgresql" ]; then
        log_message "Creating PostgreSQL full backup..."
        
        PGPASSWORD="$DB_PASSWORD" pg_dump \
            --host="$DB_HOST" \
            --port="$DB_PORT" \
            --username="$DB_USER" \
            --dbname="$DB_NAME" \
            --no-password \
            --format=custom \
            --compress=9 \
            --verbose \
            --file="$db_backup_dir/zabbix_full_backup.dump"
        
        if [ $? -eq 0 ]; then
            log_message "PostgreSQL full backup completed successfully"
        else
            log_message "ERROR: PostgreSQL full backup failed"
            return 1
        fi
    fi
    
    # バックアップ検証
    if [ -f "$db_backup_dir/zabbix_full_backup.sql.gz" ]; then
        backup_size=$(du -sh "$db_backup_dir/zabbix_full_backup.sql.gz" | cut -f1)
    elif [ -f "$db_backup_dir/zabbix_full_backup.dump" ]; then
        backup_size=$(du -sh "$db_backup_dir/zabbix_full_backup.dump" | cut -f1)
    fi
    
    # メタデータ作成
    cat > "$db_backup_dir/backup_metadata.txt" << EOF
Backup Type: Database Full
Backup Date: $(date)
Database Type: $DB_TYPE
Database Name: $DB_NAME
Database Size: ${db_size}GB
Backup Size: $backup_size
Hostname: $(hostname)
MySQL Version: $(mysql --version)
Backup Method: mysqldump/pg_dump
Compression: gzip/custom
EOF
    
    log_message "Full database backup completed: $db_backup_dir"
    return 0
}

# データベース増分バックアップ
backup_database_incremental() {
    log_message "Starting incremental database backup..."
    
    local inc_backup_dir="$BACKUP_DIR/database/incremental/$(date +%Y%m%d_%H%M%S)"
    mkdir -p "$inc_backup_dir"
    
    if [ "$DB_TYPE" = "mysql" ]; then
        # バイナリログバックアップ
        local last_log_file="$BACKUP_DIR/database/incremental/.last_log_position"
        local start_position=""
        
        if [ -f "$last_log_file" ]; then
            start_position=$(cat "$last_log_file")
        else
            # 初回実行時は現在位置から開始
            start_position=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "SHOW MASTER STATUS\G" | grep Position | awk '{print $2}')
        fi
        
        # 現在のログファイルと位置取得
        local current_log=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "SHOW MASTER STATUS\G" | grep File | awk '{print $2}')
        local current_position=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "SHOW MASTER STATUS\G" | grep Position | awk '{print $2}')
        
        # バイナリログの複製
        if [ -n "$current_log" ] && [ -n "$current_position" ]; then
            cp "/var/lib/mysql/$current_log" "$inc_backup_dir/"
            
            # 位置情報保存
            echo "$current_position" > "$last_log_file"
            
            log_message "Incremental backup completed: $current_log (position: $current_position)"
        else
            log_message "WARNING: Could not determine binary log position"
            return 1
        fi
    fi
    
    return 0
}

# 監視データアーカイブ
archive_monitoring_data() {
    log_message "Starting monitoring data archive..."
    
    local archive_dir="$BACKUP_DIR/archive/$(date +%Y%m%d)"
    mkdir -p "$archive_dir"
    
    # 古いデータの特定(3ヶ月前)
    local archive_date=$(date -d "3 months ago" +%s)
    
    # 履歴データアーカイブ
    mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
        SELECT 'history', COUNT(*) FROM history WHERE clock < $archive_date
        UNION ALL
        SELECT 'history_uint', COUNT(*) FROM history_uint WHERE clock < $archive_date
        UNION ALL
        SELECT 'history_str', COUNT(*) FROM history_str WHERE clock < $archive_date
        UNION ALL
        SELECT 'history_text', COUNT(*) FROM history_text WHERE clock < $archive_date
        UNION ALL
        SELECT 'history_log', COUNT(*) FROM history_log WHERE clock < $archive_date;" "$DB_NAME" > "$archive_dir/archive_counts.txt"
    
    # アーカイブデータをCSVエクスポート
    for table in history history_uint history_str history_text history_log; do
        log_message "Archiving table: $table"
        
        mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
            SELECT * FROM $table WHERE clock < $archive_date
            INTO OUTFILE '$archive_dir/${table}_archive.csv'
            FIELDS TERMINATED BY ','
            ENCLOSED BY '\"'
            LINES TERMINATED BY '\n';" "$DB_NAME"
        
        if [ $? -eq 0 ]; then
            # アーカイブ成功後、古いデータ削除
            mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "
                DELETE FROM $table WHERE clock < $archive_date;" "$DB_NAME"
            
            log_message "Archived and cleaned table: $table"
        else
            log_message "ERROR: Failed to archive table: $table"
        fi
    done
    
    # アーカイブファイル圧縮
    cd "$archive_dir"
    tar -czf "monitoring_data_archive_$(date +%Y%m%d).tar.gz" *.csv
    rm -f *.csv
    
    log_message "Monitoring data archive completed: $archive_dir"
    return 0
}

# バックアップ検証
verify_backup() {
    local backup_file="$1"
    local backup_type="$2"
    
    log_message "Verifying backup: $backup_file"
    
    case "$backup_type" in
        "mysql_dump")
            # MySQL dumpファイルの検証
            if zcat "$backup_file" | head -100 | grep -q "MySQL dump"; then
                log_message "✓ MySQL dump verification passed"
                return 0
            else
                log_message "✗ MySQL dump verification failed"
                return 1
            fi
            ;;
        "postgresql_dump")
            # PostgreSQL dumpファイルの検証
            if pg_restore --list "$backup_file" > /dev/null 2>&1; then
                log_message "✓ PostgreSQL dump verification passed"
                return 0
            else
                log_message "✗ PostgreSQL dump verification failed"
                return 1
            fi
            ;;
        "config_tar")
            # 設定ファイルTARの検証
            if tar -tzf "$backup_file" > /dev/null 2>&1; then
                log_message "✓ Configuration archive verification passed"
                return 0
            else
                log_message "✗ Configuration archive verification failed"
                return 1
            fi
            ;;
    esac
    
    return 1
}

# 古いバックアップクリーンアップ
cleanup_old_backups() {
    log_message "Starting backup cleanup..."
    
    # 設定バックアップクリーンアップ(30日保持)
    find "$BACKUP_DIR/config" -type d -mtime +30 -exec rm -rf {} \; 2>/dev/null
    
    # 完全データベースバックアップクリーンアップ(12週間保持)
    find "$BACKUP_DIR/database/full" -type d -mtime +84 -exec rm -rf {} \; 2>/dev/null
    
    # 増分バックアップクリーンアップ(7日保持)
    find "$BACKUP_DIR/database/incremental" -type d -mtime +7 -exec rm -rf {} \; 2>/dev/null
    
    # アーカイブクリーンアップ(6ヶ月保持)
    find "$BACKUP_DIR/archive" -type f -mtime +180 -delete 2>/dev/null
    
    log_message "Backup cleanup completed"
}

# クラウドバックアップ同期
sync_to_cloud() {
    local local_backup_dir="$1"
    
    if [ -n "$CLOUD_SYNC_ENABLED" ] && [ "$CLOUD_SYNC_ENABLED" = "true" ]; then
        log_message "Starting cloud backup sync..."
        
        case "$CLOUD_PROVIDER" in
            "aws")
                aws s3 sync "$local_backup_dir" "s3://$S3_BUCKET/zabbix-backups/" \
                    --delete --storage-class STANDARD_IA
                ;;
            "gcp")
                gsutil -m rsync -r -d "$local_backup_dir" "gs://$GCS_BUCKET/zabbix-backups/"
                ;;
            "azure")
                azcopy sync "$local_backup_dir" "https://$AZURE_ACCOUNT.blob.core.windows.net/$AZURE_CONTAINER/zabbix-backups/"
                ;;
        esac
        
        if [ $? -eq 0 ]; then
            log_message "Cloud backup sync completed successfully"
        else
            log_message "ERROR: Cloud backup sync failed"
            return 1
        fi
    fi
    
    return 0
}

# バックアップレポート生成
generate_backup_report() {
    local report_file="$BACKUP_DIR/reports/backup_report_$(date +%Y%m%d).txt"
    mkdir -p "$BACKUP_DIR/reports"
    
    cat > "$report_file" << EOF
# Zabbix Backup Report

**Date**: $(date)
**Hostname**: $(hostname)

## Backup Summary

### Configuration Backup
- Location: $BACKUP_DIR/config/
- Latest: $(ls -1t "$BACKUP_DIR/config/" | head -1)
- Size: $(du -sh "$BACKUP_DIR/config/"$(ls -1t "$BACKUP_DIR/config/" | head -1) | cut -f1)

### Database Backup
- Full Backup Location: $BACKUP_DIR/database/full/
- Latest Full: $(ls -1t "$BACKUP_DIR/database/full/" | head -1)
- Incremental Location: $BACKUP_DIR/database/incremental/
- Total Database Backups: $(find "$BACKUP_DIR/database" -name "*.sql.gz" -o -name "*.dump" | wc -l)

### Storage Usage
- Total Backup Size: $(du -sh "$BACKUP_DIR" | cut -f1)
- Available Space: $(df -h "$BACKUP_DIR" | awk 'NR==2 {print $4}')

### Backup Status
- Configuration: ✓ Success
- Database Full: ✓ Success
- Database Incremental: ✓ Success
- Cloud Sync: $([ "$CLOUD_SYNC_ENABLED" = "true" ] && echo "✓ Enabled" || echo "- Disabled")

## Recent Backup Files
$(find "$BACKUP_DIR" -type f -mtime -1 -name "*backup*" | head -10)

## Recommendations
- Monitor disk space usage
- Test restore procedures monthly
- Verify cloud sync functionality
- Review backup retention policies

EOF

    log_message "Backup report generated: $report_file"
}

# メイン実行関数
main() {
    local backup_type="${1:-full}"
    
    log_message "Starting Zabbix backup process (type: $backup_type)..."
    
    # ディレクトリ作成
    mkdir -p "$BACKUP_DIR"/{config,database/{full,incremental},archive,reports}
    
    case "$backup_type" in
        "config")
            backup_configuration
            ;;
        "database-full")
            backup_database_full
            ;;
        "database-incremental")
            backup_database_incremental
            ;;
        "archive")
            archive_monitoring_data
            ;;
        "full")
            backup_configuration
            backup_database_full
            archive_monitoring_data
            sync_to_cloud "$BACKUP_DIR"
            ;;
        "maintenance")
            cleanup_old_backups
            generate_backup_report
            ;;
    esac
    
    if [ $? -eq 0 ]; then
        log_message "Backup process completed successfully"
        send_notification "SUCCESS" "Backup completed successfully" "success"
    else
        log_message "ERROR: Backup process failed"
        send_notification "FAILED" "Backup process encountered errors" "error"
        exit 1
    fi
    
    # 日次レポート生成(フルバックアップ時のみ)
    if [ "$backup_type" = "full" ]; then
        generate_backup_report
    fi
}

# スクリプト実行
main "$@"

復旧手順

災害復旧計画

yaml
# 災害復旧レベル定義
復旧レベル:
  レベル1 - 部分復旧:
    対象: "設定ファイル復旧"
    RTO: "30分"
    RPO: "24時間"
    手順:
      - 設定バックアップから復旧
      - サービス再起動
      - 接続確認
    
  レベル2 - データ復旧:
    対象: "データベース復旧"
    RTO: "2時間"
    RPO: "15分"
    手順:
      - データベース停止
      - 完全バックアップ復元
      - 増分バックアップ適用
      - 整合性確認
    
  レベル3 - 完全復旧:
    対象: "システム全体復旧"
    RTO: "4時間"
    RPO: "15分"
    手順:
      - ハードウェア調達・設定
      - OS再インストール
      - Zabbix再インストール
      - データ復旧
      - 監視再開

# 復旧優先度
復旧優先度:
  P1 - 最高:
    - 重要業務システム監視
    - セキュリティ監視
    - 障害通知機能
  
  P2 - 高:
    - パフォーマンス監視
    - レポート機能
    - ダッシュボード
  
  P3 - 中:
    - 履歴データ
    - トレンドデータ
    - 過去レポート
  
  P4 - 低:
    - カスタマイゼーション
    - 実験的機能
    - テスト環境

アップグレード管理

段階的アップグレード戦略

アップグレード計画

yaml
# アップグレードフェーズ
フェーズ設計:
  Phase 1 - 計画・準備:
    期間: "2週間"
    タスク:
      - 新バージョン調査
      - 互換性確認
      - テスト環境構築
      - 移行計画策定
      - リスク評価
      - ロールバック計画
    
  Phase 2 - テスト実装:
    期間: "1週間"
    タスク:
      - テスト環境アップグレード
      - 機能テスト実施
      - 性能テスト実施
      - 統合テスト実施
      - セキュリティテスト
    
  Phase 3 - 本番実装:
    期間: "1日"
    タスク:
      - メンテナンス窓設定
      - 完全バックアップ実行
      - アップグレード実施
      - 動作確認
      - 監視再開
    
  Phase 4 - 事後確認:
    期間: "1週間"
    タスク:
      - 安定性監視
      - 性能監視
      - ユーザー確認
      - 問題対応
      - ドキュメント更新

# リスク評価基準
リスク評価:
  技術リスク:
    データベーススキーマ変更: "高"
    API変更: "中"
    設定形式変更: "中"
    UIの変更: "低"
  
  運用リスク:
    サービス停止時間: "中"
    データ損失可能性: "高"
    ロールバック複雑度: "中"
    技能要件変更: "低"
  
  ビジネスリスク:
    監視サービス中断: "高"
    SLA違反可能性: "高"
    ユーザー影響: "中"
    コスト影響: "低"

自動アップグレードスクリプト

bash
#!/bin/bash
# Zabbix自動アップグレードシステム

UPGRADE_CONFIG="/etc/zabbix/upgrade.conf"
LOG_FILE="/var/log/zabbix/upgrade.log"
BACKUP_DIR="/backup/zabbix/upgrade"
TEST_CONFIG="/etc/zabbix/upgrade_tests.conf"

# 設定読み込み
source "$UPGRADE_CONFIG"

# ログ関数
log_message() {
    echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE"
}

# 現在バージョン確認
get_current_version() {
    local current_version=$(zabbix_server --version | head -1 | awk '{print $3}')
    echo "$current_version"
}

# 新バージョン確認
check_new_version() {
    local current_version="$1"
    local latest_version
    
    # Zabbix公式リポジトリから最新バージョン確認
    latest_version=$(curl -s "https://repo.zabbix.com/zabbix/" | \
        grep -oP 'href="[0-9]+\.[0-9]+/"' | \
        grep -oP '[0-9]+\.[0-9]+' | \
        sort -V | tail -1)
    
    log_message "Current version: $current_version"
    log_message "Latest version: $latest_version"
    
    if [ "$current_version" != "$latest_version" ]; then
        echo "$latest_version"
        return 0
    else
        log_message "Already running latest version"
        return 1
    fi
}

# 互換性確認
check_compatibility() {
    local target_version="$1"
    local current_version="$2"
    
    log_message "Checking compatibility for upgrade to $target_version..."
    
    # メジャーバージョン変更確認
    local current_major=$(echo "$current_version" | cut -d. -f1)
    local target_major=$(echo "$target_version" | cut -d. -f1)
    
    if [ "$current_major" != "$target_major" ]; then
        log_message "WARNING: Major version upgrade detected ($current_major -> $target_major)"
        return 2  # 要注意
    fi
    
    # データベーススキーマ変更確認
    local schema_changes=$(curl -s "https://www.zabbix.com/documentation/current/en/manual/installation/upgrade_notes_$target_major" | \
        grep -i "database" | wc -l)
    
    if [ "$schema_changes" -gt 0 ]; then
        log_message "WARNING: Database schema changes detected"
        return 1  # 注意必要
    fi
    
    log_message "Compatibility check passed"
    return 0
}

# アップグレード前バックアップ
create_upgrade_backup() {
    log_message "Creating upgrade backup..."
    
    local backup_timestamp=$(date +%Y%m%d_%H%M%S)
    local upgrade_backup_dir="$BACKUP_DIR/upgrade_$backup_timestamp"
    
    mkdir -p "$upgrade_backup_dir"
    
    # 設定ファイルバックアップ
    tar -czf "$upgrade_backup_dir/config_backup.tar.gz" /etc/zabbix/
    
    # データベースバックアップ
    mysqldump --single-transaction --routines --triggers \
        -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" | \
        gzip > "$upgrade_backup_dir/database_backup.sql.gz"
    
    # アプリケーションファイルバックアップ
    tar -czf "$upgrade_backup_dir/application_backup.tar.gz" /usr/share/zabbix/
    
    # バックアップ検証
    if [ -f "$upgrade_backup_dir/database_backup.sql.gz" ] && \
       [ -f "$upgrade_backup_dir/config_backup.tar.gz" ]; then
        log_message "Upgrade backup created successfully: $upgrade_backup_dir"
        echo "$upgrade_backup_dir"
        return 0
    else
        log_message "ERROR: Upgrade backup creation failed"
        return 1
    fi
}

# パッケージアップグレード実行
perform_package_upgrade() {
    local target_version="$1"
    
    log_message "Starting package upgrade to version $target_version..."
    
    # パッケージリポジトリ更新
    apt update
    
    # 利用可能バージョン確認
    local available_version=$(apt list --upgradable 2>/dev/null | grep zabbix-server | awk '{print $2}')
    log_message "Available package version: $available_version"
    
    # Zabbixサーバー停止
    log_message "Stopping Zabbix server..."
    systemctl stop zabbix-server
    systemctl stop zabbix-agent
    
    # パッケージアップグレード
    log_message "Upgrading Zabbix packages..."
    apt upgrade -y zabbix-server-mysql zabbix-frontend-php zabbix-apache-conf zabbix-agent
    
    if [ $? -eq 0 ]; then
        log_message "Package upgrade completed successfully"
        return 0
    else
        log_message "ERROR: Package upgrade failed"
        return 1
    fi
}

# データベースアップグレード
upgrade_database() {
    log_message "Starting database upgrade..."
    
    # データベースアップグレードスクリプト実行
    local upgrade_script="/usr/share/doc/zabbix-server-mysql/database.sql"
    
    if [ -f "$upgrade_script" ]; then
        mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" < "$upgrade_script"
        
        if [ $? -eq 0 ]; then
            log_message "Database upgrade completed successfully"
            return 0
        else
            log_message "ERROR: Database upgrade failed"
            return 1
        fi
    else
        log_message "No database upgrade script found - skipping"
        return 0
    fi
}

# アップグレード後テスト
post_upgrade_test() {
    log_message "Starting post-upgrade tests..."
    
    # サービス起動
    systemctl start zabbix-server
    systemctl start zabbix-agent
    
    # 起動確認
    sleep 10
    
    if ! systemctl is-active zabbix-server >/dev/null; then
        log_message "ERROR: Zabbix server failed to start"
        return 1
    fi
    
    # データベース接続確認
    if ! mysql -u "$DB_USER" -p"$DB_PASSWORD" -e "SELECT 1;" "$DB_NAME" >/dev/null 2>&1; then
        log_message "ERROR: Database connection failed"
        return 1
    fi
    
    # API接続確認
    local api_response=$(curl -s -X POST \
        -H "Content-Type: application/json" \
        -d '{"jsonrpc":"2.0","method":"apiinfo.version","params":{},"id":1}' \
        "http://localhost/zabbix/api_jsonrpc.php")
    
    if echo "$api_response" | grep -q "result"; then
        local new_version=$(echo "$api_response" | jq -r '.result')
        log_message "API test passed - version: $new_version"
    else
        log_message "WARNING: API test failed"
        return 1
    fi
    
    # 基本機能テスト
    source "$TEST_CONFIG"
    run_functional_tests
    
    if [ $? -eq 0 ]; then
        log_message "Post-upgrade tests completed successfully"
        return 0
    else
        log_message "ERROR: Post-upgrade tests failed"
        return 1
    fi
}

# 機能テスト実行
run_functional_tests() {
    log_message "Running functional tests..."
    
    # ホスト数確認
    local host_count=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e \
        "SELECT COUNT(*) FROM hosts WHERE status=0;" -s -N "$DB_NAME")
    
    if [ "$host_count" -gt 0 ]; then
        log_message "✓ Host count check passed: $host_count hosts"
    else
        log_message "✗ Host count check failed"
        return 1
    fi
    
    # アイテム数確認
    local item_count=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e \
        "SELECT COUNT(*) FROM items WHERE status=0;" -s -N "$DB_NAME")
    
    if [ "$item_count" -gt 0 ]; then
        log_message "✓ Item count check passed: $item_count items"
    else
        log_message "✗ Item count check failed"
        return 1
    fi
    
    # 最新データ確認
    local recent_data=$(mysql -u "$DB_USER" -p"$DB_PASSWORD" -e \
        "SELECT COUNT(*) FROM history WHERE clock > UNIX_TIMESTAMP() - 3600;" -s -N "$DB_NAME")
    
    if [ "$recent_data" -gt 0 ]; then
        log_message "✓ Recent data check passed: $recent_data entries"
    else
        log_message "⚠ Recent data check warning: $recent_data entries"
    fi
    
    # Web interface確認
    local web_response=$(curl -s -o /dev/null -w "%{http_code}" "http://localhost/zabbix/")
    
    if [ "$web_response" = "200" ]; then
        log_message "✓ Web interface check passed"
    else
        log_message "✗ Web interface check failed: HTTP $web_response"
        return 1
    fi
    
    return 0
}

# ロールバック実行
perform_rollback() {
    local backup_dir="$1"
    
    log_message "Starting rollback process..."
    
    if [ ! -d "$backup_dir" ]; then
        log_message "ERROR: Backup directory not found: $backup_dir"
        return 1
    fi
    
    # サービス停止
    systemctl stop zabbix-server
    systemctl stop zabbix-agent
    
    # 設定ファイル復元
    tar -xzf "$backup_dir/config_backup.tar.gz" -C /
    
    # データベース復元
    mysql -u "$DB_USER" -p"$DB_PASSWORD" "$DB_NAME" < \
        <(zcat "$backup_dir/database_backup.sql.gz")
    
    # アプリケーションファイル復元
    tar -xzf "$backup_dir/application_backup.tar.gz" -C /
    
    # サービス再起動
    systemctl start zabbix-server
    systemctl start zabbix-agent
    
    log_message "Rollback completed"
    return 0
}

# 通知送信
send_upgrade_notification() {
    local status="$1"
    local version="$2"
    local message="$3"
    
    # Slack通知
    if [ -n "$SLACK_WEBHOOK_URL" ]; then
        local emoji
        case "$status" in
            "success") emoji="✅" ;;
            "warning") emoji="⚠️" ;;
            "error") emoji="❌" ;;
            *) emoji="ℹ️" ;;
        esac
        
        curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"$emoji Zabbix Upgrade Report\\nVersion: $version\\nStatus: $status\\n$message\"}" \
            "$SLACK_WEBHOOK_URL"
    fi
    
    # メール通知
    if [ -n "$ADMIN_EMAIL" ]; then
        echo "$message" | mail -s "Zabbix Upgrade $status: $version" "$ADMIN_EMAIL"
    fi
}

# メイン処理
main() {
    local mode="${1:-check}"
    
    case "$mode" in
        "check")
            # アップグレード可能性確認
            local current_version=$(get_current_version)
            local new_version
            
            if new_version=$(check_new_version "$current_version"); then
                log_message "New version available: $new_version"
                
                check_compatibility "$new_version" "$current_version"
                local compat_result=$?
                
                case "$compat_result" in
                    0) log_message "✓ Upgrade recommended" ;;
                    1) log_message "⚠ Upgrade possible with caution" ;;
                    2) log_message "⚠ Major upgrade - manual review required" ;;
                esac
            fi
            ;;
            
        "upgrade")
            # 自動アップグレード実行
            local current_version=$(get_current_version)
            local target_version="$2"
            
            if [ -z "$target_version" ]; then
                target_version=$(check_new_version "$current_version")
            fi
            
            if [ -n "$target_version" ]; then
                log_message "Starting upgrade from $current_version to $target_version"
                
                # バックアップ作成
                local backup_dir
                if backup_dir=$(create_upgrade_backup); then
                    
                    # アップグレード実行
                    if perform_package_upgrade "$target_version" && \
                       upgrade_database && \
                       post_upgrade_test; then
                        
                        log_message "Upgrade completed successfully"
                        send_upgrade_notification "success" "$target_version" "Upgrade completed successfully"
                    else
                        log_message "Upgrade failed - performing rollback"
                        perform_rollback "$backup_dir"
                        send_upgrade_notification "error" "$target_version" "Upgrade failed - rollback performed"
                        exit 1
                    fi
                else
                    log_message "Pre-upgrade backup failed - aborting"
                    send_upgrade_notification "error" "$target_version" "Pre-upgrade backup failed"
                    exit 1
                fi
            else
                log_message "No upgrade available"
            fi
            ;;
            
        "rollback")
            # 手動ロールバック
            local backup_dir="$2"
            
            if [ -z "$backup_dir" ]; then
                backup_dir=$(find "$BACKUP_DIR" -name "upgrade_*" -type d | sort | tail -1)
            fi
            
            if [ -n "$backup_dir" ]; then
                perform_rollback "$backup_dir"
                send_upgrade_notification "warning" "rollback" "Manual rollback performed"
            else
                log_message "ERROR: No backup directory specified"
                exit 1
            fi
            ;;
            
        "test")
            # アップグレード後テストのみ実行
            post_upgrade_test
            ;;
    esac
}

# スクリプト実行
main "$@"

まとめ

効果的なZabbix運用管理は、監視システムの安定性と継続的改善を実現する重要な要素です。

重要ポイント

  1. 日常運用: 定期的なヘルスチェックと予防的メンテナンス
  2. バックアップ戦略: 3-2-1原則に基づく包括的データ保護
  3. アップグレード管理: 段階的で安全なバージョン管理
  4. 自動化: 手作業の削減と運用効率の向上

次のステップ

次章では、一般的な問題とトラブルシューティング手法について学習し、問題解決能力を向上させます。


関連リンク