Amazon RDS for MySQL 데이터베이스의 사용 가능 메모리 부족 문제를 해결하려면 어떻게 해야 하나요?

7분 분량
0

Amazon Relational Database Service(RDS) for MySQL 인스턴스를 실행했습니다. 사용 가능한 메모리가 부족하거나, 데이터베이스의 메모리가 부족하거나, 메모리 부족으로 인해 애플리케이션에서 지연 문제가 발생했습니다. 메모리 사용 소스를 파악하고 문제를 해결하고 싶습니다.

간략한 설명

Amazon RDS for MySQL에서는 네 가지 메모리 상태를 모니터링할 수 있습니다.

  • 활성: 데이터베이스 프로세스 또는 스레드에서 활발히 사용되고 있는 메모리입니다.
  • 버퍼: 버퍼는 데이터 블록을 보관하는 데 사용되는 메모리의 임시 공간입니다.
  • 사용 가능한 메모리: 사용 가능한 메모리입니다.
  • 캐시: 캐싱은 데이터를 빠르게 검색할 수 있도록 데이터를 메모리에 임시로 저장하는 기술입니다.

기본적으로 Amazon RDS for MySQL 인스턴스를 생성하면 데이터베이스 작업을 개선하기 위해 버퍼와 캐시가 할당됩니다. 또한 Amazon RDS for MySQL에는 특정 작업을 수행하기 위한 내부 임시 테이블을 생성하는 내부 메모리 구성 요소(예: key_buffers_size 또는 query_cache_size)가 있습니다.

Amazon RDS for MySQL을 사용할 때는 MySQL에서 메모리를 사용하고 할당하는 방식을 이해해야 합니다. 메모리를 사용하는 구성 요소를 식별한 후 인스턴스 및 데이터베이스 수준에서 병목 현상을 찾을 수 있습니다. 그런 다음 이러한 특정 지표를 모니터링하고 최적의 성능을 지원하도록 세션을 구성합니다.

해결 방법

MySQL이 메모리를 사용하는 방법

Amazon RDS for MySQL에서는 인스턴스에서 사용 가능한 메모리의 80~90%가 기본 파라미터와 함께 할당됩니다. 이러한 할당은 성능에 가장 적합하지만 메모리를 많이 사용하는 파라미터를 설정하는 경우 다른 파라미터에서 메모리를 적게 사용하도록 수정하여 이를 보완합니다.

RDS for MySQL DB 인스턴스의 대략적인 메모리 사용량을 다음과 같이 계산할 수 있습니다.

Maximum MySQL Memory Usage = innodb_buffer_pool_size + key_buffer_size + ((read_buffer_size + read_rnd_buffer_size + sort_buffer_size + join_buffer_size) X max_connections)

버퍼 풀

글로벌 버퍼 및 캐시에는 Innodb_buffer_pool_size, Innodb_log_buffer_size, key_buffer_size, query_cache_size와 같은 구성 요소가 포함됩니다. innodb_buffer_pool_size 파라미터는 innodb가 데이터베이스 테이블 및 인덱스 관련 데이터를 캐싱하는 RAM의 메모리 영역입니다. 버퍼 풀이 클수록 디스크로 다시 돌리는 I/O 작업이 덜 필요합니다. 기본적으로 innodb_buffer_pool_size는 Amazon RDS DB 인스턴스에 할당된 사용 가능한 메모리의 최대 75%를 사용합니다.

innodb_buffer_pool_size = {DBInstanceClassMemory*3/4}

먼저 이 파라미터를 검토하여 메모리 사용의 소스를 파악해야 합니다. 그런 다음 사용자 지정 파라미터 그룹의 파라미터 값을 수정하여 innodb_buffer_pool_size의 값을 줄이는 것을 고려해 보세요.

예를 들어 기본 DBInstanceClassMemory*3/4*5/8 또는 *1/2로 줄일 수 있습니다. 인스턴스의 BufferCacheHitRatio 값이 너무 낮지 않은지 확인합니다. BufferCacheHitRatio 값이 낮으면 더 많은 RAM을 위해 인스턴스 크기를 늘려야 할 수 있습니다. 자세한 내용은 Amazon RDS for MySQL의 파라미터 구성 모범 사례, 파트 1: 성능 관련 파라미터를 참조하세요.

MySQL 스레드

또한 MySQL DB 인스턴스에 연결된 각 MySQL 스레드에 메모리가 할당됩니다. 다음 스레드에는 메모리 할당이 필요합니다.

  • thread_stack
  • net_buffer_length
  • read_buffer_size
  • sort_buffer_size
  • join_buffer_size
  • max_heap_table_size
  • tmp_table_size

