Notice
Recent Posts
Recent Comments
Link
«   2026/06   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
Tags
more
Archives
Today
Total
관리 메뉴

ssuperjun 님의 블로그

[장애 이력 자동 작성 도구 14] MySQL 장애 연출 본문

인턴

[장애 이력 자동 작성 도구 14] MySQL 장애 연출

ssuperjun 2026. 3. 12. 15:36

장애 연출 계획

각 장애마다 연출 → 로그 확인 → 패턴 확정 → 코드 반영 사이클을 반복

싱글 구성 (ca801)

순서 장애 유형 연출 방법
1 재시작 (정상) mysqladmin shutdown 재시작기준선 확보
2 OOM Kill stress-ng 또는 INSERT 루프로 메모리 고갈, vm.overcommit_memory 조정
3 Too Many Connections max_connections=5 설정 다수 연결
4 디스크 Full fallocate 디스크 채우기
5 Segfault kill -SIGSEGV {mysqld_pid}

복제 구성 (ca801 마스터 → cb801 레플리카)

순서 장애 유형 연출 방법
6 복제 연결 단절 (마스터 재시작) ca801에서 mysqld 재시작
7 복제 연결 단절 (네트워크 단절) iptables ca801↔cb801 포트 차단/해제

 

이후 더 추가된 사항

8. 마스터-레플리카 간 데이터 정합성 장애 유발: 레플리카에서 직접 데이터를 수정한 뒤 마스터에서 동일 row를 건드려 충돌 유발

9. 레플리카의 디스크 Full 장애 유발: 마스터의 데이터를 레플리카가 동기화하는 과정에서 레플리카의 디스크 용량을 부족하게 설정


1번 장애(MySQL 정상 종료)

1단계 - 현재 로그 끝 위치 확인:
wc -l /home1/irteam/mysql/log/mysql.err

2단계
# mysqld_safe로 직접 프로세스 종료
kill $(cat /home1/irteam/mysql/run/mysql.pid)
sleep 3
tail -10 /home1/irteam/mysql/log/mysql.err

3단계
재시작 후 로그 확인
nohup /home1/irteam/mysql/base/bin/mysqld_safe \
  --defaults-file=/home1/irteam/mysql/my.cnf > /dev/null 2>&1 &

sleep 5 && tail -5 /home1/irteam/mysql/log/mysql.err

 

결과

MySQL 재시작 흐름 정리

06:01:07  [MY-013172]  Received SHUTDOWN from user <via user signal>
                       └─ SIGTERM 수신, 정상 종료 시작

06:01:16  [MY-010910]  Shutdown complete
                       └─ mysqld 프로세스 종료 완료

06:01:16  mysqld_safe  mysqld from pid file ... ended
                       └─ mysqld_safe가 mysqld 종료를 감지하고 자신도 종료
                          (SIGTERM은 정상 종료 신호이므로 재시작 없이 종료)

── 약 4분 공백 (mysqld_safe가 없는 상태) ──

06:05:12  mysqld_safe  Logging to '...mysql.err'
06:05:12  mysqld_safe  Starting mysqld daemon with databases from ...
                       └─ 새 mysqld_safe 프로세스 시작 (nohup 명령 실행)

06:05:12  [MY-010116]  mysqld starting as process 2161032
                       └─ mysqld 프로세스 생성

06:05:12  [MY-013576]  InnoDB initialization has started
06:05:13  [MY-013577]  InnoDB initialization has ended
                       └─ InnoDB 스토리지 엔진 초기화 (약 0.24초)

06:05:13  [MY-013602]  Channel mysql_main configured to support TLS
                       └─ TLS/SSL 채널 설정 완료

06:05:13  [MY-011323]  X Plugin ready for connections (port 33060)
                       └─ X Protocol 준비 완료 (MySQL Shell 등에서 사용)

06:05:13  [MY-010931]  ready for connections (port 13306)
                       └─ mysqld 완전 기동 완료 ← 정상화 판단 기준점

2번 장애(OOM Kill)

 

참고

  • OOM Kill은 systemd가 없으므로 커널이 mysqld를 직접 죽이게 해야 하는데, stress-ng나 INSERT 루프보다 kill -9 로 간단히 연출하고 error log 패턴만 확인하는 게 효율적
  • OOM 기록은 dmesg에만 찍히고 error log에는 mysqld_safe의 감지 메시지만 남음
