가용성/2026년 10월 6일 10시 사고
10월 6일 10시 7분부터 10시 38분까지 로그인한 이용자와 캐시에 없는 문서를 연 이용자는 502나 503을 받았습니다. 캐시된 문서는 계속 열렸습니다. 보안 업데이트 목록을 보려고 데이터베이스 서버에서 돌린 dnf가 남은 메모리를 다 쓰자 서버가 디스크만 읽으며 멈췄고, 저절로 돌아오지 않아 10시 29분에 서버를 다시 시작했습니다. 데이터베이스 서버에 스왑이 없고 평소 남는 메모리가 100MB 안팎인 것은 아직 그대로입니다.
| 시각 (한국 시간) | 일어난 일 |
|---|---|
| 10:06 | 보안 업데이트 목록을 보려고 데이터베이스 서버(database-5)에 SSM으로 dnf updateinfo list --security --releasever=latest를 보냄. 같은 명령은 웹 서버에서 49초 만에 끝남
|
| 10:07 | 데이터베이스 서버의 루트 디스크 읽기가 gp3 처리량 상한인 초당 125MiB에 붙고, 데이터 디스크 읽기와 네트워크 수신은 거의 0이 됨 |
| 10:08 | 502와 503이 나가기 시작함 |
| 10:09 | 배포 뒤 점검을 하던 워커가 발견함 |
| 10:12 | dnf 명령을 취소했지만 서버에 닿지 않음 |
| 10:13 | 특수:빈문서 확인 경보가 울림. 페미위키:대문 확인은 끝까지 정상 |
| 10:29 | 데이터베이스 서버 재부팅을 요청함 |
| 10:33 | 정상 종료를 하지 못해 EC2가 강제로 다시 시작함. 10시 33분 55초부터 웹 서버의 상태 확인이 200을 받음 |
| 10:38 | 밀린 요청을 다 처리하고 마지막 5xx가 나감. 특수:빈문서 경보가 풀림 |
원인
데이터베이스 서버는 메모리가 1,847MiB인 t4g.small이고, 그 가운데 768MiB를 MariaDB의 버퍼 풀이 차지합니다.[1] 웹 서버에는 스왑 파일을 깔지만 데이터베이스 서버에는 깔지 않으므로,[2] 평소 남는 메모리는 100MB 안팎이었습니다.
--releasever=latest를 붙인 dnf는 Amazon Linux 2023 최신 저장소의 패키지 목록을 받아 메모리에 올립니다. 남은 메모리로는 모자라자 커널은 실행 중인 프로그램의 코드처럼 디스크에서 다시 읽을 수 있는 것을 메모리에서 내보냈고, 프로그램들은 돌 때마다 그것을 다시 읽어야 했습니다. 그래서 10시 7분부터 루트 디스크 읽기가 1분에 6만 5천 회, 초당 125MiB의 상한에 붙은 채 서버를 다시 시작할 때까지 내려오지 않았고, CPU는 그 읽기를 기다리느라 53%에 머물렀습니다. 커널 기록에는 OOM 킬러가 프로세스를 끝낸 흔적이 없습니다. 내보낼 수 있는 페이지가 남아 있는 동안 커널은 프로세스를 죽이지 않고 내보내고 다시 읽기를 되풀이합니다. dnf가 실제로 메모리를 얼마나 썼는지는 기록이 없어 모릅니다. 메모리 여유가 더 많고 스왑도 있는 웹 서버에서는 같은 명령이 49초 만에 끝났습니다.
MariaDB가 답하지 못하자 웹 서버의 php-fpm 워커 16개가 모두 데이터베이스를 기다리다 40초 제한에 잘렸고, PHP를 거치는 요청은 502나 503으로 끝났습니다. 캐시된 문서는 PHP를 거치지 않으므로 계속 열렸습니다. 트래픽은 늘지 않았습니다. 9시 38분의 이미지 배포는 웹 서버만 바꿨고 그 뒤 30분 동안 오류가 없었습니다.[3]
시각은 EC2와 EBS의 1분 단위 지표와 SSM 명령 기록에서 읽은 것입니다. 사고 중에는 SSM 에이전트의 마지막 응답이 10시 2분이라 dnf보다 먼저 멈춘 것으로 보았지만, 에이전트는 5분마다 응답하고 10시 6분의 dnf 명령은 받아서 실행을 시작했으며, 디스크 읽기도 10시 7분에야 뛰었습니다.
고친 것
- 데이터베이스 서버를 다시 시작해 메모리를 비웠습니다. 사고 뒤 남는 메모리는 1.3GB이지만 버퍼 풀이 차면 다시 100MB 안팎으로 돌아갑니다.
남은 문제
- 데이터베이스 서버에서 무거운 명령을 돌릴 여유가 없습니다. 웹 서버처럼 스왑 파일을 깔면 같은 일이 생겨도 멈추는 대신 느려지는 데서 그칠 수 있습니다. 버퍼 풀을 줄이거나 인스턴스를 키우는 방법도 있습니다.
- 보안 업데이트를 확인하는 방법이 필요합니다. 호스트에서 dnf를 돌리지 않고 확인하는 방법을 femiwiki#613에서 다룹니다.