Amazon RDS for MySQL 인스턴스에서 높은 CPU 사용률 문제는 어떻게 해결합니까?

최종 업데이트 날짜: 2022년 2월 11일

Amazon Relational Database Service(Amazon RDS) for MySQL DB 인스턴스의 CPU 사용률이 높습니다. 높은 CPU 사용률 문제를 해결하려면 어떻게 해야 합니까?

간략한 설명

CPU 사용률의 증가는 사용자가 시작한 많은 워크로드, 여러 동시 쿼리 또는 장기 실행 트랜잭션과 같은 여러 요인으로 인해 발생할 수 있습니다.

Amazon RDS for MySQL 인스턴스의 CPU 사용량 소스를 확인하려면 다음과 같은 접근 방식을 검토하세요.

  • 향상된 모니터링
  • 성능 개선 도우미
  • 워크로드에서 CPU 사용률의 원인을 탐지하는 쿼리
  • 모니터링이 활성화된 로그

소스를 식별한 후 워크로드를 분석하고 최적화하여 CPU 사용량을 줄일 수 있습니다.

해결 방법

향상된 모니터링 사용

Enhanced Monitoring의 운영 체제(OS) 프로세스 목록 섹션에서 OS 프로세스RDS 프로세스를 검토합니다. mysqld 또는 Aurora 프로세스의 CPU 사용률을 확인합니다. 이러한 지표를 사용하면 CPU 사용률 증가가 OS 또는 RDS 프로세스로 인해 발생했는지 확인할 수 있습니다. 또는 이러한 지표를 사용하여 mysqld 또는 Aurora로 인한 CPU 사용량 증가를 모니터링할 수 있습니다. cpuUtilization에 대한 지표를 검토하여 CPU 사용률 분기점을 확인할 수도 있습니다. 자세한 내용은 Enhanced Monitoring을 사용하여 OS 지표 모니터링을 참조하세요.

참고: 성능 스키마를 활성화하면 OS 스레드 ID를 데이터베이스의 프로세스 ID에 매핑할 수 있습니다. 자세한 내용은 충분한 메모리가 있는데도 Amazon RDS DB 인스턴스가 스왑 메모리를 사용하는 이유는 무엇입니까?를 참조하세요.

성능 개선 도우미 사용

성능 개선 도우미를 사용하여 인스턴스에서 실행 중이며 CPU 사용량을 높이는 쿼리를 정확히 식별할 수 있습니다. 먼저 MySQL에 대한 성능 개선 도우미를 활성화합니다. 그런 다음, 성능 개선 도우미를 사용하여 워크로드를 최적화할 수 있습니다. 반드시 DBA와 상의하세요.

성능 개선 도우미와 함께 사용할 수 있는 데이터베이스 엔진을 확인하려면 Amazon RDS의 성능 개선 도우미로 DB 부하 모니터링을 참조하세요.

쿼리를 사용하여 워크로드에서 CPU 사용률의 원인 탐지

워크로드를 최적화하기 전에 문제가 있는 쿼리를 식별해야 합니다. 높은 CPU 문제가 발생하는 동안 다음 쿼리를 실행하여 CPU 사용률의 근본 원인을 파악할 수 있습니다. 그런 다음, 워크로드를 최적화하여 CPU 사용량을 줄입니다.

SHOW PROCESSLIST 명령은 현재 MySQL 인스턴스에서 실행 중인 스레드를 보여줍니다. 경우에 따라 동일한 명령문 집합이 완료 없이 계속 실행될 수 있습니다. 이 경우 후속 명령문은 첫 번째 명령문 집합이 완료될 때까지 기다려야 합니다. 이는 InnoDB 행 수준 잠금이 동일한 행을 업데이트하고 있기 때문입니다. 자세한 내용은 MySQL 웹 사이트에서 SHOW PROCESSLIST 문을 참조하세요.

SHOW FULL PROCESSLIST;

