#!/bin/bash
# ============================================================
# GUARDiA SM | db_mysql_sm.sh
# 대상: MySQL / MariaDB
# 파라미터: MYSQL_HOST=localhost MYSQL_PORT=3306
#           MYSQL_USER=root MYSQL_PASS=password
#           SLOW_QUERY_WARN=100 MAX_CONN_WARN=80
# ============================================================
set -euo pipefail
MYSQL_HOST=${MYSQL_HOST:-localhost}
MYSQL_PORT=${MYSQL_PORT:-3306}
MYSQL_USER=${MYSQL_USER:-root}
MYSQL_PASS=${MYSQL_PASS:-""}
SLOW_QUERY_WARN=${SLOW_QUERY_WARN:-100}
MAX_CONN_WARN=${MAX_CONN_WARN:-80}
OK="[OK]"; WARN="[WARN]"; CRIT="[CRIT]"
SEP="─────────────────────────────────────────"
RESULT=0

# mysql 실행 헬퍼
MY="mysql -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER}"
[ -n "$MYSQL_PASS" ] && MY="${MY} -p${MYSQL_PASS}"
MY="${MY} --batch --silent"

echo "======================================================"
echo " GUARDiA SM 점검 | MySQL/MariaDB | $(hostname -s)"
echo " 점검 시각: $(date '+%Y-%m-%d %H:%M:%S %Z')"
echo "======================================================"

# ── 1. 프로세스 ───────────────────────────────────────────
echo; echo "[$SEP] 1. MySQL/MariaDB 프로세스"
MYSQL_PROC=$(pgrep -c "mysqld\|mariadbd" 2>/dev/null || echo 0)
if [ "$MYSQL_PROC" -gt 0 ]; then
    echo " ${OK} MySQL/MariaDB 실행 중 (${MYSQL_PROC}개)"
else
    echo " ${CRIT} MySQL/MariaDB 프로세스 없음"
    RESULT=2
fi

# ── 2. 포트 리스닝 + 접속 테스트 ─────────────────────────
echo; echo "[$SEP] 2. 포트 리스닝 및 접속"
if ss -tlnp 2>/dev/null | grep -q ":${MYSQL_PORT} "; then
    echo " ${OK} 포트 ${MYSQL_PORT} LISTEN"
else
    echo " ${CRIT} 포트 ${MYSQL_PORT} LISTEN 없음"
    RESULT=2
fi
if command -v mysql &>/dev/null; then
    VERSION=$(${MY} -e "SELECT @@version;" 2>/dev/null | head -1 || echo "접속 실패")
    if echo "$VERSION" | grep -qE "[0-9]+\.[0-9]+"; then
        echo " ${OK} DB 접속 성공 — 버전: ${VERSION}"
    else
        echo " ${CRIT} DB 접속 실패"
        RESULT=2
    fi
else
    echo " ${WARN} mysql 클라이언트 없음"
    [ $RESULT -lt 1 ] && RESULT=1
fi

# ── 3. 연결 현황 ─────────────────────────────────────────
echo; echo "[$SEP] 3. 연결 현황"
if command -v mysql &>/dev/null && [ "$RESULT" -lt 2 ]; then
    MAX_CONN=$(${MY} -e "SHOW VARIABLES LIKE 'max_connections';" 2>/dev/null | awk '{print $2}')
    CURR_CONN=$(${MY} -e "SHOW STATUS LIKE 'Threads_connected';" 2>/dev/null | awk '{print $2}')
    RUNNING=$(${MY} -e "SHOW STATUS LIKE 'Threads_running';" 2>/dev/null | awk '{print $2}')
    echo " 최대 연결: ${MAX_CONN}"
    echo " 현재 연결: ${CURR_CONN} (실행 중: ${RUNNING})"
    if [ -n "$MAX_CONN" ] && [ "$MAX_CONN" -gt 0 ]; then
        CONN_PCT=$(( CURR_CONN * 100 / MAX_CONN ))
        if [ "$CONN_PCT" -ge "$MAX_CONN_WARN" ]; then
            echo " ${WARN} 연결 사용률 ${CONN_PCT}%"
            [ $RESULT -lt 1 ] && RESULT=1
        else
            echo " ${OK} 연결 사용률 ${CONN_PCT}%"
        fi
    fi
fi

