본문 바로가기

DB

Real My SQL - 아키텍처(3)

InnoDB 스토리지 엔진 아키텍처

InnoDB 스토리지 엔진은 레코드 기반의 잠금을 제공하여 이로인해 높은 동시성 처리가 가능하다. 

 

특징 

  • 프라이머리 키에 의한 클러스터링 
  • 잠금이 필요없는 일관된 읽기
  • 외래 키 지원
  • 자동 데드락 감지
  • 자동화된 장애 복구

 

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

 - InnoDB 테이블은 기본적으로 프라이머리 키에 의해 클러스터링 되어 디스크에 저장된다. 즉, 프라이머리 키 값이 순차적으로 디스크에 저장된다는 뜻으로 프라이머리 키에 의해 인덱스 레인지 스캔이 빠르게 처리 될 수 있다.(다른 보조 인덱스에 비해 높게 설정된 이유)

 

잠금이 필요 없는 일관된 읽기

 - MVCC 라는 기술을 통해 락을 사용하지 않고 읽기를 수행한다. 다른 트랜잭션이 가지고 있는 락을 기다리지 않고 읽기 작업이 가능하다(SERIALIZABLE 격리수준 제외)

 

외래 키 지원

 - MyISAM, MEMORY 테이블은 사용할 수 없으며 InnoDB 테이블의 외래키는 부모, 자식 테이블 모두 인덱스 생성이 필요하고 변경 시에는 부모 테이블이나 자식테이블에 데이터가 있는지 체크하는 작업이 필요하므로(무결설 제약) 잠금이 여러 테이블로 전파된다. 이로인해 데드락이 발생할 때가 많다.

 

자동 데드락 감지

 - InnoDB는 그래프 기반의 데드락 체크 방식을 사용하기 때문에 데드락 발생함과 동시에 바로 감지되고, 감지된 데드락은 ROLLBACK이 가장 용이한 트랜잭션을 자동적으로 종료시켜 데드락을 해결한다.

 

자동화된 장애 복구

 - InnoDB는 손실이나 장애로부터 데이터를 보호하기 위한 매커니즘이 탑재되어 있으며 MySQL 서버가 시작할 때 완료되지 못한 트랜잭션이나 디스크에 일부만 기록된 페이지 등에 대한 일련의 복구작업이 자동으로 실행된다.

 

InnoDB 버퍼 풀

 InnoDB 스토리지 엔진에서 가장 핵심적인 부분으로 데이터 또는 인덱스 정보를 캐시하며, write 작업을 지연시켜 버퍼링 역할도 처리한다. InnoDB 버퍼풀은 백그라운드 스레드의 작업이 되는 메모리 공간이다. 

InnoDB 버퍼풀은 아직 디스크에 기록되지 않는 더티 페이지를 가지고 있으며 주기적 또는 특정 체크포인트 이벤트가 발생할 때 write 스레드가 필요한 만큼의 페이지를 디스크에 기록한다. 모든 더티 페이지가 디스크에 기록되는 것은 아니다.

 

언두 로그

 UPDATE나 DELETE 문장으로 데이터가 변경되었을 때 이전 데이터를 보관하는 영역이다. 

UPDATE member SET name = '홍길동' WHERE member_id = '1';

위 문장이 실행되면 트랜잭션이 커밋하지 않아도 InnoDB 버퍼풀이나 디스크에 홍길동으로 변경된다. 변경되기 이전의 값이 박계수였다면 언두 영역에는 박계수라는 값이 백업된다. 커밋된다면 현재 상태를 유지하며, 롤백된다면 언두영역의 값으로 InnoDB 버퍼풀을 복구하며 디스크도 복구한다.

언두 영역은 2가지 용도로 사용되는데 첫번째 용도는 롤백용도로 사용되고, 두번째 용도는 트랜잭션의 격리 수준을 유지하면서 높은 동시성을 제공하는데 사용된다.  

 

인석트 버퍼(Insert Buffer)

 레코드가 INSERT 되거나 UPDATE 될 때 디스크를 업데이트 하는 것 뿐만 아니라 인덱스도 업데이트 하는 작업이 필요하다. 인덱스를 업데이트하는 작업은 랜덤 액세스가 발생하므로 테이블에 인덱스가 많다면 많은 자원이 소모된다. InnoDB는 InnoDB 버퍼풀에 존재하면 즉시 업데이트 하지만, 만약 디스크로부터 읽어와서 업데이트 시켜야한다면 즉시 실행하지 않고 인석트 버퍼 공간에 저장해두고 사용자에게 결과를 반환하는 형태로 성능을 향상시킨다. 

인석트 버퍼에 저장되어 있는 인덱스 페이지는 추후 백그라운드 스레드에 의해 병합되는데 이 스레드를 인석트 버퍼 머지 스레드라고 한다. MySQL 5.5 버전 이후부터는 INSERT, DELETE로 인한 추가/삭제 작업에 대해서도 버퍼링 할 수 있게 되었다.

 

리두 로그 및 로그버퍼

 쿼리 문장으로 데이터를 변경하고 커밋하면 ACID를 보장하기 위해 즉시 write 해야한다. 하지만 이러한 작업은 랜덤 엑세스를 하기 때문에 많은 자원을 소모한다. 이러한 부하를 줄이기 위해 InnoDB 버퍼풀과 같은 장치가 존재하지만 이 장치만으로 ACID를 보장하기 어렵다. 이를 위해 변경된 내용을 순차적으로 디스크에 기록하는 로그 파일을 가지고 있다. 정확한 명칭은 리두 로그이다. 

사용량이 많은 DBMS 서버는 리두 로그의 로그 기록작업이 큰 문제가 발생할 수 있으며 최대한 ACID를 보장하는 수준에서 버퍼링하기 위해 로그 버퍼라는 공간을 사용한다. 로그버퍼의 크기는 1~8MB 수준을 설정하는 것이 적합하며 BLOB이나 TEXT 같이 큰 데이터를 자주 변경하는 경우는 더 크게 설정하는 것이 좋다. 

 

MVCC

 MVCC의 가장 큰 목적은 잠금을 사용하지 않는 일관된 읽기를 제공하는데 있다. InnoDB는 언두 로그를 이용해 이 기능을 구현한다.  

 

잠금 없는 일관된 읽기

  격리 수준이 READ-UNCOMMITTED나 READ-COMMITED, REPEATABLE-READ 수준인경우 INSERT와 연결되지 않는 순수한 읽기(SELECT) 작업은 다른 트랜잭션의 변경 작업과 관계없이 항상 잠금을 대기하지 않고 바로 실행된다. 즉 위의 격리수준일 경우 SELECT 시 격리 수준에 따라 버퍼풀 데이터나 언두 영역의 데이터를 읽는다.

 

 

'DB' 카테고리의 다른 글

Real My SQL - 아키텍처(2)  (0) 2021.06.06
Real My SQL - 아키텍처(1)  (0) 2021.06.06
SQL 문제풀이 6)  (0) 2020.12.20
SQL 문제풀이 5)  (0) 2020.12.19
SQL 문제풀이 4)  (0) 2020.12.18