참고: SHOW PROCESSLIST 쿼리는 마스터 사용자로 실행하세요. 마스터 사용자가 아닌 경우, MySQL 인스턴스에서 실행 중인 모든 스레드를 보려면 MySQL PROCESS 서버 관리 권한이 있어야 합니다. 관리자 권한이 없으면 SHOW PROCESSLIST는 사용 중인 MySQL 계정에 연결된 스레드만 표시합니다.

INNODB_TRX 테이블은 읽기 전용 트랜잭션이 아닌 현재 실행 중인 모든 InnoDB 트랜잭션에 대한 정보를 제공합니다.

SELECT * FROM INFORMATION_SCHEMA.INNODB_TRX;

INNODB_LOCKS 테이블은 InnoDB 트랜잭션이 요청했지만 아직 받지 못한 잠금에 대한 정보를 제공합니다.

MySQL 5.7 또는 이전 버전의 경우:

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;

MySQL 8.0의 경우:

SELECT * FROM performance_schema.data_lock;

INNODB_LOCK_WAITS 테이블은 차단된 각 InnoDB 트랜잭션에 대해 하나 이상의 행을 제공합니다.

MySQL 5.7 또는 이전 버전의 경우:

SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;

MySQL 8.0의 경우:

SELECT * FROM performance_schema.data_lock_waits;

다음과 유사한 쿼리를 실행해 대기 중인 트랜잭션과 대기 중인 트랜잭션을 차단하는 트랜잭션을 확인할 수 있습니다. 자세한 내용은 MySQL 웹 사이트에서 InnoDB 트랜잭션 및 잠금 정보 사용을 참조하세요.

MySQL 5.7 또는 이전 버전의 경우:

SELECT
  r.trx_id waiting_trx_id,
  r.trx_mysql_thread_id waiting_thread,
  r.trx_query waiting_query,
  b.trx_id blocking_trx_id,
  b.trx_mysql_thread_id blocking_thread,
  b.trx_query blocking_query
FROM       information_schema.innodb_lock_waits w
INNER JOIN information_schema.innodb_trx b
  ON b.trx_id = w.blocking_trx_id
INNER JOIN information_schema.innodb_trx r
  ON r.trx_id = w.requesting_trx_id;

MySQL 8.0의 경우:

SELECT
  r.trx_id waiting_trx_id,
  r.trx_mysql_thread_id waiting_thread,
  r.trx_query waiting_query,
  b.trx_id blocking_trx_id,
  b.trx_mysql_thread_id blocking_thread,
  b.trx_query blocking_query
FROM       performance_schema.data_lock_waits w
INNER JOIN information_schema.innodb_trx b
  ON b.trx_id = w.blocking_engine_transaction_id
INNER JOIN information_schema.innodb_trx r
  ON r.trx_id = w.requesting_engine_transaction_id;

SHOW ENGINE INNODB STATUS 쿼리는 표준 InnoDB 모니터로부터 InnoDB 스토리지 엔진의 상태에 관한 정보를 제공합니다. 자세한 내용은 MySQL 웹 사이트에서 SHOW ENGINE 문을 참조하세요.

SHOW ENGINE INNODB STATUS;

SHOW [GLOBAL | SESSION] STATUS는 서버 상태에 대한 정보를 제공합니다. 자세한 내용은 MySQL 웹 사이트에서 SHOW STATUS 문을 참조하세요.

SHOW GLOBAL STATUS;

참고: 이러한 쿼리는 Aurora 2.x(MySQL 5.7), Aurora 1.x(MySQL 5.6), MariaDB 10.x에서 테스트되었습니다. 또한, INFORMATION_SCHEMA.INNODB_LOCKS 테이블은 MySQL 5.7.14부터 더 이상 지원되지 않으며 MySQL 8.0에서 제거됩니다. performance_schema.data_locks 테이블은 INFORMATION_SCHEMA.INNODB_LOCKS 테이블을 대체합니다. 자세한 내용은 MySQL 웹 사이트의 data_locks 테이블을 참조하세요.

