RealMySQL 8.0 을 읽고 정리했습니다.

InnoDB 스토리지 엔진 아키텍처

InnoDB → MySQL의 스토리지 엔진 가운데

  • 가장 많이 사용되고,
  • 거의 유일하게 레코드 기반의 잠금을 제공하여 동시성 처리가 가능하고, 안정적이며 뛰어난 성능
  • 구조

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

  • InnoDB의 모든 테이블은 기본적으로 프라이머리 키를 기준으로 클러스터링 되어 저장 → 즉, 프라이머리 키 값의 순서대로 디스크에 저장되어 → 프라이머리 키에 의한 스캔은 상당히 빨리 처리됨
  • 결과적으로 쿼리의 실행 계획에서 프라이머리 키는 다른 보조 인덱스에 비해 높은 비중으로 설정
    • InnoDB 테이블 구조 = 오라클의 IOT(Index Organized Table) 구조

4.2.2 외래 키 지원

  • Only InnoDB, not MyISAM과 MEMORY 테이블
  • 여러가지 제약사항이 있어 실무에서는 잘 사용하지 않음
  • InnoDB의 외래 키는 부모 테이블과 자식 테이블 모두 해당 칼럼에 인덱스 생성이 필요하고, 변경 시에는 반드시 부모 테이블이나 자식 테이블에 데이터가 있는지 체크하는 작업이 필요하므로 잠금이 여러 테이블로 전파되고, 그로 인해 데드락이 발생할 때가 많아서 실무에서 잘 사용하지 않는다.

4.2.3 MVCC(Multi Version Concurrency Control)

  • 일반적으로 레코드 레벨의 트랜잭션을 지원하는 DBMS가 제공하는 기능
  • MVCC의 가장 큰 목적은 잠금 없는 일관된 읽기를 제공하는 것 → InnoDB는 언두 로그를 이용해 이 기능을 구현함
  • ex) ‘유재석’에서 ‘홍길동’으로 UPDATE
mysql > UPDATE member SET name='홍길동' WHERE member_id='1';

이 때의 상황

  1. InnoDB 버퍼 풀 : 수정 후 ‘홍길동'이 반영됨 (레코드 전체)
  2. 언두 로그 : 수정 전 ‘유재석'이 반영됨 (PK, 메타정보 및 수정된 칼럼만 백업)

→ 이 때, 커밋이나 롤백이 일어나지 않은 상황에서 2번 사용자가 해당 데이터를 읽으려고 하면 어떻게 될까?

결론 : 격리 수준에 따라 다르다.

  • READ_UNCOMMITTED : InnoDB 버퍼 풀이나 데이터 파일로부터 변경된 ‘홍길동' 데이터를 읽어서 반환한다.
  • READ_COMMITTED 이상 : 아직 커밋되지 않았기 때문에 언두 영역의 '유재석' 데이터를 반환한다. 이러한 과정을 DBMS 에서는 MVCC 라고 표현한다.

4.2.4 잠금 없는 일관된 읽기(Non-Locking Consistent Read)

  • InnoDB 스토리지 엔진은 MVCC를 이용해 INSERT와 연결되지 않은 순수한 SELECT 작업은 락을 걸지 않고, 바로 수행
    • 락을 걸지 않기 때문에 다른 트랜잭션이 갖고 있는 락을 기다리지 않음
    • 읽기 작업 가능(serializable 격리 수준은 제외)
    • lock이 걸려있어도 읽을 때는 언두 영역에서 읽기 때문에 lock이 걸리든 말든 상관없이 이전 버전의 데이터를 읽을 수 있다.

4.2.5 자동 데드락 감지

  • InnoDB는 그래프 기반의 데드락 체크 방식을 사용 → 데드락이 발생함과 동시에 바로 감지되고, 감지된 데드락은 관련 트랜잭션 중에서 ROLLBACK이 가장 용이한 트랜잭션(ROLLBACK을 했을 때 복구 작업이 가장 작은 트랜잭션, 즉 레코드를 가장 적게 변경한 트랜잭션)을 자동적으로 강제 종료해 버린다. 따라서 데드락 때문에 쿼리가 제한시간(Timeout)에 도달하거나 슬로우 쿼리로 기록되는 경우는 많지 않다.