# mysqld PID 확인
cat /home1/irteam/mysql/run/mysql.pid

# SIGKILL 전송 (OOM Kill과 동일한 효과)
kill -9 $(cat /home1/irteam/mysql/run/mysql.pid)

# mysqld_safe가 재시작할 때까지 대기 후 로그 확인
sleep 10 && tail -20 /home1/irteam/mysql/log/mysql.err

 

결과

kill -9 (OOM Kill 동일 패턴) 로그 흐름 정리

06:14:05  mysqld_safe  Number of processes running now: 0
                       └─ mysqld 프로세스가 사라진 것을 mysqld_safe가 감지
                          ← [CRASH_DETECTED] 감지 기준점

06:14:05  mysqld_safe  mysqld restarted
                       └─ mysqld_safe가 자동 재시작 결정
                          (SIGTERM과 달리 SIGKILL은 비정상 종료로 인식 → 재시작)

06:14:05  [MY-010116]  mysqld starting as process 2161286
                       └─ 새 mysqld 프로세스 생성

06:14:05  [MY-013576]  InnoDB initialization has started
06:14:05  [MY-013577]  InnoDB initialization has ended

06:14:05  [MY-010229]  Starting XA crash recovery...
06:14:06  [MY-010232]  XA crash recovery finished.
                       └─ 정상 종료와의 핵심 차이점
                          비정상 종료 시에만 등장 → 비정상 종료의 간접 증거

06:14:06  [MY-010931]  ready for connections
                       └─ 재시작 완료 ← 정상화 판단 기준점

 

정상 종료 vs 비정상 종료(kill -9) 차이:

항목 정상 종료 (SIGTERM) 비정상 종료 (SIGKILL/OOM)
Received SHUTDOWN
Shutdown complete
mysqld_safe ... ended
Number of processes running now: 0
mysqld restarted
XA crash recovery

=> [CRASH_DETECTED] 감지 키워드로 Number of processes running now: 0 사용해도


3 장애(too many connections)

 

현재 max_connections 설정값 확인

/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "SHOW VARIABLES LIKE 'max_connections';"

결과: max_connections = 151

 

# 1. max_connections를 3으로 낮춤 (root + 테스트 연결 고려)
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'nhn!@#123' \
  -e "SET GLOBAL max_connections = 3;"

# 2. 연결 폭발 (백그라운드로 10개 연결 동시 시도)
for i in $(seq 1 10); do
  /home1/irteam/mysql/base/bin/mysql \
    -S /home1/irteam/mysql/run/mysql.sock \
    -u root -p'nhn!@#123' \
    -e "SELECT SLEEP(10);" &
done

# 3. 잠시 대기 후 로그 확인
sleep 5 && tail -20 /home1/irteam/mysql/log/mysql.err

 

결과

Too many connections 에러가 클라이언트 측(터미널)에는 출력됐지만 error log에는 아무것도 찍히지 않음

 

log_error_verbosity 값 확인

확인 결과: log_error_verbosity = 2

3이어야 Too many connections 로그파일에 기록되지만 실제 운영 환경에서 log_error_verbosity 3 경우는 흔치 않음(로그가 너무 많이 쌓여 디스크에 부담이 되기 때문)

 

결론

=> Too many connections는 스킵하자

max_connections 초과는 DB 자체 장애라기보다 애플리케이션 레벨 문제이기도 하고, error log 흔적이 남지 않는 장애를 수집하는 나중에 구현 진행해도

 

max_connections 원래대로 복구

/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "SET GLOBAL max_connections = 151;"

4 장애(디스크 full)

 

디스크 여유 공간 확인

df -h /home1/irteam/mysql/data

 

결과: 여유 공간이 56G로 넉넉해서 전부 채우는 건 비효율적

 