또한 MySQL은 일부 작업을 수행하기 위해 내부 임시 테이블을 생성합니다. 이러한 테이블은 처음에 메모리 기반 테이블로 생성됩니다. 테이블이 tmp_table_size 또는 max_heap_table_size(둘 중 낮은 값)로 지정된 크기에 도달하면 테이블이 디스크 기반 테이블로 변환됩니다. 여러 세션에서 내부 임시 테이블을 생성하면 메모리 사용률이 증가할 수 있습니다. 메모리 사용률을 줄이려면 쿼리에 임시 테이블을 사용하지 마세요.

참고: tmp_table_sizemax_heap_table_size 제한을 늘리면 더 큰 임시 테이블이 메모리에 있을 수 있습니다. 암시적 임시 테이블이 생성되었는지 확인하려면 created_tmp_tables 변수를 사용합니다. 이 변수에 대한 자세한 내용은 MySQL 웨사이트에서 created_tmp_tables을 참조하세요.

조인 및 정렬 작업

조인 또는 정렬 작업 중에 join_buffer_size 또는 sort_buffer_size 등과 동일한 유형의 여러 버퍼를 할당하면 메모리 사용량이 증가합니다. 예를 들어 MySQL은 두 테이블 간에 조인을 수행하기 위해 하나의 조인 버퍼를 할당합니다. 쿼리에 다중 테이블 조인이 포함되고 모든 쿼리에 조인 버퍼가 필요한 경우 MySQL은 전체 테이블 수보다 조인 버퍼를 하나 적게 할당합니다. 세션 변수를 너무 높은 값으로 구성하면 쿼리가 최적화되지 않은 경우 문제가 발생할 수 있습니다. join_buffer_size, join_buffer_size, sort_buffer_size와 같은 세션 수준 변수에 최소 메모리를 할당할 수 있습니다. 자세한 내용은 DB 파라미터 그룹 작업을 참조하세요.

MYISAM 테이블에 대량 삽입을 수행하는 경우 bulk_insert_buffer_size 바이트의 메모리가 사용됩니다. 자세한 내용은 MySQL 스토리지 엔진 사용 모범 사례를 참조하세요.

성능 스키마

Amazon RDS for MySQL에서 성능 인사이트를 위한 성능 스키마를 활성화한 경우 성능 스키마에서 메모리를 사용할 수 있습니다. 성능 스키마가 활성화되면 MySQL은 인스턴스가 시작될 때와 서버 작업 중에 내부 버퍼를 할당합니다. 성능 스키마가 메모리를 사용하는 방법에 대한 자세한 내용은 MySQL 웹 사이트의 성능 스키마 메모리 할당 모델을 참조하세요.

성능 스키마 테이블과 함께 MySQL sys 스키마도 사용할 수 있습니다. 예를 들어 performance_schema 이벤트를 사용하여 성능 스키마에서 사용하는 내부 버퍼에 할당된 메모리 양을 표시할 수 있습니다. 또는 다음과 같은 쿼리를 실행하여 할당된 메모리 양을 확인할 수 있습니다.

SELECT * FROM performance_schema.memory_summary_global_by_event_name WHERE EVENT_NAME LIKE 'memory/performance_schema/%';

메모리 계측 도구는 setup_instruments 테이블에 "memory/code_area/instrument_name" 형식으로 나열됩니다. 메모리 계측을 활성화하려면 setup_instruments 테이블에서 관련 계측 도구의 ENABLED 열을 업데이트하세요.

UPDATE performance_schema.setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'memory/%';

인스턴스의 메모리 사용량 모니터링

Amazon CloudWatch 지표

사용 가능한 메모리가 부족할 때 DatabaseConnections, CPUUtilization, ReadIOPS, WriteIOPS에 대한 Amazon CloudWatch 지표를 모니터링합니다.

DatabaseConnections의 경우 데이터베이스에 적용되는 각 연결에는 일정량의 메모리가 할당되어야 한다는 점에 유의하세요. 따라서 데이터베이스 연결이 급증하면 사용 가능한 메모리가 감소할 수 있습니다. Amazon RDS에서 max_connections에 대한 소프트 제한은 다음과 같이 계산됩니다.

{DBInstanceClassMemory/12582880}

Amazon CloudWatch에서 DatabaseConnections 지표를 확인하여 이 소프트 한도를 초과하고 있는지 모니터링합니다.