# ── 4. 슬로우 쿼리 ────────────────────────────────────────
echo; echo "[$SEP] 4. 슬로우 쿼리"
if command -v mysql &>/dev/null && [ "$RESULT" -lt 2 ]; then
    SLOW_CNT=$(${MY} -e "SHOW STATUS LIKE 'Slow_queries';" 2>/dev/null | awk '{print $2}' || echo 0)
    SLOW_LOG=$(${MY} -e "SHOW VARIABLES LIKE 'slow_query_log';" 2>/dev/null | awk '{print $2}')
    LONG_TIME=$(${MY} -e "SHOW VARIABLES LIKE 'long_query_time';" 2>/dev/null | awk '{print $2}')
    echo " 슬로우 쿼리 로그: ${SLOW_LOG} (임계: ${LONG_TIME}s)"
    if [ "${SLOW_CNT:-0}" -gt "$SLOW_QUERY_WARN" ]; then
        echo " ${WARN} 슬로우 쿼리 누적: ${SLOW_CNT}건"
        [ $RESULT -lt 1 ] && RESULT=1
    else
        echo " ${OK} 슬로우 쿼리: ${SLOW_CNT}건"
    fi
fi

# ── 5. InnoDB 상태 ────────────────────────────────────────
echo; echo "[$SEP] 5. InnoDB 주요 상태"
if command -v mysql &>/dev/null && [ "$RESULT" -lt 2 ]; then
    INNODB=$(${MY} -e "
        SHOW STATUS WHERE Variable_name IN
        ('Innodb_buffer_pool_reads','Innodb_buffer_pool_read_requests',
         'Innodb_row_lock_waits','Innodb_deadlocks','Innodb_log_waits');" \
        2>/dev/null | sed 's/^/ /' || echo "")
    echo "$INNODB"
    # 데드락 체크
    DEADLOCKS=$(${MY} -e "SHOW STATUS LIKE 'Innodb_deadlocks';" 2>/dev/null | awk '{print $2}' || echo 0)
    [ "${DEADLOCKS:-0}" -gt 0 ] && echo " ${WARN} 데드락 발생: ${DEADLOCKS}건" && [ $RESULT -lt 1 ] && RESULT=1
fi

# ── 6. 복제(Replication) 상태 ────────────────────────────
echo; echo "[$SEP] 6. 복제 상태"
if command -v mysql &>/dev/null && [ "$RESULT" -lt 2 ]; then
    SLAVE_STATUS=$(${MY} -e "SHOW SLAVE STATUS\G" 2>/dev/null || \
                   ${MY} -e "SHOW REPLICA STATUS\G" 2>/dev/null || echo "")
    if [ -n "$SLAVE_STATUS" ]; then
        IO_RUNNING=$(echo "$SLAVE_STATUS" | grep "Slave_IO_Running\|Replica_IO_Running" | awk '{print $2}')
        SQL_RUNNING=$(echo "$SLAVE_STATUS" | grep "Slave_SQL_Running\|Replica_SQL_Running" | awk '{print $2}')
        BEHIND=$(echo "$SLAVE_STATUS" | grep "Seconds_Behind_Master\|Seconds_Behind_Source" | awk '{print $2}')
        echo " IO Thread: ${IO_RUNNING}, SQL Thread: ${SQL_RUNNING}"
        echo " 복제 지연: ${BEHIND}초"
        if [ "$IO_RUNNING" != "Yes" ] || [ "$SQL_RUNNING" != "Yes" ]; then
            echo " ${CRIT} 복제 비정상"
            RESULT=2
        elif [ "${BEHIND:-0}" -gt 60 ]; then
            echo " ${WARN} 복제 지연 과다 (${BEHIND}s)"
            [ $RESULT -lt 1 ] && RESULT=1
        else
            echo " ${OK} 복제 정상"
        fi
    else
        echo " 복제 미설정 (Standalone)"
    fi
fi

# ── 7. DB 크기 ────────────────────────────────────────────
echo; echo "[$SEP] 7. DB 크기 (상위 5)"
if command -v mysql &>/dev/null && [ "$RESULT" -lt 2 ]; then
    ${MY} -e "
        SELECT table_schema AS db,
               ROUND(SUM(data_length + index_length)/1024/1024, 1) AS size_mb
        FROM information_schema.tables
        GROUP BY table_schema
        ORDER BY size_mb DESC
        LIMIT 5;" 2>/dev/null | sed 's/^/ /' || true
fi

# ── 요약 ─────────────────────────────────────────────────
echo
echo "======================================================"
case $RESULT in
    0) echo " 최종 결과: ${OK}   MySQL/MariaDB 정상" ;;
    1) echo " 최종 결과: ${WARN} 주의 항목 있음" ;;
    2) echo " 최종 결과: ${CRIT} 즉시 조치 필요" ;;
esac
echo " 점검 완료: $(date '+%Y-%m-%d %H:%M:%S')"
echo "======================================================"
exit $RESULT