MySQL 데이터 디렉토리를 별도 작은 파티션으로 마운트하는 대신, fallocate 파일을 만들어 공간을 채우기

  • 56G 중 50G는 실제 데이터 없이 공간만 점유하도록 해, 6G만 다 채워도 디스크 full이 일어나도록 설계함
  • MySQL 쓰기 흐름 (INSERT 실행 시): 클라이언트 → mysqld → InnoDB → t.ibd 파일에 데이터 기록 → binlog 파일에 변경 이력 기록
  • insert 명령  쓰이는 information_schema.tables MySQL 내장 가상 테이블로 항상 존재함. 테스트 목적으로 대량 행을 빠르게 생성할 자주 쓰임
# 1. 50G짜리 더미 파일 생성 (약 몇 초 소요)
fallocate -l 50G /home1/irteam/dummy_fill.img

# 2. 디스크 여유 공간 확인 (얼마 안 남았는지 확인)
df -h /home1/irteam/mysql/data

# 3. MySQL에서 쓰기 작업 유발 (binlog 쓰기 트리거)
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "CREATE DATABASE IF NOT EXISTS test_disk;
      USE test_disk;
      CREATE TABLE IF NOT EXISTS t (id INT AUTO_INCREMENT PRIMARY KEY, v VARCHAR(255));
      INSERT INTO t (v) SELECT REPEAT('x', 255) FROM information_schema.tables LIMIT 100;"

# 4. 로그 확인
tail -20 /home1/irteam/mysql/log/mysql.err

=> 디스크 full 연출은 실패

 

참고

df -h: 파일시스템 전체 여유 공간

du -sh: MySQL 데이터 디렉토리가 현재 차지하는 크기

MySQL 데이터를 꽉 채워 df -h Avail 용량 0으로 만들면 디스크 Full 장애 발생

 

 

시행착오 후 재시도

# 1. my.cnf에 O_DIRECT 추가 (캐시 우회 쓰기)
echo "innodb_flush_method=O_DIRECT" >> /home1/irteam/mysql/my.cnf

# 2. MySQL 재시작
kill $(cat /home1/irteam/mysql/run/mysql.pid)
sleep 3
nohup /home1/irteam/mysql/base/bin/mysqld_safe \
  --defaults-file=/home1/irteam/mysql/my.cnf > /dev/null 2>&1 &
sleep 5

# 3. 설정 확인
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "SHOW VARIABLES LIKE 'innodb_flush_method';"

# 4. 페이지 캐시 다시 비우기
sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

# 5. 대량 INSERT + 실시간 로그 모니터링 (별도 터미널에서)
tail -f /home1/irteam/mysql/log/mysql.err


# 별도 터미널에서 INSERT 실행
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "USE test_disk;
      INSERT INTO t (v) SELECT REPEAT('x', 255)
      FROM information_schema.tables a,
           information_schema.tables b,
           information_schema.tables c LIMIT 500000;"

=> 에러 메시지가 잘림 -> 디스크가  차서 로그 파일 자체도  쓰는 상황. 디스크 full 장애 연출 성공!

 

최종 확인

# 1. mysqld 프로세스 살아있는지 확인
ps aux | grep mysqld | grep -v grep

# 2. 로그 전체 마지막 부분
tail -10 /home1/irteam/mysql/log/mysql.err

# 3. dmesg에서 디스크 관련 에러 확인
sudo dmesg | tail -20

 

결론

항목 결과
디스크 Full 직전 증상 [MY-014084] redo log 병목  수집 가능
디스크 Full 직접 에러 [MY-000??] 로그가 잘려서 메시지 코드 확인 불가
로그 기록 자체 디스크 Full이면 로그도  

디스크 full이면 로그가 잘리는 상황이므로 로그 내용을 수집할  없음

 

원상 복구

# 1. 더미 파일 정리
rm -f /home1/irteam/dummy*.img

# 2. 디스크 상태 확인
df -h /home1/irteam/mysql/data

# 3. my.cnf에서 O_DIRECT 제거
sed -i '/innodb_flush_method/d' /home1/irteam/mysql/my.cnf

디스크 full 장애 상황도 수집하도록 스크립트에 반영

 

디스크 full이면 무조건 로그가 잘리나? -> 은빈 인턴님은 디스크 full 연출 시 로그가 잘리지 않았다고 함

스크립트 코드 구현은 일단 은빈 인턴님이 디스크 full 장애를 내고 기록된 로그를 바탕으로 진행함

디스크 full 로그 패턴 흐름