또한 FreeableMemory 외에도 SwapUsage에 대한 CloudWatch 지표를 모니터링하여 메모리 부족을 확인하세요. 대량의 스왑이 사용되고 FreeableMemory가 부족한 경우 인스턴스의 메모리 사용량이 많을 수 있습니다. 높은 메모리 압력은 데이터베이스 성능에 영향을 미칩니다. 메모리 압력 수준을 95% 미만으로 유지하는 것이 좋습니다. 자세한 내용은 메모리가 충분한데 Amazon RDS 인스턴스가 스왑 메모리를 사용하는 이유는 무엇인가요?를 참조하세요.

향상된 모니터링

DB 인스턴스의 리소스 사용률을 모니터링하려면 향상된 모니터링을 켭니다. 그런 다음 세분성을 1~5초(기본값은 60초)로 설정합니다. 향상된 모니터링을 사용하면 사용 가능한 메모리와 활성 메모리를 실시간으로 모니터링할 수 있습니다.

또한 DB 인스턴스의 스레드를 나열하여 최대 CPU 및 메모리를 소비하는 스레드를 모니터링할 수 있습니다.

mysql> select THREAD_ID, PROCESSLIST_ID, THREAD_OS_ID from performance_schema.threads;

그런 다음 thread_OS_ID를 thread_ID에 매핑합니다.

select p.* from information_schema.processlist p, performance_schema.threads t
where p.id=t.processlist_id and t.thread_os_id=<Thread ID from EM processlist>;

사용 가능 메모리 부족 문제 해결

사용 가능 메모리 부족 문제가 발생하는 경우 다음 문제 해결 팁을 고려하세요.

  • 쿼리를 실행하기에 충분한 리소스가 데이터베이스에 할당되어 있는지 확인합니다. Amazon RDS에서는 인스턴스 유형에 따라 할당되는 리소스의 양이 달라집니다. 또한 저장 프로시저와 같은 특정 쿼리는 실행 중에 메모리를 무제한으로 사용할 수 있습니다.
  • 큰 쿼리를 작은 쿼리로 나누면 오래 실행되는 트랜잭션을 피할 수 있습니다.
  • 데이터베이스의 모든 활성 연결 및 쿼리를 보려면 SHOW FULL PROCESSLIST 명령을 사용합니다. 조인 또는 정렬 작업이 포함된 장기 실행 쿼리를 관찰하는 경우 최적화 프로그램이 계획을 계산할 수 있을 만큼 RAM이 충분해야 합니다. 또한 임시 테이블이 필요한 쿼리를 식별한 경우 테이블에 할당할 추가 메모리가 있어야 합니다.
  • 장기 실행 트랜잭션, 메모리 사용률 통계, 잠금을 보려면 SHOW ENGINE INNODB STATUS 명령을 사용합니다. 출력을 검토하고 버퍼 풀 및 메모리 항목을 확인합니다. 버퍼 풀 및 메모리 항목은 InnoDB의 메모리 할당에 관한 정보(예: “할당된 총 메모리”, “내부 해시 테이블”, “버퍼 풀 크기”)를 제공합니다. 또한 InnoDB Status는 또한 래치, 잠금 및 교착 상태에 관한 추가 정보를 제공하는 데 도움이 됩니다.
  • 워크로드에 교착 상태가 자주 발생하는 경우 사용자 지정 파라미터 그룹에서 innodb_lock_wait_timeout 파라미터를 수정합니다. InnoDB는 innodb_lock_wait_timeout 설정을 사용하여 교착 상태가 발생하면 트랜잭션을 롤백합니다.
  • 데이터베이스 성능을 최적화하려면 쿼리를 적절하게 조정해야 합니다. 그렇지 않으면 성능 문제가 발생하고 대기 시간이 길어질 수 있습니다.
  • Amazon RDS 성능 개선 도우미를 사용하면 DB 인스턴스를 모니터링하고 문제가 있는 쿼리를 식별하는 데 도움이 됩니다.
  • CPU 사용률, IOPS, 메모리 및 스왑 사용량과 같은 Amazon CloudWatch 지표를 모니터링하여 인스턴스가 병목 현상을 일으키지 않게 합니다.
  • 사용 가능한 메모리가 95%에 도달하면 알림을 받을 수 있도록 FreeableMemory 지표에 CloudWatch 경보를 설정합니다. 인스턴스 메모리의 5% 이상을 비워 두는 것이 좋습니다.
  • 인스턴스를 MySQL의 최신 마이너 버전으로 정기적으로 업그레이드하세요. 이전 마이너 버전에는 메모리 누수 관련 버그가 있을 가능성이 높습니다.

관련 정보

Amazon RDS 모니터링 개요

메모리가 충분한데 Amazon RDS DB 인스턴스가 스왑 메모리를 사용하는 이유는 무엇인가요?