[F-Lab 챌린지 54일차 TIL]

성수데브리·2023년 8월 20일
0

f-lab_java

목록 보기
44/73

InnoDB 스토리지 엔진 아키텍처

  • 레코드 기반 잠금을 제공하여 높은 동시성 처리가 가능하고 안정적이며 성능이 뛰어나다.

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

  • InnoDB 의 모든 테이블은 기본적으로 프라이머리 키를 기준으로 클러스터링되어 저장된다.
  • = 프라이머리 키 값의 순서대로 디스크에 저장된다.
  • 세컨더리 인덱스는 레코드의 주소 대신 프라이머리 키 값을 논리적 주소로 사용
  • PK 가 클러스터링 인덱스므로 레인지 스캔이 빨리 처리된다.

외래 키 지원

  • 외래 키 지원은 InnoDB 스토리지 엔진 레벨에서 지원하는 기능이다.
  • MyISAM 에서는 사용할 수 없다.
  • InnoDB 에서 외래키는 부모 테이블과 자식 테이블 모두 해당 컬럼에 인덱스 생성이 필요하다.
    • 변경 시 반드시 부모 테이블이나 자식 테이블에 데이터가 있는지 체크하는 작업이 필요하므로 잠금이 여러 테이블로 전파된다.
    • 이로인해 데드락이 발생하므로 주의하라

MVCC (Multi Version Concurrency Control)

  • 레코드 레벨의 트랜잭션을 지원하는 DBMS 가 제공하는 기능

  • 목적 : 잠금을 사용하지 않는 일관된 읽기를 제공

  • 언두 로그(Undo log) 를 이용해 구현한다.

  • Multi Version 의미 : 하나의 레코드에 대해 여러 개의 버전이 동시에 관리된다는 의미

    MVCC 과정 살펴보기

    1. 최초 INSERT

      INSERT INTO member(id, name, area)
      VALUEs(1, 'LEE', '서울');
      
      COMMIT;

    2. 해당 레코드 UPDATE

      • 커밋 실행 여부와 관계없이 InnoDB 버퍼 풀의 데이터는 업데이터 된다.
      • 디스크의 데이터 파일은 체크포인트나 InnoDB 의 Write 스레드에 의해 새로운 값으로 업데이트돼 있을 수 있고 아닐 수도 있음
      UPDATE member
      SET area = '경기'
      WHERE id = 1;

    3. 위에서 수행한 UPDATE 를 커밋하기 전 SELECT 하면?

      • 설정된 격리 수준에 따라 다르다.
        • READ_UNCOMMITED : 버퍼 풀의 데이터 읽는다.
        • READ_COMMITED 나 그 이상 수준 : 언두 영역의 데이터 읽는다.
    • 정리 : 한 레코드에 대해 2개의 버전이 유지되고, 필요에 따라 어느 데이터가 보여지는지 상황에 따라 달라지는 구조다.
    • 주의 : 트랜잭션이 길어져서 언두 영역에 보관해야 할 데이터가 많아지면 테이블스페이스의 공간이 많이 늘어나는 상황 발생할 수 있다.
    1. COMMIT 한다.
      - 현재까지 상태를 영구적인 데이터로 만든다.
      - 롤백 하면 언두 영역의 데이터 → 버퍼 풀로 복구 / 언두 영역 내용 삭제 ( 언두 영역을 필요로하는 트랜잭션이 더는 없을 때)

      잠금 없는 일관된 읽기

    • InnoDB 스토리지 엔진은 MVCC 기술을 이용해 잠금을 걸지 않고 읽기 작업을 수행한다.

    • 순수한 읽기 작업은 다른 트랜잭션의 변경 작업과 관계없이 항상 잠금을 대기하지 않고 바로 실행된다.

      → 변경 전 데이터인 언두 로그를 사용한다. 