22:56:46  [MY-014084]  Threads are unable to reserve space in redo log
                       └─ 디스크 부족으로 redo log checkpoint 불가 (전조 증상)

22:56:47  [MY-013865]  Redo log writer is waiting for a new redo log file
                       └─ redo log 공간 부족 (전조 증상)

22:56:48  [MY-000035]  Disk is full writing './mysql-bin.000016'
                       (OS errno 28 - No space left on device).
                       Waiting for someone to free space... Retry in 60 secs.
                       └─ 디스크 Full 직접 감지. 60초마다 재시도하며 대기

22:59:44  [MY-010907]  Error writing file 'mysql-bin' (errno: 28)
                       └─ 60초 대기 후 재시도에서도 실패

22:59:44  [MY-011072]  Binary logging not possible.
                       'binlog_error_action' is set to 'ABORT_SERVER'.
                       Server is being stopped.
                       └─ binlog 쓰기 포기, ABORT_SERVER 발동

22:59:44  mysqld got signal 6
          handle_fatal_signal         ← [SEGFAULT] 감지 키워드
          exec_binlog_error_action_abort
                       └─ mysqld 스스로 SIGABRT 발생 후 강제 종료

22:59:50  mysqld_safe Number of processes running now: 0   ← [CRASH_DETECTED]
22:59:50  mysqld_safe mysqld restarted
22:59:50  [MY-010116]  starting as process ...
22:59:51  [MY-013577]  InnoDB initialization has ended
22:59:51  [MY-010229]  Starting XA crash recovery...
22:59:51  [MY-010232]  XA crash recovery finished.
22:59:51  [MY-010931]  ready for connections               ← 정상화 기준점

 


5 장애(segfault)

 

# 1. Segfault 연출 (SIGSEGV 전송)
kill -SIGSEGV $(cat /home1/irteam/mysql/run/mysql.pid)

# 2. mysqld_safe가 재시작할 때까지 대기 후 로그 확인
sleep 10 && tail -30 /home1/irteam/mysql/log/mysql.err

 

Segfault 로그 흐름 정리

08:05:43  Attempting backtrace. You can use the following information...
          stack_bottom = 0 thread_stack 0x100000
           #0 0x101ac96 _Z18print_fatal_signali ...
           #1 0x101ad54 handle_fatal_signal ...
           ...                                      ← 스택 트레이스 (여러 줄)
          The manual page at http://dev.mysql.com/...

08:05:43  mysqld_safe  Number of processes running now: 0  ← [CRASH_DETECTED]
08:05:43  mysqld_safe  mysqld restarted                    ← [SAFE_RESTARTED]
08:05:43  [MY-010116]  starting as process 2164903         ← [STARTING]
08:05:43  [MY-013576]  InnoDB initialization has started
08:05:44  [MY-013577]  InnoDB initialization has ended     ← [INNODB_READY]
08:05:44  [MY-010229]  Starting XA crash recovery...       ← [XA_RECOVERY]
08:05:44  [MY-010232]  XA crash recovery finished.         ← [XA_RECOVERY_END]
08:05:44  [MY-010931]  ready for connections               ← [READY] 정상화 기준점

=> Segfault 시 Aborting 메시지나 [SEGFAULT] 키워드가 error log에 찍히지 않음

스택 트레이스(Attempting backtrace)와 handle_fatal_signal이 Segfault의 실제 감지 키워드

 

스택 트레이스란?

서버가 예상치 못하게 종료(crash)되었을 에러 로그 파일에 기록되는 함수 호출 경로 정보(어떤 경로를 거쳐 호출됐는지, 어느 함수를 호출하는 도중에 오류가 발생했는지 파악할 수 있음)

 

스택 트레이스를 제외하면 kill -9와 로그 패턴이 동일하므로, 구현에 용이

항목 kill -9 SIGSEGV
스택 트레이스
Number of processes running now: 0
mysqld restarted
XA crash recovery
ready for connections

 

태그 감지 키워드 비고
[SEGFAULT] handle_fatal_signal 스택 트레이스 줄에 등장
[CRASH_DETECTED] mysqld_safe Number of processes running now: 0 Segfault/OOM/kill -9 공통

6 장애(복제 연결 단절 - 마스터 재시작)

 

ca801(마스터) 재시작 cb801(레플리카) 로그에 어떤 패턴이 찍히는지 확인

