0. 인트로
일어나니 아침부터 서버가 뻗어 있습니다.
서버에 요청을 날려보니 504 에러가 응답했고 부랴부랴 AWS에 접속 해서 로그를 뒤져봤습니다.
response header를 읽는 중에 타임 아웃이 발생했다고 하네요.
response 데이터를 읽어드릴 때 버퍼 크기를 조정하면 해결 된다고 해서, 자세한 내용은 모르지만 엔진엑스 설정을 바꿔주었습니다. 하지만 결과는 달라지지 않았습니다.
1. 원인은 DB Lock
RDS에 접속 해서 활성 세션을 확인 해보니 아니나 다를까 DB가 잠긴 상태였습니다.
DB Lock을 해결하려면 가장 우선은 잠겨 있는 프로세스를 삭제 해주어야 합니다.
직접 CLI로 프로세스를 KILL 해주어도 되지만, DB 클라이언트 도구를 이용하면 더욱 간단합니다.
DBeaver에서는 해당 DB의 Administer 패키지에 락 매니저가 있습니다.
Lock에 대한 정보와 관계가 컬럼 형태와 그림으로 표시 되어 있습니다.
Lock을 풀기 위해서는 해당 Lock 컬럼을 오른쪽 마우스로 클릭해서 삭제 해주시면 됩니다.
2. 문제는 Root Cause
결국 Lock을 푸는 데서 그치는 게 아니라 원인을 찾고 재발하지 않도록 하는 것이 중요합니다.
RDS 콘솔에서 제공하는 쿼리를 확인해보니 단순한 조회 쿼리와 ALTER TABLE 쿼리가 CPU를 점유하고 있었는데요.
조회 쿼리를 뜯어봐도 트랜잭션이 대기 상태에 있을 만한 쿼리가 있지는 않아서 ALTER TABLE 쪽을 유심히 살펴봤습니다.
그리고 비슷한 상황으로 로컬에서 프로젝트를 구동해보니 원인을 파악할 수 있었습니다.
JPA의 ddl-auto 옵션이 update로 설정되어 있기 때문이었습니다.
domain entity의 수정과 추가 작업이 진행되었었고, ddl-auto 옵션이 update 였기 때문에 서버를 구동 시킬 때 기존 컬럼에서 새로운 컬럼을 추가하는 과정에서 constraint 를 위반해서 트랜잭션이 잠긴 것이었습니다.
근본적인 해결책은 ddl-auto 옵션을 제거하고 entity의 변경이 발생하는 경우에는 DB에 직접 접근해서 DDL 쿼리로 테이블을 조작해야 합니다.
하지만 아직 개발 단계고 변경이 활발하게 이루어지기 때문에 참조 관계가 걸린 entity를 작업할 때는 ddl-auto 옵션을 create로 설정하여 DB를 클리어해주는 것으로 규칙을 정하고 트러블 슈팅을 종료하였습니다.
'프로젝트' 카테고리의 다른 글
Github Actions + Docker Compose + Elastic Beanstalk (0) | 2022.07.21 |
---|---|
SpringBoot 전략패턴 + IF 분기 없애기 (0) | 2022.06.08 |
*.do 없애고 깔끔한 HTTP API 만들기 (2) | 2022.05.09 |
Spring - Jenkins - tomcat으로 이해하는 CI/CD (0) | 2022.04.07 |
댓글