자동 데드락 감지

  • InnoDB 스토리지 엔진은 내부적으로 잠금이 교착 상태에 빠지지 않았는지 체크하기 위해
    잠금 대기 목록을 그래프(Wait-for List) 형태로 관리한다.
  • 데드락 감지 스레드가 검사, 교착 상태 트랜잭션 발견하면 강제 종료한다.
    • 언두 로그 레코드를 더 적게 가진 트랜잭션을 먼저 처리
    • innodb_table_locks 시스템 변수 활성화하자
  • 자동 데드락 감지 스레드가 느려지는 경우
    • 122 페이지 복습

자동화된 장애 복구

  • 자동 복구 대상
    • 완료되지 못한 트랜잭션
    • 디스크에 일부만 기록된 데이터 페이지

InnoDB 버퍼 풀

  • InnoDB 스토리지 엔진에서 가장 핵심적인 부분
  • 역할
    • 디스크의 데이터 파일이나 인덱스 정보를 메모리에 캐시하는 공간
    • 쓰기 작접을 지연시켜 일괄 작업으로 처리할 수 있게 해주는 버퍼 역할 → 랜덤한 디스크 작업을 줄여준다
  • 풀 인스턴스
    • 버퍼 풀 전체를 관리하는 잠금으로 인한 내부 잠금 경합으로 버퍼 풀을 여러 개로 쪼개어 관리할 수 있도록 개선됨.

버퍼 풀 구조

  • 자료구조
    • LRU (Least Recently Used) 리스트
      • Old Sublist : LRU 영역
      • New Sublist : MRU 영역
      • 사용 목적 디스크로부터 한 번 읽어온 페이지를 최대한 오랫동안 InnoDB 버퍼풀의 메모리에 유지해서 디스크 읽기를 최소화하는 것
      • 데이터 찾는 과정
        1. Buffer Pool 검사
          1. 있으면?
        2. 없으면?
    • Flush 리스트
      • 디스크로 동기화되지 않은 데이터를 가진 데이터 페이지의 변경 시점 기준의 페이지 목록을 관리한다.
      • 데이터가 변경되면 InnoDB 는 변경 내용을 리두 로그에 기록하고 버퍼 풀의 데이터 페이지에도 변경 내용을 반영한다.
      • 체크포인트. 리두 로그와 데이터 페이지의 상태를 동기화한다. 북구시 리두 로그의 어느 부분부터 복구를 실행해야 할지 판단하는 기준점
    • Free 리스트 InnoDB 버퍼 풀에서 실제 사용자 데이터로 채워지지 않는 비어 있는 페이지들의 목록. 사용자의 쿼리가 새롭게 디스크의 데이터 페이지를 읽어와야 하는 경우 사용된다.

버퍼 풀과 리두 로그

성능 향상을 위한 버퍼 풀의 용도

  1. 데이터 캐시
    • 버퍼 풀의 용량을 늘리는 것
  2. 쓰기 버퍼링 ( 112 페이지 )
    • 1개 이상의 고정 크기 파일을 연결해서 순환 고리처럼 사용
    • LSN(log sequence number) : 리두 로그 파일에 매번 기록될 때마다 로그 포지션은 계속 증가된 값을 갖게 된다.
    • Checkpoint Age
      • 가장 최근 체크포인트의 LSN마지막 리두 로그 엔트리의 LSN차이
      • 활성 리두 로그 공간의 크기를 일컫는다.

Buffer Pool Flush

  • 더티 페이지를 디스크에 동기화하는 것
  • 5 버전에서 디스크 쓰기 폭증 발생. 8 버전에서 개선
  • 백그라운드 스레드에서 실행되는 2개의 플러시 기능
    1. 플러시 리스트 플러시

      주기적으로 플러시 리스트 플러시 함수를 호출해서 츨러시 리스트에서 오래전에 변경된 데이터 페이지 순서대로 디스크에 동기화하는 작업 수행

    2. LRU 리스트 플러시

      사용 빈도가 낮은 데이터 페이지들을 제거해서 새로운 페이지들을 읽어올 공간을 만든다.

0개의 댓글