ca801에서
# 마스터 재시작
kill $(cat /home1/irteam/mysql/run/mysql.pid)
sleep 3
nohup /home1/irteam/mysql/base/bin/mysqld_safe \
  --defaults-file=/home1/irteam/mysql/my.cnf > /dev/null 2>&1 &

cb801에서
# 레플리카 로그 실시간 모니터링
tail -f /home1/irteam/mysql/log/mysql.err

 

로그 패턴 정리

08:05:43  [MY-010557]  Error reading packet from server: Lost connection
                       └─ 마스터가 갑자기 죽으면서 복제 연결 끊김 ← [CONN_LOST]

08:05:43  [MY-010897]  Storing MySQL user name... (Warning)
                       └─ 재연결 시도 전 경고, 노이즈 → 수집 불필요

08:05:43  [MY-010584]  Error reconnecting to source, attempt 1/86400
                       └─ 재연결 시도 중 ← [RECONNECTING] (첫/마지막만 표시)

08:06:43  [MY-010592]  connected to source, replication resumed
                       └─ 복제 재연결 완료 ← [CONNECTED] 정상화 기준점

08:06:43  [MY-014001]  connected to source, Starting replication from file
                       └─ 복제 스레드 시작 ← [REPL_START]

08:11:39  [MY-010558]  received end packet from server due to dump thread
                       being killed on source
                       └─ 마스터가 재시작되면서 dump thread가 종료됨
                          새로운 패턴(마스터 정상 종료 상황)이지만 마스터 비정상 종료 상황과 동일한 태그 사용 ← [CONN_LOST]

08:12:39  [MY-010592]  connected to source, replication resumed
                       └─ 복제 재연결 완료 ← [CONNECTED] 정상화 기준점

08:12:39  [MY-014001]  connected to source, Starting replication from file
                       └─ 복제 스레드 시작 ← [REPL_START]

7 장애(복제 연결 단절 - 네트워크 단절)

 

iptables ca801↔cb801 포트를 차단/해제하기

ca801에서
# cb801 IP 확인
echo "cb801 IP 확인"
grep replica /home1/irteam/mysql/my.cnf || echo "cb801주소"

cb801에서
# ca801 IP 확인 (로그에서 직접)
grep "connected to source" /home1/irteam/mysql/log/mysql.err | tail -1

cb801에서
로그 모니터링
tail -f /home1/irteam/mysql/log/mysql.err

ca801에서
# 1. 포트 차단
sudo iptables -I INPUT -s cb801주소 -p tcp --dport 13306 -j DROP
echo "차단 시작: $(date)"

# 2. 90초 대기 (replica_net_timeout 60초 + 여유 30초)
sleep 90

# 3. 차단 해제
sudo iptables -D INPUT -s cb801주소 -p tcp --dport 13306 -j DROP
echo "차단 해제: $(date)"

 

로그 패턴 분석

08:29:45  [MY-010897] Warning        ← 차단 후 60초 뒤 재연결 시도 (08:28:16 + 60초 = 08:29:16 근처)
08:30:05  connected to source        ← 차단 해제 후 재연결 성공

=> [CONN_LOST] 패턴이 없음

 

원인 추측

  • DROP은 패킷을 조용히 버리는 방식이라 TCP 연결이 즉시 끊기지 않고 타임아웃까지 기다림
  • 그 사이 replica_net_timeout(60초)이 지나면 레플리카가 스스로 재연결을 시도하는데, 이 경우 Lost connection 대신 Warning만 찍히고 넘어갈 수 있음

재시도(ca801에서)

# DROP 대신 REJECT 사용 (즉시 RST 패킷 전송)
sudo iptables -I INPUT -s cb801주소 -p tcp --dport 13306 -j REJECT
echo "차단 시작: $(date)"

sleep 90

sudo iptables -D INPUT -s cb801주소 -p tcp --dport 13306 -j REJECT
echo "차단 해제: $(date)"

 

로그 패턴 정리

08:32:15  iptables REJECT 차단 시작
          │
          │ (replica_net_timeout 60초 대기)
          │
08:33:35  [MY-010897] Warning            ← 재연결 시도 전 경고
08:33:35  [MY-010584] Error reconnecting ← 재연결 실패 (REJECT로 즉시 거부)
          │
          │ (60초 후 재시도)
          │
