Database

InnoDB 알아보기 (In-Memory Structures - Change Buffer)

mysterious dev 2024. 1. 29. 23:56

Change Buffer

 

 

체인지 버퍼는 버퍼 풀에 존재하지 않는 세컨더리 인덱스에 대한 변경을 캐시하기 위한 메모리 영역이다.


INSERT, UPDATE, DELETE 로 데이터가 변경되면,

디스크에 있는 데이터 파일을 변경하는 작업과 해당 테이블의 인덱스를 업데이트하는 작업이 필요하다.

인덱스는 디스크에 존재하므로 인덱스의 업데이트는 디스크 접근을 발생시키고,

이러한 작업이 많아질수록 성능은 저하된다.

 

InnoDB는 변경해야 할 인덱스 페이지가 버퍼 풀에 올라와있으면 곧바로 업데이트를 수행하지만,

디스크에서 읽어와야 하는 경우에는 데이터를 바로 변경하지 않는다.

데이터의 변경은 임시 공간에 저장하고 사용자에게는 곧바로 반환하여 성능을 향상시키는데,

이때 사용되는 임시 공간이 체인지 버퍼이다.

 

체인지 버퍼의 데이터는 다음과 같은 상황에서 병합(merge)된다.

  • 해당 페이지가 읽기 작업에 의해 디스크에서 버퍼 풀로 로드되는 경우
  • 시스템이 대부분 유휴(idle) 상태이거나, slow shutdown 시 main thread에 의해 주기적으로 디스크로 쓰여진다.
slow shutdown(clean shutdown)은 MySQL 서버가 종료될 때 모든 커밋된 내용을 데이터 파일에 기록하고 종료하는 작업이다.
main thread는 background thread이다.
첫번째 사진을 보면 체인지 버퍼가 메모리와 디스크에 모두 존재함을 확인할 수 있다.
메모리에 존재하는 체인지 버퍼는 버퍼 풀의 일부이며,
디스크에 존재하는 체인지 버퍼는 system tablespace의 일부로써 서버가 종료될 때 인덱스 변경이 버퍼링된다.
따라서 DB 재시작 시에도 버퍼링된 데이터는 유지된다.

 

 

 

 

✔️ 세컨더리 인덱스만 버퍼링하는 이유

인덱스에 유니크 제약조건이 있는 경우, 사용장에게 결과를 전달하기 전에 중복 체크를 해야 한다.

따라서 PK에 의한 인덱스(클러스터드 인덱스)와 유니크 제약조건을 가진 세컨더리 인덱스에는 체인지 버퍼를 사용할 수 없다.

 

 

 

 

✔️ 버퍼링 작업 종류 설정

MySQL 5.5 이전 버전까지는 INSERT 작업에 대해서만 버퍼링이 가능했었다.

그래서 그 당시까지는 Change Buffer 대신 Insert Buffer라는 용어를 사용했다.

 

5.5버전 이후에는 조금씩 개선되어 8.0 버전에서는 INSERT, DELETE, UPDATE에 대해서도 버퍼링이 가능해졌다.

또한 innodb_change_buffering 옵션을 통해 작업의 종류별로 체인지 버퍼를 설정할 수 있게되었다.

  • all: inserts + deletes + purges
  • none: 버퍼링 안 함
  • inserts: 삽입에 대해서만 버퍼링
  • deletes: 삭제 마킹 작업(delete-marking)만 버퍼링
  • changes: inserts + deletes
  • purges: 영구적으로 삭제하는 작업만 버퍼링 (백그라운드 작업)

 

 

 

 

✔️ 메모리 공간 설정

체인지 버퍼는 기본적으로 버퍼 풀의 25%까지 사용할 수 있도록 설정되었다.

innodb_change_buffer_max_size 를 통해 해당 값을 변경할 수 있으며, 0~50 사이의 값을 설정할 수 있다.

 

 

 

 

 

 

참고