카테고리 없음

[우당탕탕 AWS] 느린 녀석은 필요없어 : RDS Slow Query Logging Setting

ooin 2024. 10. 18. 22:26
반응형

이번 글에서는 AWS RDS 에서 Slow Query 를 로깅하도록 설정하는 방법과 로깅된 쿼리를 확인하는 방법을 정리합니다.

Slow Query?

데이터베이스에서 실행 시간이 비정상적으로 오래 걸리는 쿼리를 말합니다. 이러한 쿼리는 데이터베이스 성능을 저하시키고 나아가 서비스의 품질을 떨어뜨리기 때문에 이를 식별하고 최적화를 진행하여야합니다.

 

Why?

Slow Query 가 발생하는 원인은 아래와 같이 나누어 볼수 있습니다.

  • 비효율적인 쿼리 구조
SQL 쿼리가 복잡하거나 비효율적으로 작성된 경우, 데이터 검색에 시간이 오래 걸릴 수 있습니다.
  • 인덱스 부족 또는 비효율적인 사용
데이터베이스에 적절한 인덱스가 없거나 잘못된 인덱스가 사용되면, 쿼리 처리 속도가 느려질 수 있습니다.
  • 대용량 데이터 처리
데이터 양이 매우 많을 때 쿼리가 느려질 수 있습니다. 특히 전체 테이블 스캔을 수행하는 쿼리는 시간이 오래 걸립니다.
  • 잠금(Locking) 문제
쿼리가 실행되는 동안 다른 트랜잭션이 테이블이나 행을 잠글 때, 경합으로 인해 느려질 수 있습니다.
  • 잘못된 조인 사용
여러 테이블을 잘못된 방식으로 조인하거나, 불필요한 조인이 포함된 쿼리는 성능을 저하시킬 수 있습니다.

 

 

How?

그럼 어떻게 DB 에서 Slow Query 를 로깅할 수 있을까요?

 

저의 경우에는 AWS RDS 를 사용하고 있어, RDS Slow Query Logging 을 셋팅하였습니다.

 

진행순서

순서는 간략히 보면 아래와 같습니다.

(파라미터 그룹이 없다면) RDS 파라미터 그룹 생성 -> 파라미터 그룹 수정 -> slow query 관련 파라미터 설정 -> 수정 완료 

 

 

AWS RDS
우측의 파라미터 그룹 탭으로 이동


Slow Query 로그 파라미터 설정:

  • 파라미터 그룹을 선택하고, 파라미터 편집(Edit Parameters)을 클릭합니다.

기존에 있던 파라미터 그룹 선택 후 작업 > 편집 진행

 

  • 다음 파라미터를 수정합니다

 

 

  • slow_query_log: 1로 설정하여 슬로우 쿼리 로그를 활성화합니다.

  • long_query_time: 로깅할 슬로우 쿼리의 기준 시간을 설정합니다 (예: 1초). 이보다 오래 걸리는 쿼리가 슬로우 쿼리로 로깅됩니다.

  • log_output: TABLE 또는 FILE로 설정합니다. TABLE로 설정하면 RDS에서 mysql.slow_log 테이블에 저장되고, FILE로 설정하면 로그 파일로 저장됩니다.

추가적으로, 인덱스를 사용하지 않는 쿼리도 로깅을 원한다면

  • log_queries_not_using_indexes: 1로 설정하면 인덱스를 사용하지 않는 쿼리도 로깅됩니다.

 

위와 같이 설정해준 후에 '변경사항 저장' 을 클릭하여 변경사항을 저장합니다.

 

위와 같이 수정완료 메시지를 확인하면 slow query logging 셋팅을 완료한 것 입니다.


이제 로깅되는 slow query 를 조회해보도록 하겠습니다.

 

저의 경우에는 다행히도 서비스상에서 사용하는 쿼리중에는 슬로우 쿼리가 존재하지 않았습니다.

따라서 로깅이 제대로 되는지 확인하기 위해 실행시간이 1초이상 걸릴법한 쿼리를 호출 후 테이블에 저장된 쿼리로그를 조회해 보았습니다.

로그 조회 쿼리

  • 쿼리 로그 중 1초 이상 소요된 쿼리를 조회하는 쿼리
SELECT * FROM mysql.slow_log where query_time > 1 ORDER BY query_time desc, start_time DESC LIMIT 1000;

 

 

user_host, db 등의 컬럼은 제외하였습니다.

 

위 이미지와 같이 정상적으로 1초 이상 소요된 쿼리는 테이블에 로깅된 것을 확인할 수 있었습니다.

 

컬럼 설명

  1. lock_time: 쿼리가 데이터를 잠그는 데 소요된 시간(초)입니다. 테이블 또는 행이 잠긴 동안 다른 쿼리가 이를 기다려야 하므로, 높은 lock_time은 성능 저하를 유발할 수 있습니다.
  2. rows_sent: 쿼리 결과로 클라이언트에 전송된 행의 수입니다. 이 값이 클 경우, 많은 데이터를 전송해야 하므로 쿼리의 응답 시간이 길어질 수 있습니다.
  3. rows_examined: 쿼리를 처리하기 위해 스캔한 총 행 수입니다. rows_examined이 많다는 것은 테이블의 많은 행을 탐색했음을 의미하며, 이는 쿼리의 비효율성을 나타낼 수 있습니다.
  4. last_insert_id: 이 값은 AUTO_INCREMENT 컬럼이 있는 테이블에 대해 INSERT 문이 실행된 후, 마지막으로 생성된 AUTO_INCREMENT 값입니다. 슬로우 쿼리 분석에는 직접적인 영향이 없으나, 테이블에 대한 잠금 문제가 발생할 수 있습니다.
  5. server_id: 쿼리가 실행된 서버의 ID입니다. 레플리케이션 환경에서 어떤 서버에서 실행되었는지 확인하는 데 유용합니다.
  6. thread_id: 쿼리를 실행한 스레드 ID입니다. 특정 스레드와 관련된 문제를 진단하는 데 사용할 수 있습니다.
  7. rows_affected: 쿼리에 의해 변경된 행 수입니다. UPDATE, DELETE와 같은 쿼리에서 얼마나 많은 데이터가 수정되었는지를 나타냅니다.

결론

다행히도 슬로우 쿼리가 발생하지 않아 쿼리를 최적화하는 작업은 진행하지 않았지만, 추가적인 개발이나 수정등의 작업 그리고 주기적으로 슬로우 쿼리를 확인하여 서비스의 품질을 유지하도록 해야겠습니다.

 

반응형