MySQL Full Scan으로 DB가 터짐

shleecloud·2023년 7월 2일
0

들어가며

장애를 처리하는 경험은 중요하다. 하지만 되도록 겪고 싶지 않다. 돌아보면 좋은 경험이지만 그 당시엔 서비스가 말 그대로 망할 수도 있는 위험이다. 시스템 엔지니어 생활로 수많은 장애 상황을 경험하고 극복했지만 장애가 발생한 당시 쏟아지는 문의전화는 섬뜩하다.

원인은 쿼리 Full Scan

사용자가 많지 않은 서비스지만 44만줄 Full Scan을 클라이언트 여러곳에서 찌르니 DB가 골로 가는건 어쩌면 당연한게 아닐까.

평소에 잘 동작하니 인덱스를 당연히 타고 있을 줄 알았다.하지만 Legacy 코드를 보니 Range 설정 없이 태초부터 지금까지 스캔을 하면서 문자열이 일치하는지 비교하고 있었다.

사실 예방할 수는 있었다. 지금 돌아보면 Elastic에서 특정 쿼리가 처리속도가 엄청 느리다고 알려주고 있었는데.. 별 일 없겠지~ 하다가 순식간에 가버렸다.

현상

처음 장애를 인지했을 때는 서버를 봤다. DB를 타지 않는 요청은 정상적으로 처리하고 있었다. 혹시 몰라서 재배포해도 그대로였다.

DB 스텟을 확인해보니 CPU가 치솟았다. 완만하게 우상향이 아니라 절벽으로 치솟는다. (내 주식도 저렇게 올랐으면..)

그 이후로 쿼리 해소가 안되니 Pool does not exist 에러가 뜨기 시작한다. 다행히 Write DB는 멀쩡했다. 우선 복구부터!

조치

Read DB 재시작하여 빠르게 복구했다. 이후 성능 업그레이드를 하고 쿼리를 조정했다. 조정됐는지 여부를 보려고 Explain 명령어를 활용했다. 범위를 지정하고 다시돌려보니 쿼리 코스트가 9509.5 점으로 개선됐다.

마치며

DB 장애는 순식간에 가는구나. 그래서 Slow Query 알럿이 있는게 아닐까. 미리 예방하려면 단순 CPU 수치도 중요하지만 DB를 괴롭히는 쿼리를 미리 예방하는 작업도 중요하다. DB 성능 최적화에 대해서 고민하게 됐다.

https://dev.mysql.com/doc/refman/8.0/en/using-explain.html
https://www.infoworld.com/article/3234637/7-keys-to-better-mysql-performance.html

profile
블로그 옮겼습니다. https://shlee.cloud

0개의 댓글