급하게 요구사항이 변경되었고 개발일정을 넉넉하게 말씀드렸다
요구사항이 변경됨에 따라 ALTER TABLE을 할 일이 생겨서 기능 구현을 어느정도 끝마치고 RDS에 ALTER TABLE을 했는데 무슨 해당 쿼리가 끝나지 않고 계속 돌아가는 것이였다
근데 또 DML작업은 가능한데 DDL작업만 안된다.... 사실 해당 테이블에 데이터가 아예 없어서 DROP하고 다시 만들생각도 했었는데 그것도 안됬다...
여러가지 문제가 있을 수 있지만 알아본 결과
1. 대용량 데이터라서 시간이 오래걸릴 수 있다 -> 대용량 데이터도 아닐 뿐더러 얼마나 돌아가는지 봤는데 5분을 넘겼다
2. 테이블 메타데이터 락으로 다른 세션이 사용중이라 안될 수 있다 -> 그럴싸하다
3. 서버 부하 -> 새벽 4시고 하고 지금은 광고를 끈 상태라서 부하가 심하지 않다
4. 하드웨어 문제 -> 다른 테이블은 잘만 된다
5. 다른 트랜잭션이 제대로 종료되지 않아서 -> 그럴싸하다
그래서 2번과 5번을 위주로 알아보기로 하고 2번부터 보면
SHOW PROCESSLIST;
명령어를 사용하여 출력의 State열이 "Waiting for table metadata lock" 과 같은 메시지를 보여주면 나의 프로세스가 락 떄문에 대기 중인지 알 수 있다
하지만 그런 프로세스는 없었다....
5번으로 넘어가 보면
SELECT *
FROM information_schema.innodb_trx;
해당 명령어로 trx_state 칼럼을 확인하여 트랜잭션이 "RUNNING" 상태인지 혹은 "LOCK WAIT" 상태인지 확인할 수 있다
결과
304044843212120|RUNNING|....생략|REPEATABLE READ|....생략|
찾았다....
이제 여기서 trx_mysql_thread_id 칼럼에 있는 id를 기반으로
KILL [id];
해주면 된다 하지만 이 방법은 돌아가고 있는 트랜잭션의 변경사항이 전부 롤백되기 때문에 예상치 못한 부작용이 발생할 수 있다
해당 트랜잭션을 강제 종료하니까 잘 된다....
데이터 변경하는 트랜잭션이 종료되지 않은 이유는 여러가지가 있을 수 있다
이정도 인거 같다
확인 결과 해당 테이블에 트랜잭션을 거는 api가 단하나 있었는데 해당 api가 디비에 저장하고 알림톡을 보내는 과정에서 트랜잭션 경계를 명확하게 하지 않아서 발생한 이슈였다
트랜잭션 처리가 명확한 코드를 작성해야겠다