MySQL 데이터베이스 환경에서 고가용성 및 데이터 일관성을 유지하기 위해 주-종(Master-Slave) 복제는 필수적인 구성 요소입니다. 복제 프로세스에 문제가 발생하면 데이터 불일치, 서비스 중단 등의 심각한 문제가 초래될 수 있습니다. 본 문서에서는 쉘 스크립트를 사용하여 MySQL 복제 상태를 주기적으로 모니터링하고, 이상 감지 시 관리자에게 알림을 전송하는 방법을 설명합니다.
1. 스크립트 구성 요소
아래는 MySQL 복제 상태를 확인하고 경고를 보내는 쉘 스크립트의 예시입니다.
#!/bin/bash
# 설정 변수
DB_SERVER="localhost"
DB_USERNAME="replication_monitor" # MySQL 모니터링용 사용자명
DB_PASSWORD="your_secure_db_pass" # MySQL 모니터링용 비밀번호
ALARM_WEBHOOK_URL="https://your_company_messenger_webhook_url" # 알림을 보낼 웹훅 주소 (예: 기업 메신저 봇)
# MySQL 복제 스레드 상태를 조회하는 함수
get_thread_status() {
local thread_name=$1
# 'SHOW SLAVE STATUS\G' 명령을 실행하고, 특정 스레드 이름에 해당하는 값만 추출합니다.
# 오류 메시지는 /dev/null로 리다이렉트하여 숨깁니다.
mysql -h"${DB_SERVER}" -u"${DB_USERNAME}" -p"${DB_PASSWORD}" -e "SHOW SLAVE STATUS\\G" 2>/dev/null | \
grep "${thread_name}:" | awk '{print $2}'
}
# IO 스레드 상태 확인
# Master로부터 이벤트를 가져오는 스레드의 상태를 확인합니다.
REPL_IO_STATE=$(get_thread_status "Slave_IO_Running")
# SQL 스레드 상태 확인
# 가져온 이벤트를 로컬 데이터베이스에 적용하는 스레드의 상태를 확인합니다.
REPL_SQL_STATE=$(get_thread_status "Slave_SQL_Running")
# 경고 메시지 목록을 저장할 배열 초기화
WARNING_MESSAGES=()
# IO 스레드 상태 검증
if [[ "${REPL_IO_STATE}" != "Yes" ]]; then
WARNING_MESSAGES+=("복제 IO 스레드 상태가 비정상입니다: 현재 상태 \"${REPL_IO_STATE}\"")
fi
# SQL 스레드 상태 검증
if [[ "${REPL_SQL_STATE}" != "Yes" ]]; then
WARNING_MESSAGES+=("복제 SQL 스레드 상태가 비정상입니다: 현재 상태 \"${REPL_SQL_STATE}\"")
fi
# 비정상 상태 감지 시 통합 알림 전송
if [[ ${#WARNING_MESSAGES[@]} -gt 0 ]]; then
FULL_ALERT_MESSAGE="[MySQL 주-종 복제 알림]\n"
for msg in "${WARNING_MESSAGES[@]}"; do
FULL_ALERT_MESSAGE+="- ${msg}\n"
done
# 웹훅으로 알림 전송 (이 예시는 단순히 텍스트를 POST 본문으로 보냅니다.
# 대부분의 기업 메신저 웹훅은 JSON 형식을 요구하므로, 아래 주석 처리된 예시처럼 조정해야 합니다.)
# JSON_PAYLOAD=$(printf '{"msgtype": "text", "text": {"content": "%s"}}' "$FULL_ALERT_MESSAGE")
# curl -s -H "Content-Type: application/json" -d "${JSON_PAYLOAD}" "${ALARM_WEBHOOK_URL}"
# 원본 스크립트의 간결한 전달 방식을 모방하되, POST 요청을 명시
echo -e "${FULL_ALERT_MESSAGE}" | curl -s -X POST --data-binary @- "${ALARM_WEBHOOK_URL}"
fi
2. 스크립트 상세 설명
2.1. Shebang 및 초기 설정
스크립트의 첫 줄 #!/bin/bash는 이 스크립트를 Bash 쉘로 실행하도록 지정합니다. 이어서 MySQL 연결 정보와 알림을 보낼 웹훅 URL을 정의합니다.
DB_SERVER: MySQL 서버의 호스트 주소입니다.DB_USERNAME: MySQL에 연결할 사용자 이름입니다.DB_PASSWORD: 해당 사용자의 비밀번호입니다. 보안상 중요한 정보이므로 실제 운영 환경에서는 환경 변수나 비밀 관리 도구를 사용하는 것이 좋습니다.ALARM_WEBHOOK_URL: 알림 메시지를 보낼 외부 시스템(예: 기업 메신저, 슬랙)의 웹훅 URL입니다.
2.2. 복제 스레드 상태 조회 함수
get_thread_status 함수는 특정 MySQL 복제 스레드의 현재 상태를 추출합니다.
get_thread_status() {
local thread_name=$1
mysql -h"${DB_SERVER}" -u"${DB_USERNAME}" -p"${DB_PASSWORD}" -e "SHOW SLAVE STATUS\\G" 2>/dev/null | \
grep "${thread_name}:" | awk '{print $2}'
}
mysql -h... -e "SHOW SLAVE STATUS\\G": MySQL 서버에 접속하여 복제 상태 정보를 수직(\G) 형식으로 조회합니다.2>/dev/null: MySQL 명령 실행 중 발생할 수 있는 에러 메시지를 화면에 출력하지 않고 무시합니다.grep "${thread_name}:":SHOW SLAVE STATUS결과에서Slave_IO_Running:또는Slave_SQL_Running:과 같이 지정된 스레드 이름이 포함된 줄을 찾습니다.awk '{print $2}': 찾은 줄에서 두 번째 필드(예:Yes또는No)만을 추출합니다.
2.3. IO 및 SQL 스레드 상태 확인
정의된 get_thread_status 함수를 사용하여 Slave_IO_Running과 Slave_SQL_Running 두 가지 핵심 스레드의 상태를 각각 REPL_IO_STATE와 REPL_SQL_STATE 변수에 저장합니다.
Slave_IO_Running: 주(Master) 서버로부터 바이너리 로그 이벤트를 성공적으로 읽어오는 IO 스레드의 상태를 나타냅니다.Yes가 아니면 문제가 발생한 것입니다.Slave_SQL_Running: IO 스레드가 가져온 바이너리 로그 이벤트를 종(Slave) 서버에 적용하는 SQL 스레드의 상태를 나타냅니다. 이 또한Yes가 아니면 복제 지연이나 오류가 발생하고 있음을 의미합니다.
2.4. 상태 검증 및 경고 메시지 구성
각 스레드의 상태가 "Yes"가 아닌 경우, WARNING_MESSAGES 배열에 해당 경고 메시지를 추가합니다. 이렇게 하면 여러 복제 문제가 동시에 발생해도 하나의 알림으로 통합하여 보낼 수 있습니다.
2.5. 알림 전송
WARNING_MESSAGES 배열에 하나 이상의 메시지가 있다면, 이를 조합하여 FULL_ALERT_MESSAGE를 생성하고, curl 명령을 사용하여 ALARM_WEBHOOK_URL로 POST 요청을 보냅니다.
echo -e "${FULL_ALERT_MESSAGE}" | curl -s -X POST --data-binary @- "${ALARM_WEBHOOK_URL}"
echo -e "${FULL_ALERT_MESSAGE}": 생성된 알림 메시지를 표준 출력으로 보냅니다.-e옵션은 이스케이프 시퀀스(예:\n)를 해석합니다.curl -s -X POST --data-binary @- "${ALARM_WEBHOOK_URL}":-s: 진행 상황 및 에러 메시지를 숨겨 출력하지 않도록 합니다 (silent mode).-X POST: HTTP POST 메소드를 사용하도록 지정합니다.--data-binary @-: 표준 입력(@-)으로 들어오는 데이터를 HTTP 요청 본문으로 전송하도록 합니다. 이는 파이프된 메시지를 웹훅으로 보내는 일반적인 방법입니다.
대부분의 최신 메신저 웹훅은 텍스트 메시지를 보낼 때 특정 JSON 형식의 페이로드를 기대합니다. 만약 위의 curl 명령이 정상적으로 알림을 보내지 못한다면, 웹훅 서비스의 API 문서를 참조하여 JSON 페이로드를 구성해야 합니다. 스크립트 내 주석에 JSON 페이로드 예시가 포함되어 있습니다.