장애 기록을 정리하다가 같은 원인이 네 번 있는 것을 발견했다. 주문 목록과 상품 검색과 정산 조회와 통계 조회가 각각 느려진 건이라 증상은 전부 달라 보였다.
Table of contents
Open Table of contents
네 번의 같은 원인
원인을 나란히 놓고 보니 전부 인덱스 없이 대량 테이블을 조회한 것이었다. 매번 그 쿼리에 인덱스를 걸어 해결했고 네 번 다 그렇게 끝냈다.
왜 반복되는지를 보니 흐름이 같았다. 새 기능을 만들 때 인덱스를 안 걸고 개발 환경에는 자료가 적어 안 느리다가 운영에서 자료가 쌓이면 느려진다. 한 건씩 고치는 방식으로는 그 흐름이 없어지지 않았다.
앞에서 막는 장치
그래서 뒤에서 고치는 대신 앞에서 걸리게 했다. 개발과 시험 환경에서 느린 쿼리를 로그로 남기게 했는데 자료가 적어 안 걸리므로 시험 환경에 운영과 비슷한 양을 넣었다.
주문 100만 건 규모를 넣으니 느린 쿼리가 드러났다. 여기에 주요 조회의 실행 계획을 확인하는 시험을 더해 전체 스캔이면 실패하게 하고 새 쿼리를 추가할 때 그 목록에 넣도록 했다.
네 기록의 통합
흩어진 네 기록을 하나로 합치고 발생 시점과 원인과 대책을 한자리에 적었다. 마지막 줄에 대책 이후 재발 여부를 두고 계속 갱신했다.
재발 여부를 적어 두는 것이 대책의 성패를 재는 유일한 지표였다. 또 나면 대책이 부족한 것이므로 그 줄이 비어 있으면 아직 판정이 안 된 상태다.
모아 보기 위한 형식
같은 방식으로 다른 반복 결함도 찾으려니 형식이 걸렸다. 원인이 인덱스가 없어서라거나 인덱스 미설정이라거나 쿼리가 인덱스를 안 탄다고 제각각 적혀 있어서 같은 것인데 안 모였다.
원인을 목록에서 고르게 하고 상세는 따로 적게 바꿨다. 그러고 나서 모아 세니 인덱스 없는 대량 조회 넷과 외부 호출 시간 초과 미설정 셋과 설정 반영 안 됨 셋과 권한 확인 누락 둘이 나왔다. 한 건씩 보면 안 보이고 모아 보니 보였는데 그 전에는 형식이 달라 모을 생각조차 못 했다.
대책이 도는지 확인
대책을 세우고 끝내지 않고 셋을 각각 확인했다. 시험 환경 자료는 넣었고 실행 계획 시험은 빌드에서 돌고 있었다.
절차가 지켜지는지가 애매해서 새 조회가 추가된 커밋에 실행 계획 시험도 같이 추가됐는지를 이력에서 셌다. 추가된 것이 있어서 지켜지고 있다고 판정했다. 절차를 적었다는 것과 절차가 돈다는 것은 다르므로 후자는 따로 재야 한다.
정리
- 같은 결함이 여러 번 기록됐다면 아직 안 고친 것이다
- 증상이 달라 보여도 원인이 같을 수 있다
- 한 건씩 고치면 원인이 안 없어진다
- 앞에서 막으려면 개발과 시험 환경을 운영과 비슷하게 만든다
- 확인하는 시험을 두고 새것을 추가할 때 같이 넣게 한다
- 여러 기록을 합치고 대책과 재발 여부를 적는다
- 모아 세려면 원인 기록 형식이 같아야 한다
- 절차를 적었다는 것과 절차가 돈다는 것은 다르다