08:34:03  iptables REJECT 해제
08:34:35  [MY-010592] connected to source ← 재연결 성공
08:34:35  [MY-014001] Starting replication

=> 이번에도 [CONN_LOST] 로그는 찍힘

 

복제 구성 로그 패턴 정리:

상황 찍히는 패턴
마스터 비정상 종료(kill -9) [MY-010557] → [MY-010584] → [MY-010592]
마스터 정상 종료(SIGTERM) [MY-010558] → [MY-010584] → [MY-010592]
네트워크 차단(REJECT) [MY-010584] → [MY-010592]
네트워크 차단(DROP) Warning → [MY-010592]

[CONN_LOST] 감지 키워드

태그 감지 키워드 상황
[CONN_LOST] [MY-010557] 마스터 비정상 종료 / 네트워크 강제 단절
[CONN_LOST] [MY-010558] 마스터 정상 종료
[RECONNECTING] [MY-010584] 재연결 시도 (/마지막만 표시)
[CONNECTED] [MY-010592] 재연결 성공 정상화 기준점
[REPL_START] [MY-014001] 복제 스레드 시작

8번 장애(마스터-레플리카 간 데이터 정합성 장애)

 

레플리카에서 직접 데이터를 수정한 뒤 마스터에서 동일 row를 건드려 충돌 유발

cb801에서 실행 (복제 일시 중단 + 데이터 직접 수정)
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "STOP REPLICA SQL_THREAD;
      USE test_disk;
      INSERT INTO t VALUES (99999, 'replica_only_data');"

ca801에서 실행 (마스터에서 동일 pk insert)
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "USE test_disk;
      INSERT INTO t VALUES (99999, 'master_data');"

cb801에서 복제 재개 후 로그 확인
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "START REPLICA SQL_THREAD;"

sleep 3
tail -20 /home1/irteam/mysql/log/mysql.err

 

결과

cb801에서 INSERT INTO t VALUES (99999, 'replica_only_data')가 Duplicate entry 에러로 실패

=> 99999는 이미 존재

하지만 mysql.err 로그를 확인한 결과, 정합성 충돌은 error log 기록되지 않는 것이 확인됨

 

8번 장애는 스크립트에 반영하지 않음


9번 장애(레플리카의 디스크 Full 장애)

 

마스터의 데이터를 레플리카가 동기화하는 과정에서 레플리카의 디스크 용량을 부족하게 설정

터미널 1 - cb801에서 실행 (로그 모니터링):
tail -f /home1/irteam/mysql/log/mysql.err

터미널 2 - cb801에서 실행 (디스크 채우기):
fallocate -l 37G /home1/irteam/dummy.img && df -h /home1/irteam/mysql/data

터미널 3 - ca801에서 실행 (대량 INSERT로 복제 유발):
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "USE test_disk;
      INSERT INTO t (v) SELECT REPEAT('x', 255)
      FROM information_schema.tables a,
           information_schema.tables b,
           information_schema.tables c LIMIT 500000;"

 

결과

=> 새로운 로그가 확인됨. 레플리카(cb801) Avail 용량도 0임이 확인됨

 

로그 패턴 흐름 정리(레플리카(cb801) 기준)

02:21:45  [MY-014084]  redo log 공간 부족 (전조)

02:21:46  [MY-012144]  posix_fallocate() failed: No space left on device
                       └─ InnoDB가 t.ibd 파일 확장 시도 실패

02:21:46  [MY-012637]  일부만 기록됨 (880640/1048576 bytes)
02:21:46  [MY-012638]  재시도 실패
02:21:46  [MY-012639]  Write to file failed, OS errno 28
02:21:46  [MY-012640]  Error number 28 = 'No space left on device'
02:21:46  [MY-012145]  t.ibd 쓰기 실패

02:21:47  [MY-013132]  The table 't' is full!
02:21:47  [MY-010584]  Replica SQL Worker 1 failed
                       └─ 복제 SQL 스레드 중단
                          (이후 로그 잘림)

 

마스터 디스크 Full과의 차이:

