Real MySQL - 04 아키텍처

johan1103·2023년 2월 17일
post-thumbnail

💻 Inno DB 스토리지 엔진 아키텍처

MySQL 에서 사용할 수 있는 스토리지 엔진 중 거의 유일하게 레코드 기반의 잠금을 제공한다.

그렇기 때문에 높은 동시성 처리가 가능하고 성능이 뛰어나다.

프라이이머리 키에 의한 클러스터링

Inno DB의 모든 테이블은 기본적으로 프라이머리 키를 기준으로 클러스터링 되어 저장된다. 즉, 프라이머리 키 값의 순서대로 디스크에 저장된다.

모든 세컨더리 인덱스가 레코드의 주소 대신 프라이머리 키의 값을 논리적인 주소로 사용한다.

프라이머리키가 클러스터링 인덱스이므로 프라이머리 키를 이용한 레인지 스캔은 상당히 빨리 처리될 수 있다. (결과적으로 퀴리의 실행 계획에서 프라이머리 키는 기본적으로 다른 보조 인덱스에 비해 비중이 높게 설정된다.)

💡자세한 내용은 8.8 절 ‘클러스터링 인덱스’에서 다룬다.

MVCC

잠금을 걸지 않고 일관된 읽기를 위한 기능이다. InnoDB는 언두 로그를 이용해서 이 기능을 구현한다. 읽게되는 데이터는 데이터베이스의 격리 수준에 따라 다르다.

InnoDB에서는 데이터베이스에 Insert를 한 다음 Update를 하면 트랜잭션 commit을 하기 전 까지는 InnoDB버퍼 풀이라는 공간에서 수정을 진행하고 수정하기 전 원본을 언두로그에 임시로 저장한다. commit을 하게 되면 언두 로그를 비우고 InnoDB 버퍼풀 내용을 영구적인 데이터로 만들어버린다. (디스크에 반영이 된다.) Rollback을 하면 언두 영역에 있는 백업된 데이터를 InnoDB 버퍼 풀로 다시 복구하고 연두 영역의 내용을 삭제해버린다..

💡커밋이나 롤백이 된다고 무조건 언두로그를 비우는 것은 아니라고 한다. 정확히는 언두 영역을 필요로 하는 트랜잭션이 더는 없을 때 삭제된다고 한다. (구체적으로 어느 상황인지는 모르겠다.)

중요한 것은 격리 수준에 따라서 Commit을 하기 전에는 어떤 데이터를 읽어내는 것인지이다. Update를 반영하고 Commit이 되지 않은 상황에서는 InnoDB 버퍼풀에는 Update된 내용이, 언두로그에는 Update되기 전 원본 내용이 저장되어있을 것이다.

🐤격리 수준이 READ_UNCOMMITED인 경우

InnoDB 버퍼 풀이 현재 가지고 있는 변경된 데이터를 반환한다. 즉, 데이터가 커밋됐든 아니든 변경된 상태의 데이터를 반환한다.

🐣그외에 REPEATED_READ, ISOLATION인 경우

커밋되지 않은 정보는 반영하지 않고 이전의 내용인 언두 영역의 데이터를 반환한다. 이러한 과정을 DBMS에서는 MVCC라고 표현한다.

InnoDB 버퍼 풀

InnoDB 스토리지 엔진에서 가장 핵심적인 부분으로, 디스크의 데이터 파일이나 인덱스 정보를 메모리에 캐시해 두는 공간이다.

책에서는 처음으로 MySQL서버를 준비한다면 운영체제의 전체 메모리 공간이 8GB미만이라면 50%정도만 InnoDB버퍼 풀로 설정하고 나머지 메모리 공간은 MySQL 서버와 운영체제, 다른 프로그램이 사용할 수 있는 공간으로 확보해주고, 운영체제의 전체 메모리 공간이 50GB이상이라면 대략 15GB에서 30GB정도를 운영체제와 다른 응용프로그램을 위해서 남겨두고 나머지를 InnoDB버퍼 풀로 할당하는 것을 추천하고 있다.

💡InnoDB 버퍼 풀은 innodb_buffer_pool_size 시스템 변수로 크기를 설정할 수 있다.

언두 로그

InnoDB 스토리지 엔진은 트랜잭션과 격리 수준을 보장하기 위해 DML(Insert, Update, Delete)로 변경되기 이전 버전의 데이터를 별도로 백업한다. 이렇게 백업된 데이터를 언두 로그라고 한다.

언두 로그의 특징

  • 트랜잭션 보장

    트랜잭션이 롤백될 때, 데이터는 변경 이전의 데이터로 복구되어야 한다. 이때 원본 데이터를 저장해 놓은 언두로그의 도움으로 복구를 할 수 있다.

  • 격리 수준 보장

    특정 커넥션에서 데이터를 변경하는 도중에 다른 커넥션에서 데이터를 조회하면 트랜잭션 격리 수준에 맞게 변경중인 레코드를 읽지 않고 언두 로그에 백업해둔 데이터를 읽어서 반환할 수 있게 한다.

    원본 데이터를 저장해 놓은 언두 로그 덕분에 테이블에 락을 걸지 않고 읽관된 읽기가 가능하고 트랜잭션의 격리수준을 유지하면서 높은 동시성을 제공한다.

0개의 댓글