kimyu0218
  • [mysql] InnoDB 체인지 버퍼
    2024년 02월 04일 21시 28분 54초에 업로드 된 글입니다.
    작성자: @kimyu0218

    체인지 버퍼

    체인지 버퍼는 버퍼 풀에 존재하지 않는, 보조 인덱스 페이지*의 변경 내용을 캐시하는 데이터 구조다. DML 작업으로 인한 변경사항을 일시적으로 저장하고, 이후 다른 읽기 작업으로 인해 해당 페이지를 버퍼 풀에 가져올 때 변경 내용을 병합한다. 

    *보조 인덱스 페이지 : 인덱스 순서와 레코드의 순서가 일치하지 않으므로 레코드의 위치를 나타내는 포인터를 저장한다. 데이터가 변경되면 정렬된 상태를 유지하기 위해 인덱스 페이지가 수정된다.

    변경사항을 데이터베이스에 반영하면 보조 인덱스가 수정된다. 하지만 인덱스들은 디스크에 위치하므로 레코드가 변경될 때마다 보조 인덱스를 수정하는 I/O 작업이 발생한다. 이를 방지하기 위해 체인지 버퍼에 보조 인덱스 페이지의 변경 내용을 캐싱하여 불필요한 I/O 작업을 최소화한다.

    🚨 레코드에 대한 수정사항만 디스크에 반영하고, 보조 인덱스에 대한 변경은 나중에 처리한다.

    체인지 버퍼에 기록된 변경사항을 병합할 때, 업데이트 해야 하는 보조 인덱스가 많은 경우 몇 시간이 소요될 수도 있다. 이 시간동안 디스크 I/O가 증가하고, 쿼리 속도가 저하될 수 있다.

     

    검정색 사각형 주목!

    위의 그림에서도 확인할 수 있듯이 체인지 버퍼는 주 메모리에 위치한다. 하지만 데이터베이스가 종료되어 변경된 인덱스 페이지를 디스크에 기록해야 하는 경우, 디스크의 system tablespace를 사용한다.

     

    burk insert처럼 DML 작업이 많은 어플리케이션의 경우, 체인지 버퍼로 많은 혜택을 얻을 수 있다. 하지만 체인지 버퍼는 버퍼 풀의 일부를 차지하기 때문에 데이터를 캐시하는 데 사용할 수 있는 메모리를 감소시킨다. 따라서 작업량이 버퍼 풀 크기에 맞먹거나 상대적으로 적은 보조 인덱스가 있는 경우, 체인지 버퍼를 비활성화하는 것이 더 좋을 수 있다. (작업량이 버퍼 풀 크기와 동일한 경우, 체인지 버퍼는 쓸모가 없다. 왜냐하면 체인지 버퍼는 버퍼 풀에 없는 페이지에 대한 보조 인덱스만 캐싱하기 때문이다.)

     

    `innodb_change_buffering`*은 체인지 버퍼링을 제어한다. 해당 값은 `my.cnf`나 `my.ini`에서 확인할 수 있으며 `SET GLOBAL`을 통해 수정할 수 있다.

    *inno_db_change_buffering 값에는 all, none, inserts, deletes, changes, purges가 있다. 기본값은 `all`이다.
    이외에도 체인지 버퍼의 최대 크기를 설정하는 등 체인지 버퍼를 최적화하는 다양한 방법이 존재한다.

    참고자료

    댓글