4.2.6 자동화된 장애 복구

  • InnoDB는 손실이나 장애로부터 데이터를 보호하기 위한 여러 가지 매커니즘이 탑재!
    • MySQL 서버가 시작될 때, 완료되지 못한 트랜잭션이나 디스크에 일부만 기록된 데이터 페이지(Partial write) 등에 대한 일련의 복구 작업이 자동으로 진행된다.

4.2.7 InnoDB 버퍼 풀

  • InnoDB에서 가장 핵심적인 부분
  • innodb_buffer_pool_size 로 설정, 전체 물리 메모리의 50~80% 수준으로 설정
  • 디스크의 데이터 파일이나 인덱스 정보를 메모리에 캐시해 두는 공간 + 쓰기 작업을 지연시켜 일괄 작업으로 처리할 수 있게 해주는 버퍼 역할 → INSERT나 UPDATE 그리고 DELETE와 같이 데이터를 변경하는 쿼리는 디스크 작업을 발생시킴 → 버퍼 풀이 있다면 이러한 변경된 데이터를 모아서 처리하게 되면 랜덤한 디스크 작업의 횟수를 줄일 수 있다!
  • 아직 디스크에 기록되지 않은 변경된 데이터를 가지고 있다. → 이러한 데이터를 가지고 있는 페이지를 더티 페이지(Dirty page)
  • 더티 페이지는 InnoDB에서 주기적으로 또는 어떤 조건이 되면 체크포인트 이벤트가 발생하는데, 이때 Write 스레드가 필요한 만큼의 더티 페이지만 디스크로 기록한다. 체크포인트가 발생한다고 해서 버퍼 풀의 모든 더티 페이지를 디스크로 기록하는 것은 아니다.

4.2.8 Double Write Buffer

  • 파셜 페이지(Partial-page) or 톤 페이지(Ton-page) : 페이지가 일부만 기록되는 현상, 하드웨어 오작동이나 시스템 비정상 종료 등으로 발생함
  • InnoDB의 리두 로그는 공간의 낭비를 막기 위해 페이지의 변경된 내용만을 기록함 → 이로 인해 InnoDB에서 더티 페이지를 디스크 파일로 플러시할 때 일부만 기록되는 문제가 발생하면 해당 페이지는 복구가 어려울 수도.. → 이를 막기 위해 Double Write 기법을 이용!

4.2.9 언두(Undo) 로그

  • ex) ‘유재석’에서 ‘홍길동’으로 UPDATE
mysql > UPDATE member SET name='홍길동' WHERE member_id='1';
  • 언두 영역 : when? UPDATE나 DELETE 문장으로 데이터를 변경했을 때 why? 변경되기 전의 데이터를 보관하고자 사용
  • 언두 데이터 : ex) 언두 데이터 ‘유재석’ why?
  1. 트랜잭션의 rollback 대비용
  2. 트랜잭션의 격리 수준을 유지하면서 높은 동시성 제공해줘서
    • 트랜잭션의 격리 수준 : 동시에 여러 트랜잭션이 데이터를 변경하거나 조회할 때, 한 트랜잭션의 작업 내용이 다른 트랜잭션에 어떻게 보여질지를 결정하는 기준

4.2.10 체인지 버퍼

  • 인덱스 변경에 따른 자원 소모를 줄여주는 임시 메모리 공간

탄생 배경

  • 🧐 문제 : INSERT나 UPDATE 될 때 데이터 파일을 변경하는 작업 + 해당 테이블에 포함된 인덱스를 변경하는 작업 이 필요 →해당 테이블에 포함된 인덱스를 변경하는 작업 은 랜덤하게 디스크를 읽는 작업이 필요하므로 테이블에 인덱스가 많다면 상당히 많은 자원을 소모
  • 😃 해결 : 인덱스를 변경해야 한다면, 즉시 실행하지 않고 임시 공간에 저장해 두고 바로 사용자에게 반환하는 형태로 성능을 향상! → 이 때 사용하는 임시 메모리 공간 = 체인지 버퍼

