트랜잭션(transaction manager): 트랜잭션을 스케줄링하고 데이터베이스 상태의 논리적 일관성 보장.
잠금 매니저(lock manager): 트랜잭션에서 접근하는 데이터베이스 객체에 대한 잠금을 제어. 동시 수행 작업이 물리적 데이터 무결성을 침해하지 않도록 함.
=> 트랜잭션과 잠금 매니저는 동시성 제어. 논리적 물리적 데이터 무결성을 보장하고, 동시 수행 작업의 효율적 수행을 담당.
엑세스 메서드(access method): 디스크에 저장된 데이터에 대한 접근 및 저장 방식을 정의. 힙 파일/B-트리/LSM 트리 등의 자료구조 사용.
버퍼 매니저(buffer manager): 데이터 페이지를 메모리에 캐시.
복구 매니저(recovery manager): 로그를 유지 관리하고 장애 발생 시 시스템을 복구.
MySQL의 기본 스토리지 엔진
구조가 단순해, 속도가 빠르다.
데이터 저장에 실제적인 제한이 없고 매우 효율적으로 저장한다.
→ 메모리 효율이 InnoDB보다 좋음
테이블 작업시 특정 행을 수정하려고 하면 테이블 전체에 락이 걸려서 다른사람이 작업 할 수 없다. (Table-level Lock)
→ 갱신이 많은 용도로는 성능적으로 불리. 동시 서비스에 적합X
→ multi-thread 환경에서는 성능이 저하될 수 있다.
트랜잭션에 대한 지원이 없기때문에 작업도중 문제가 생겨도 이미 db안으로 데이터가 들어감. DB 프로세스가 비정상 종료하면 테이블이 파손될 가능성이 높다. → 데이터 무결성이 보장되지 않는다.
Full-text 검색이 가능하다
주로 select 작업이 많은 경우에 사용된다. 즉, 읽기(READ)작업에 효과적이다.
MariaDB의 기본 스토리지 엔진
MyISAM보다 데이터 저장비율이 낮고, 데이터 로드 속도가 느리다.
레코드 기반의 락(Lock)을 제공한다. 즉, 테이블 레벨이 아닌 ROW 레벨의 락을 지원한다. 이로 인해 높은 동시성 처리가 가능한 특징이 있고 안정적이다. (Row - level Lock)
→ insert,update,delete에 대한 속도가 빠르다
외부키를 지원한다
자동 데드락 감지 : 감지 시 변경된 레코드가 가장 작은 트랜잭션을 롤백해버려서 데드락을 풀어준다.
자동 장애 복구 : 완료하지 못한 트랜잭션이나 일부만 기록되어 손상된 데이터 페이지 등을 자동 복구한다.
데이터 무결성 보장(트랜잭션, 외래키, 제약조건, 동시성 등) - ACID
데이터 입력 및 수정이 빈번한 높은 퍼포먼스를 요구하고 다중 사용자, 동시성이 높은 OLTP 애플리케이션에 적합
Primary Key를 기준으로 Clustering되어서 저장된다. 즉, PK를 기준으로 순서대로 디스크에 저장되는 구조로 PK에 의한 Range Scan이 빠르다.
→ 데이터를 PK순서에 맞게 저장한다는 뜻이므로 order by 등 쿼리에 유리할 수 있다.
인덱스와 더불어 데이터까지 버퍼풀에 저장하기 때문에 모든 데이터가 메모리에 있으면 디스크를 읽지 않아도 된다.
→ 데이터 접근 속도가 빠르다
→ 인덱스와 데이터 모두 메모리에 적재되므로 메모리 사용 효율에 좋지 않다.
→ 메모리 때문에 로그 수집에 대한 용도로 InnoDB를 사용하면 안된다.
Index memory caching (둘다 지원)
특정 데이터와 인덱스에 대해서 메모리 캐쉬를 지원한다.
서버에서 프로그래머가 캐시에 저장해 둘 요청을 설정하면, 그에 대해서 캐시에 저장해두고 해당 요청과 데이터에 대해 변경이 있을때 까지, 해당 요청에 대해서는 서버까지 통신하지 않고 캐시를 우선으로 조회하게 된다. 즉, 데이터베이스에 중복되는 요청을 하는 경우 메모리 캐쉬를 이용한다.Data 압축 (MyISAM만 지원)
MySQL 서버에서 디스크에 저장된 데이터 파일의 크기는
- 쿼리의 처리 성능
- 백업 및 복구 시간
- 저장 비용
과 밀접하게 연결된다. 이러한 문제를 해결하기 위해 Data 압축을 사용한다.
MySQL 서버는 디스크에 저장하는 시점에 데이터 페이지가 압축되어 저장되고, 디스크에서 데이터 페이지를 읽어올 때 압축이 해제되는 방식이다. 버퍼 풀에 데이터 페이지가 한 번 적재되면, InnoDB 스토리지 엔진은 압축이 해제된 상태로만 데이터 페이지를 관리하고 MyISAM 는 압축형식을 취한다.
이전의 인메모리 임시 테이블은 VARCHAR, VARBINARY 같은 가변 길이 데이터 타입에 대해서도, Column에 지정된 문자 수를 격납하므로 스토리지를 과소비 하는 문제가 있었다.
예) "name varchar(20)” 컬럼에 "jonggu"가 저장되어 있으면 실제 데이터는 6바이트, 인모메리 임시 테이블에서는 실제 데이터 크기가 아닌 20바이트를 사용한다
8.0부터 추가된 TempTable에서는 가변 길이 데이터 타입도 실제 데이터 크기만 소비하도록 개선되었다.
이전의 인메모리 임시 테이블은 BLOB, TEXT, JSON 같은 타입을 서포트 하지 않았으므로, 이러한 타입이 있는 경우는 디스크 임시 테이블을 사용하도록 되어 있었다.
TempTable에서는 이 타입들 또한 서포트 되어, 인메모리 임시 테이블에서 처리할 수 있게 되었다.
이전의 인메모리 임시 테이블은 스레드 별로 메모리 최대 값을 설정하고, 스레드 별로 메모리를 확보하고 있었다.
TempTable에서는 스토리지 엔진이 점유하는 메모리 최대 값을 설정할 수 있게 되었고, 모든 스레드가 공유하여 사용한다.
최대 값은 temptable_max_ram으로 설정가능하고 기본 값은 1GB이다.
이전의 인메모리 임시 테이블은 디스크 임시 테이블로 전환될 때, 인메모리 임시 테이블의 데이터를 디스크 임시 테이블로 복사하는 처리가 발생하고 있었다.
temptable_use_mmap=ON인 경우, TempTable 스토리지 엔진이 mmap 임시 파일로 인메모리 임시 테이블을 위한 공간을 할당하기 때문에 데이터를 복사하는 처리는 발생하지 않는다.
MySQL 8.0에서는 내부 임시 테이블의 종류가 3가지 있는 데, 그 중에서 어떤 설정이 좋을 지 생각해보자.
In-Memory temporary table: TempTable, Disk Temporary table: TempTable(Default)
In-Memory temporary table: TempTable, Disk Temporary table: InnoDB
In-Memory temporary table: Memory, Disk Temporary table: InnoDB
메모리에 데이터를 저장하는 엔진이며 Transaction을 지원하지 않고 table-level locking을 사용한다.
메모리를 사용하기 때문에 기본적으로 속도가 아주 빠른 편이지만 데이터를 읽어버릴 위험이 있다. 그렇기 때문에 중요하지 않지만 빠른 처리가 필요한 임시 테이블로 많이 사용하는 편이다.
메모리 테이블의 모든 데이터는 메모리 안에 저장되므로 쿼리가 디스크 입출력을 기다릴 필요가 없다.
HEAP 테이블이라 불리던 메모리 테이블은 불변하는 데이터나 재시작 이후 지속되지 않는 데이터에 빠르게 접근하는 데 유용하다.
메모리 테이블의 테이블 구조는 서버가 재시작해도 지속되지만 데이터는 지속되지 않는다
메모리 테이블 사용 예시