MySQL 메모리 영역
메모리 영역은 글로벌 메모리 영역과 로컬 메모리 영역으로 나뉜다.
글로벌 메모리 영역
글로벌 메모리는 클라이언트 스레드의 수와 무관하게 하나의 메모리 공간만 할당된다.
필요에 따라 2개 이상 할당받을 수도 있지만, 클라이언트 수와는 전혀 무관하다.
생성된 모든 글로벌 메모리는 모든 스레드에 의해 공유가 된다.
대표적인 글로벌 메모리 영역은 아래와 같다.
- Inno DB 버퍼 풀
- Inno DB Change 버퍼 : InnoDB 스토리지 인덱스 페이지의 변경을 메모리에 저장하고 flush하여 디스크에 저장하도록 만드는 기능
- Inno DB 로그 버퍼 : 트랜잭션의 변경사항을 임시로 저장하는 역할
- MyISAM 키 캐시 : MyISAM 스토리지에서 사용되는 메모리 버퍼로 인덱스를 디스크에서 메모리로 로드하여 캐싱하는 기술
- 테이블 캐시 : 테이블의 메타데이터와 데이터 블록을 메모리에 보관하는 메모리 영역
글로벌 메모리 영역은 데이터베이스 서버가 실행되는 동안 계속해서 메모리를 점유한다.
이 영역에 할당된 메모리는 데이터베이스 서버의 전반적인 동작에 사용되며, 일반적으로 임시적으로 할당되는 것이 아니라 영구적으로 할당된다.
로컬 메모리 영역(= 세션 메모리 영역, 클라이언트 메모리 영역)
로컬 메모리는 세션 메모리 영역이라고도 하며, MySQL 서버상에 존재하는 클라이언트 쿼리를 처리하는 메모리 영역을 말한다.
클라이언트가 MySQL에 접속하면 요청을 처리하기 위해 스레드를 한 개씩 할당하는데, 클라이언트 스레드가 사용하는 메모리 공간이라고 해서 클라이언트 메모리 영역이라고도 한다.
또한 클라이언트와 MySQL 서버와의 커넥션을 세션이라고도 하기 때문에 로컬 메모리 영역을 세션 메모리 영역이라고도 부른다.
대표적인 로컬 메모리 영역은 아래와 같다.
- 정렬 버퍼 : 데이터베이스에서 정렬연산을 수행하는 동안 결과물을 메모리에 임시로 저장하는데, 이 메모리 영역을 말한다.
- 조인 버퍼 : 두개 이상의 테이블에서 데이터를 가져온 결과물을 메모리에 임시로 저장하는데, 이 메모리 영역을 말한다.
- 리드 버퍼(Read Buffer) : 쿼리를 실행할 때 테이블에서 데이터를 읽어오면서 메모리에 임시로 저장하는데, 이 메모리 영역이다.
- 네트워크 커넥션 버퍼 : 데이터를 전송하기 위해 데이터 패킷을 생성하고 네트워크로 송수신하는데 데이터 전송을 위한 메모리 영역
- 결과 버퍼(Result Buffer) : 클라이언트가 요청한 쿼리 실행 결과물을 임시로 저장하는 메모리 영역
- 바이너리 로그 캐시 : 데이터베이스의 변경내역(Insert, update 등)을 메모리에 임시로 저장하고, 로그 파일에 저장한다.
로컬 메모리는 각 클라이언트 스레드별로 독립적으로 할당되며, 절대 공유되지 않는다는 특징이 있다.
로컬 메모리는 독립적이라는 특성 때문에 정렬 버퍼같은 로컬 메모리 영역을 남발하다가는 MySQL 서버가 메모리 부족 현상을 일으킬 수 있다.
로컬 메모리의 경우 정렬버퍼, 조인버퍼, 리드 버퍼와 같이 각 쿼리의 용도별로 필요할 때만 공간이 할당되고 필요하지 않은 경우 MySQL에서 메모리 공간을 할당하지 않을수도 있다.
반면에 커넥션 버퍼는 커넥션이 열려 있는 동안 계속 할당되어야 쿼리를 언제든지 실행할 준비가 되므로 메모리 공간을 계속 유지한다.
비교
InnoDB 로그 버퍼와 바이너리 로그 캐시 비교
InnoDB 로그 버퍼는 트랜잭션의 변경 사항을 임시로 저장한다.
그리고 InnoDB 스토리지 엔진에서 사용된다.
바이너리 로그 캐시는 데이터베이스의 모든 변경 작업을 로그로 기록하기 위해 변경 내역을 임시로 저장한다.
그리고 MySQL 전반적인 로깅 메커니즘에서 사용된다.
글로벌 메모리 영역과 로컬 메모리 영역의 메모리 공간 할당 비교
글로벌 메모리 영역은 데이터 베이스 서버가 실행되는 동안 계속 메모리 영역을 점유한다.
하지만, 로컬 메모리 영역은 정렬버퍼, 조인버퍼, 리드 버퍼 등과 같은 경우 쿼리 실행 동안만 메모리를 점유할 수 있기도 하고
커넥션 버퍼와 같이 데이터베이스 서버가 실행되는 동안 계속 메모리 영역을 점유할 수도 있다.
참고
Real MySQL 8.0 4장 아키텍쳐