특징

  • 반드시 중복 여부를 체크해야 하는 유니크 인덱스는 체인지 버퍼를 사용할 수 없음
  • 체인지 버퍼에 임시로 저장된 인덱스 레코드 조각은 이후 백그라운드 스레드에 의해 병합됨 → 이를 체인지 버퍼 머지 스레드 라고 함

4.2.11 리두(Redo) 로그 및 로그 버퍼

데이터 파일을 변경하는 것은 랜덤하게 디스크에 기록해야 하므로 비용이 비싼 작업이다. → 이 작업을 모아서 처리하여 성능을 향상하기 위해 InnoDB 버퍼 풀 같은 장치가 있음

BUT! InnoDB 버퍼 풀 만으로는 ACID를 보장할 수 없어서 → 순차적으로 디스크에 기록하는 로그 파일을 생성 = 리두 로그 (일반적으로 로그를 지칭함) 너무 많은 변경이 일어나면 리두 로그에 기록하는 것도 큰 문제가 되어서 보완하고자 = 로그 버퍼 로그 버퍼의 크기 = 일반적으로 1~8MB 수준, BLOB나 TEXT와 같이 큰 데이터를 자주 변경하는 경우는 더 크게 설정

4.2.12 어댑티브 해시 인덱스

  • InnoDB에서 사용자가 자주 요청하는 데이터에 대해 자동으로 생성하는 인덱스
  • innodb_adaptive_hash_index : 시스템 변수를 이용해서 활성화 및 비활성화

도입 목적

  • B-Tree의 검색 시간을 줄여주기 위해

작동 방식

  • 자주 읽히는 데이터 페이지의 키 값을 이용해 변수 생성
  • 필요할 때마다 어댑티브 해시 인덱스를 검색해서 레코드가 저장된 데이터 페이지로 가기
  • → 장점! B-Tree를 루트 노드부터 리프 노드까지 찾아가는 비용이 없어지고, CPU는 적은 일을 하지만 쿼리 성능은 빨라져서 동시에 더 많은 쿼리를 처리함

특징

  • (key, value) = (’인덱스 키 값’, 해당 인덱스 키 값이 저장된 ‘데이터 페이지 주소’)
  • 인덱스 키 값 = ‘B-Tree 인덱스 고유번호(ID)와 B-Tree 인덱스 실제 키 값’ 조합
  • 인덱스 키 값에 ‘B-Tree 인덱스의 고유번호’가 포함되는 이유 → InnoDB에서 어댑티브 해시 인덱스는 하나만 존재하기 때문이다. 즉, 특정 키 값이 어느 인덱스에 속한 것인지 구분하기 위해서!

왜 우리는 시스템에 돈을 내는가

시스템이란 무엇을 위해 도입하는가?

→ 데이터베이스란 무엇을 위해 도입하는가?

 왜 시스템에 돈을 내는가?

시스템을 만드는 이유

 

데이터베이스의 초기비용

시스템의 전체비용 내역

  • 초기비용 : 최초에 지급하는 돈
  • 운영비용 : 서비스를 이용하는 기간에 계속해서 지급하는 돈

일반적으로 운영비용의 단위 금액(월 비용이나 연간 비용)은 초기비용보다 낮게 설정됨

하지만 초기비용 < 운영비용 합인 경우도 드물지 않음

초기비용과 운영비용의 비율을 바꿔서 전체비용을 낮게 보이려는 심리적인 트릭도 있음

 

라이선스 요금과 가격의 차이

  • 라이선스 : 데이터베이스 도입할 때 초기비용, 소프트웨어 사용허가료

차이

  1. 판매단위가 특수하다
  2. 운영비용을 지급하지 않으면 현실적으로 사용할 수 없다.

 