로그 분석 및 모니터링 활성화

로그를 분석하거나 Amazon RDS for MySQL에서 모니터링을 활성화하려는 경우 다음 방법을 고려하세요.

  • MySQL General Query Log를 분석하여 특정 시간에 mysqld가 무엇을 하는지 볼 수 있습니다. 클라이언트가 연결 또는 연결 해제되는 시점에 대한 정보를 포함하여 특정 시간에 인스턴스에서 실행 중인 쿼리를 볼 수도 있습니다. 자세한 내용은 MySQL 웹 사이트에서 General Query Log를 참조하세요.
    참조: General Query Log를 장시간 활성화하면 로그가 스토리지를 소비하고 성능 오버헤드를 추가할 수 있습니다.
  • MySQL Slow Query Log를 분석하여 long_query_time에 설정된 초보다 실행 시간이 오래 걸리는 쿼리를 찾습니다. 또한 워크로드를 검토하고 쿼리를 분석하여 성능과 메모리 소비를 향상시킬 수 있습니다. 자세한 내용은 MySQL 웹 사이트에서 Slow Query Log를 참조하세요. 팁: Slow Query Log 또는 General Query Log를 사용할 때 log_output 파라미터를 FILE로 설정하세요.
  • MariaDB 감사 플러그 인을 사용하여 데이터베이스 활동을 감사합니다. 예를 들어 데이터베이스에 로그온하는 사용자나 데이터베이스에 대해 실행되는 쿼리를 추적할 수 있습니다. 자세한 내용은 MariaDB 감사 플러그 인 지원을 참조하세요.
  • Aurora for MySQL을 사용하는 경우 고급 감사를 사용할 수도 있습니다. 감사를 통해 로그할 쿼리 유형을 보다 효과적으로 제어할 수 있습니다. 이렇게 하면 로깅 오버헤드가 줄어듭니다.
  • innodb_print_all_deadlocks 파라미터를 사용하여 교착 상태 및 리소스 잠금을 확인합니다. 이 파라미터를 사용하여 InnoDB 사용자 트랜잭션의 교착 상태에 대한 정보를 MySQL 오류 로그에 기록할 수 있습니다. 자세한 내용은 MySQL 웹 사이트에서 innodb_print_all_deadlocks를 참조하세요.

높은 CPU 워크로드 분석 및 최적화

CPU 사용량을 증가시키는 쿼리를 확인한 후에는 CPU 소비를 줄이기 위해 워크로드를 최적화합니다.

워크로드에 필요하지 않은 쿼리가 표시되면 다음 명령을 사용하여 연결을 종료할 수 있습니다.

CALL mysql.rds_kill(processID);

쿼리의 processID를 찾으려면 SHOW FULL PROCESSLIST 명령을 실행합니다.

쿼리를 종료하지 않으려면 EXPLAIN을 사용하여 쿼리를 최적화합니다. EXPLAIN 명령은 쿼리 실행과 관련된 개별 단계를 보여줍니다. 자세한 내용은 MySQL 웹 사이트에서 EXPLAIN을 사용한 쿼리 최적화를 참조하세요.

프로필 세부 정보를 검토하려면 PROFILING을 활성화합니다. PROFILING 명령은 현재 세션에서 실행 중인 명령문에 대한 리소스 사용량을 나타낼 수 있습니다. 자세한 정보는 MySQL 웹 사이트에서 SHOW PROFILE 명령문을 참조하세요.

테이블 통계를 업데이트하려면 ANALYZE TABLE을 사용합니다. ANALYZE TABLE 명령은 옵티마이저가 쿼리를 실행할 적절한 계획을 선택하도록 도와줍니다. 자세한 내용은 MySQL 웹 사이트에서 ANALYZE TABLE 문을 참조하세요.