항목 마스터 디스크 Full 레플리카 디스크 Full
핵심 키워드 [MY-000035], [MY-011072] [MY-012144], [MY-013132], [MY-010584]
mysqld 종료 여부 ✓ ABORT_SERVER 강제 종료 ✗ mysqld 살아있음
복제 중단 여부 ✓ (마스터 종료로 연결 끊김) ✓ SQL 스레드만 중단
자동 복구 mysqld_safe 재시작 디스크 확보 수동 START REPLICA SQL_THREAD 필요

 

복구 진행

# 1. 더미 파일 삭제로 공간 확보
rm /home1/irteam/dummy.img
df -h /home1/irteam/mysql/data

# 2. 복제 SQL 스레드 재시작
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "START REPLICA SQL_THREAD;"

# 3. 복제 상태 확인
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "SHOW REPLICA STATUS\G" | grep -E "Slave_SQL_Running|Seconds_Behind|Last_SQL_Error"

 

복구 로그 흐름 정리

cb801 로그 흐름:
02:21:46  [MY-012144]  posix_fallocate() failed: No space left on device
02:21:46  [MY-012639]  Write to file failed, errno 28
02:21:46  [MY-012640]  Error number 28 = 'No space left on device'
02:21:47  [MY-013132]  The table 't' is full!
02:21:47  [MY-010584]  Replica SQL Worker 1 failed  ← SQL 스레드 중단, 로그 잘림
          ※ 더미 파일 삭제 후 공간 확보
02:28:29  [MY-014084]  redo log 공간 부족 (복제 재개 후 밀린 데이터 처리 중)
02:29:11  [MY-010557]  Lost connection  ← ca801 redo log 병목으로 인한 마스터 재시작 또는 연결 끊김
02:29:11  [MY-014001]  connected to source, Starting replication  ← 복제 재연결

ca801 로그 흐름:
02:21:38  [MY-014084]  redo log 병목 (INSERT 처리 중)
02:22:06  [MY-014084]  redo log 병목 지속

=> ca801 mysqld 종료되지 않았고, INSERT 완료된 redo log 병목만 찍힘

 

레플리카 디스크 Full 패턴 확정:

키워드 의미
[MY-012144] InnoDB 파일 확장 실패 (No space left)
[MY-012639] 파일 쓰기 실패 (errno 28)
[MY-012640] errno 28 = No space left on device
[MY-013132] The table is full
[MY-010584] Replica SQL Worker 실패 → SQL 스레드 중단

9번 장애 재시도(레플리카의 디스크 Full 장애를 감지하기 위해)

ca801에서 실행 (대량 INSERT로 복제 유발):
/home1/irteam/mysql/base/bin/mysql \
  -S /home1/irteam/mysql/run/mysql.sock \
  -u root -p'비밀번호' \
  -e "USE test_disk;
      INSERT INTO t (v) SELECT REPEAT('x', 255)
      FROM information_schema.tables a,
           information_schema.tables b,
           information_schema.tables c LIMIT 500000;"

 

로그 패턴 정리

06:52:17  [MY-000035]  Disk is full writing './relay-bin.000043'
                       Waiting for someone to free space... Retry in 60 secs
07:02:17  [MY-000035]  (600초마다 반복 출력)
07:12:18  [MY-000035]  (반복)
07:22:18  [MY-000035]  (반복)
          ※ 공간 확보 시 자동 재개 (mysqld 종료 없음)

이전 레플리카 디스크 Full과 비교:

항목 InnoDB 파일 쓰기 실패 relay-bin 쓰기 실패
핵심 키워드 [MY-012144], [MY-013132] [MY-000035]
대상 파일 t.ibd (데이터 파일) relay-bin.xxxxx
mysqld 종료
복제 중단 SQL 스레드 즉시 중단 I/O 스레드 대기 (자동 재개 가능)
복구 방식 수동 START REPLICA SQL_THREAD 공간 확보 시 자동 재개

현재 스크립트는 relay-bin 쓰기 실패 로그 패턴에 대한 장애 감지가 안되는 상황

=> 코드 수정 진행

주요 수정 사항: 정상화 판단 기준(gap)을 12분으로 수정

이유: 디스크 full 에러 메시지([MY-000035])가 10분에 한번씩 출력되기 때문

 

레플리카 디스크 Full 장애 감지 완료