프로세서 라이선스와 사용자 라이선스

  • 프로세서 라이선스 : 하드웨어 CPU 성능에 따라 가격이 결정됨
    • 사용자 수가 많거나 불특정 다수가 이용해서 사용자 수를 셀 수 없는 경우 적용
  • 사용자 라이선스 : 사용자 수에 따라 가격이 결정됨
    • 사용자 수가 적은 경우 유리

둘 다 DBMS가 동작하는 시스템의 규모(프로세서 성능, 사용자 수)가 커질수록 라이선스료도 올라간다.

 

초기비용을 늘리는 범인

에디션과 옵션

에디션

  • 스탠다드 에디션 : 중소규모 시스템용
  • 엔터프라이즈 에디션 : 대규모 시스템용
    • 신뢰성 : 클러스터 구성, 리플리케이션
    • 성능 : 일정 수량 이상의 프로세서 기술지원, 테이블 파티셔닝, 성능 리포트 출력, 데이터 압축
    • 보안 : 데이터 암호화, 감사로그 기록
    • 오픈소스 DBMS(PostgreSQL, MySQL)보다 벤더에서 개발한 DBMS(Oracle, SQL Server. DB2)이 고급 기능을 가짐
  • 익스프레스 에디션 : 시험판
    • 라이선스료 무료(벤더가 제시하는 이용 요건 지키는 선에서)
    • 일부 기능 이용 불가
    • 시험이나 테스트용으로 사용 가능

 

데이터베이스의 운영비용

상용 시스템에서는 초기비용 못지않게 운영비용(= 기술지원 비용)이 발생

일정 기간에 OO원을 지급해야 함

 

기술지원 서비스

  • 기술 Q&A
  • 버그 수정을 위한 프로그램 배포
  • 최신 버전으로의 업데이트 관리
  • 새로운 OS나 하드웨어에의 대응
  • 전문 기술자나 컨설턴트를 통한 문제 해결
  • 노하우나 버그 정보 같은 기술 데이터베이스로의 접근 권리

특징

  • 제품의 기술지원 기간에 주의
  • 기술지원 없는 소프트웨어는 위험
  • 기술지원 수준은 매년 내려감
    • EOSL(End Of Service Life) : 서포트 종료 타이밍
  • 구매 시기와 기술지원 기간은 관계없음
    • 소프트웨어 수명 : 소프트웨어 릴리스를 기준으로 산정됨

라이선스 vs 서브스크립션

구분 서브스크립션(임대모델) 라이선스(구매모델)
특징 사용권 대여 사용권 구매
장점 1. 정해진 초기비용 없이 도입 가능
2. 시범 도입 가능
3. 불필요할 때 바로 사용 중단 가능
4. 타 데이터베이스로 마이그레이션이 쉬움
1. 반영구적으로 이용 가능
2. 전체비용의 변동 위험이 적고 장기적인 계획을 세울 수 있음
단점 1. 이용 기간이 길면 전체비용이 구매 비용보다 높아질 수 있음
2. 서비스를 제공하는 벤더의 도산이나 사업 철수로 서비스를 정지하면 이용할 수 없음
3. 요금인상 등의 비용 변경 요소가 있음
1. 초기비용 필요
2. 시범 도입 불가능
3. 타 데이터베이스로 마이그레이션이 어려움

 

초기비용과 운영비용의 조합

  1. 초기비용 X + 운영비용 X
    • 상용은 현실적으로 불가능
    • 개인은 무료 소프트웨어
  2. 초기비용 O + 운영비용 X
    • 유지보수 계약을 맺지 않아 기술지원이 없는 것
  3. 초기비용 O + 운영비용 O
  4. 초기비용 X + 운영비용 O
    • 오픈소스 이용
    • 기술지원료만 유상으로 하거나, 서브스크립션 형식
    • Red Hat, MySQL 등

 

초기비용의 트릭

인간의 현재지향 편향을 이용하여 초기비용을 운영비용에 포함하여 이익을 회수

운영비용을 포함한 전체비용을 확실하게 계산해야 함

 

 

+ Recent posts