본 문서에서는 MySQL의 스토리지 엔진에 대해 알아보도록 하겠습니다.
스토리지 엔진
스토리지 엔진이란 MySQL에서 실제 Data를 디스크 스토리지에 저장하거나 읽어오는 부분을 담당합니다.
위 그림과 같이 MySQL은 스토리지 엔진을 플러그인 방식으로 사용할 수 있는 구조를 가지고 있기 때문에 필요에 따라 원하는 스토리지 엔진을 구성하여 사용할 수 있습니다.
사용자는 show [storage] engines
명령을 통해 스토리지 엔진 목록을 확인 가능하며, Support 값이 나타내는 의미는 다음과 같습니다.
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
Value | Description |
DEFAULT | 사용가능하며(=YES) 현재 기본 스토리지 엔진 |
YES | 사용가능한 스토리지 엔진 |
NO | 포함되지 않은 스토리지 엔진 |
DISABLED | 포함은 되어 있지만, 비활성화 상태로 설정된 스토리지 엔진 |
- MySQL 엔진과 달리, 스토리지 엔진은 여러 개를 동시에 사용할 수 있습니다. 테이블이 사용할 스토리지 엔진을 지정하면 이후 해당 테이블의 Read/Write 작업은 지정한 스토리지 엔진이 처리합니다.
- 어떤 스토리지 엔진을 사용하느냐에 따라 성능 차이가 발생하기도 합니다. 이는 스토리지 엔진별로 서로 다른 작업 처리 방식을 갖기 때문이며, 이러한 이유로 스토리지 엔진의 선택은 매우 중요합니다.
- MySQL Server에 포함되지 않은 스토리지 엔진을 사용하려면 MySQL 서버를 다시 빌드해야 하지만, 플러그인 형태로 빌드되어 제공되는 스토리지 엔진의 경우에는 라이브러리를 다운로드해서 쉽게 추가하여 사용 및 업그레이드가 가능합니다.
스토리지 엔진의 종류
MySQL 8.0에서 플러그인 방식으로 제공되는 스토리지 엔진의 종류는 다음과 같습니다.
InnoDB
먼저 InnoDB 엔진에 대해서 설명하겠습니다. InnoDB 엔진은 MySQL 8.0의 기본 스토리지 엔진이며, 가장 보편적으로 많이 사용하는 스토리지 엔진입니다. (Oracle과 가장 유사한 구조를 가지고 있습니다.)
특징
- InnoDB 엔진 사용 시 DML 작업은 ACID 모델을 따르며 Commit, Rollback 및 복구 기능을 갖춘 트랜잭션으로 Data를 보호합니다.
📢 ACID는 원자성(Atomicity), 일관성(Consistency), 격리성(Isolation), 내구성(Durability)을 의미합니다. 이는 데이터베이스 내 트랜잭션의 속성으로 Data 유효성을 보장합니다.
- InnoDB의 핵심 특징은 Buffer Pool의 존재입니다. Oracle의 Buffer Cache와 마찬가지로 디스크 상의 Data 파일이나 인덱스 정보를 메모리에 캐시 해두기 위한 공간입니다. 변경된 Data를 모아서 처리하기 때문에 디스크 I/O 횟수를 줄일 수 있습니다.
- PK(Primary Key)를 기반으로 쿼리를 최적화하도록 디스크에 Data를 정렬하여 저장합니다. Clustered Index라는 Primary Key Index가 있어 PK 검색에 대한 I/O 를 최소화합니다.
- Row-Level Lock 및 MVCC를 이용하여 Multi User에게 동시성을 제공합니다.
📢 MVCC(Multi Version Concurrency Control)는 수정 및 읽기 대상인 Data가 있을 경우, 상호 간의 충돌을 막고 Session 별로 해당 Data를 쓰거나 조회하는 시점의 Data의 정합성을 보장하는 메커니즘입니다. 하나의 레코드에 대하여 여러 버전으로 관리하는 방식으로, MySQL은 트랜잭션의 Commit과 Rollback 여부와 상관없이 변경 이전의 Data를 Undo 로그에 기록하여 격리 레벨에 따라 Lock을 사용하지 않고 일관되게 Data 조회가 가능합니다.
- 데이터 무결성을 보장하기 위해 FK(Foreign Key)를 지원합니다. 관련 Data를 다른 테이블로 분리할 때 참조 무결성을 위한 FK 설정이 가능합니다.
- 자동으로 Dead Lock을 감지하여 변경된 레코드가 가장 적은 트랜잭션을 Rollback하여 자동으로 데드락을 풀어줍니다.
MyISAM
MyISAM 엔진은 InnoDB보다 심플하고 빠르지만 동시성 제어가 어렵습니다. (MySQL 5.5 이전까지 기본 스토리지 엔진이었습니다.)
특징
- Full-Text 인덱싱, 압축, 함수(Geographic Information System, GIS, 지리정보시스템) 등 여러 유용한 기능을 제공합니다.
- 트랜잭션을 지원하지 않습니다.
- (InnoDB의 Buffer Pool과 유사한 역할을 하는) Key Cache라는 메모리 영역이 존재하며, 이는 MyISAM 테이블의 인덱스를 저장하기 위해 미리 할당된 영역입니다. Key Cache는 인덱스를 대상으로 동작하기 때문에 인덱스의 디스크 쓰기 작업에 대해서는 부분적으로나마 버퍼 역할을 수행합니다. 테이블 Data는 캐시나 버퍼링 기능이 없기 때문에 항상 디스크를 사용합니다.
- Row 단위가 아닌 Table-Level의 Lock을 제공하며, 모든 테이블에 대하여 읽고 쓰는 경우 공유된 읽기 권한, 배타적 쓰기 잠금 권한을 얻어야 합니다.
- 동시 삽입을 지원하기 때문에 대량의 Insert를 수행하는 배치작업에 적합합니다.
- 읽기 전용 또는 읽기 위주의 작업에 적합하며 주로 Read 쿼리가 많은 DW 환경에서 많이 사용됩니다.
MEMORY(Heap)
메모리에 Data를 저장하는 스토리지 엔진으로, I/O 효율이 다른 엔진보다 훨씬 높습니다.
특징
- Table-Level의 Lock을 사용합니다.
- 메모리에 저장하기 때문에 기본적으로 속도가 매우 빠른 편이지만 Data를 유실할 가능성이 있습니다. (테이블의 정의는 MySQL Data Dictionary에 저장되며 디스크에 파일을 생성하지 않습니다.)
- 중요도가 떨어지지만 빠른 처리가 필요한 임시 테이블에 많이 사용합니다.
- MEMORY 엔진이 사용되는 경우는 아래와 같습니다.
- Data 조회 또는 Mapping
- 주기적으로 집계되는 Data의 결과를 캐시
- Data 분석 시 중간 결과 저장
ARCHIVE
대량의 Data를 압축하여 저장하는 스토리지 엔진입니다.
특징
- Row가 Insert될 때마다 zlib로 압축하기 때문에 디스크 I/O를 훨씬 적게 발생시키며 빠르게 Insert 작업을 처리할 수 있습니다.
- Insert, Replace 및 Select는 허용하지만 Delete 또는 Update 쿼리는 허용하지 않습니다.
- Row-Level의 Lock을 사용합니다.
- 많은 양의 로그성 Data를 저장하고 읽는데 주로 사용됩니다.
- 인덱스를 지원하지 않습니다.
CSV(Comma Separated Values)
쉼표로 구분된 값 형식을 사용하여 텍스트 파일에 Data를 저장하는 스토리지 엔진입니다.
특징
- CSV 스토리지 엔진을 사용하여 생성하는 테이블의 모든 컬럼은 NOT NULL 속성을 가집니다.
- Server가 실행되는 동안 데이터베이스 내외로 파일을 복사할 수 있습니다.
- CSV 파일이 대부분의 응용 프로그램과 쉽게 통합될 수 있으므로 유연성을 제공합니다.
- (ex. 스프레드시트에서 CSV 파일을 내보내기하여 MySQL Server의 Data 디렉토리에 저장하면 Server는 즉시 이 파일을 읽을 수 있으며, CSV 테이블에 Data를 기록하면 외부 프로그램을 통해 확인할 수 있습니다.)
FEDERATED
별도의 물리적 MySQL Server를 하나의 논리적 MySQL 데이터베이스로 만들고 연결하는 스토리지 엔진이며, 특히 분산 Data 환경에 권장됩니다.
특징
- FEDERATED 테이블은 두가지 요소로 구성됩니다.
- Remote Server : 테이블의 정의 및 Data로 구성됩니다. Remote 테이블은 MyISAM 또는 InnoDB를 포함하여 Remote Server에서 지원하는 모든 유형의 스토리지 엔진의 사용이 가능합니다.
- Local Server : Remote Server의 테이블 정의와 일치하는 테이블이 필요하며 Remote Server와 달리 Federated 엔진으로 테이블을 구성해야 합니다. Local Server에는 실제 Data 파일이 없으며, 테이블 정의 시 Remote 테이블을 가리키는 Connection 정보를 포함하고 있습니다.
- Local Server에서 Federated 테이블을 Query 하면 Remote Server 내의 테이블을 참조하며, 모든 작업은 Remote Server에 연결합니다.
- Local 테이블에는 실제 Data가 저장되지 않습니다.
- Local Server의 Federated 테이블에 대해 Query 및 Command를 수행할 때 Insert, Update 또는 Delete 등의 작업이 Remote Server로 전송되며, 해당 Server의 Data 파일을 업데이트하거나 일치하는 Row을 반환합니다.
📢 Federated 테이블 Data에 대한 Access가 원격으로 처리되기 때문에 인덱스를 사용하는 곳은 실제 Remote 테이블입니다. 인덱스 사용이 불가하여 전체 테이블에 대한 검색이 필요한 경우라면 Remote 테이블에서 모든 Row를 가져온 후 Local Server에서 필터링하므로 성능 저하 및 네트워크 부하가 발생할 수 있습니다. (반환된 결과는 메모리에 저장되어야 하므로 Local Server Swapping 또는 Hanging으로 이어질 수 있습니다.)
BLACKHOLE
Data를 받아들이지만 이를 버리고 저장하지 않는 저장 메커니즘을 전혀 갖고 있지 않은 스토리지 엔진입니다.
특징
- Blackhole 테이블에 Data를 Insert하면 저장되지 않으며, 검색 시 항상 빈 결과를 반환합니다.
- Blackhole 테이블을 생성하면 테이블 정의를 만들 뿐 실제 테이블과 연결된 파일은 없습니다.
- Replication 환경에서 Master Server에 Blackhole Table이 존재한다면
binlog_format
을statement
로 설정해야 합니다.
(binlog_format
이mixed
,row
인 경우 Slave 테이블에 변경내역이 적용되지 않습니다.) - BLACKHOLE 엔진이 사용되는 경우는 다음과 같습니다.
- Dump 파일 구문 확인
- 바이너리 로깅의 활성화 여부에 따른 성능을 비교하는데 사용하여 binlog 기록의 오버헤드를 측정
- 스토리지 엔진 자체와 관련 없는 성능 관련 병목현상 탐색
NDB(For MySQL Cluster)
Cluster DB라고 부르며, MySQL Cluster를 구성할 때 사용하는 스토리지 엔진입니다.
MySQL NDB Cluster = MySQL Server + NDB Storage Engine
NDB Cluster(Network Database Cluster)는 Shared-noting 시스템에서 메모리 내 데이터베이스의 클러스터링을 가능하게 하는 기술입니다. MySQL과는 별도의 프로세스(노드)로 동작해서 클러스터링을 처리하며, 사용자가 Custom Clients(NDBAPI)를 통해 Cluster에 Access 하는 경우 MySQL Server와 독립적으로 사용할 수 있습니다.
- Data Nodes : Data 저장 및 Query의 주요 작업 수행
- SQL Nodes : Query 실행 (=MySQL Server 인스턴스)
- Management Server : Cluster 구성 관리, 새로운 Connection 처리, Node 장애 시 백업 생성
📢 Shared-nothing이란 문자 그래도 ‘아무것도 공유하지 않는다’라는 의미로, 네트워크 이외의 자원을 모두 분리하는 방식입니다. Shared-nothing 시스템에서 각 구성 요소는 메모리 및 디스크를 자체적으로 가져야 합니다. 네트워크 공유, 네트워크 파일 시스템 및 SAN과 같은 공유 스토리지 메커니즘의 사용은 권장되지 않거나 지원되지 않습니다.
특징
- 클러스터형 데이터베이스 엔진은 가능한 최고 수준의 가동 시간과 가용성이 필요한 응용 프로그램에 특히 적합합니다.
- NDB 스토리지 엔진에 의해 Data가 저장되면 테이블(및 테이블 Data)은 Data 노드에 저장됩니다. 이러한 테이블은 클러스터의 다른 모든 MySQL Server(SQL 노드)에서 직접 Access 할 수 있습니다.
- NDB 클러스터에 연결되지 않은 MySQL 서버는 NDB 스토리지 엔진을 사용할 수 없으며, NDB 클러스터 Data에 Access할 수 없습니다.
MRG_MyISAM
MERGE 엔진이라고도 하며, 동일한 MyISAM 테이블 모음을 논리 단위로 취급하여 동시에 Query할 수 있습니다. 여러 테이블에서 반환된 결과는 하나의 테이블에서 반환된 결과와 같습니다.
“동일”한 MyISAM 테이블이란, 모든 테이블이 동일한 컬럼 Data 유형과 인덱스 정보를 가지고 있음을 의미합니다.
Merge 테이블을 생성하면 MySQL은 디스크에 기본 MyISAM 테이블의 이름이 들어있는 .MRG 파일을 생성합니다. Merge 테이블의 테이블 형식은 MySQL Data Dictionary에 저장됩니다.
특징
- 컬럼이 다른 순서로 나열되거나 해당 컬럼에 동일한 Data 유형이 없거나 인덱스의 순서가 다른 MyISAM 테이블은 Merge 할 수 없습니다.
- MERGE 테이블에 Mapping되는 MyISAM 테이블에 대한 권한이 있어야만 Merge 테이블에서 Select, Delete, Update 및 Insert를 사용할 수 있습니다.
- 로그 테이블과 같은 대규모 Data Set를 쉽게 관리할 수 있으며 처리 속도가 빠릅니다. (큰 테이블을 여러 개로 나누어 다른 디스크에 저장한 후에 Merge 테이블로 실행하면 하나의 큰 테이블을 처리하는 것보다 속도가 향상됩니다.)
- 여러 테이블을 하나의 테이블로 즉시 Mapping 합니다. Merge 테이블은 개별 테이블의 인덱스를 사용하기 때문에 자체 인덱스를 유지할 필요가 없으므로 Merge 테이블 모음은 생성하거나 다시 Mapping 하는 속도가 매우 빠릅니다.
- 인덱스 읽기 속도는 느린 단점이 있습니다. (인덱스를 읽을 때 Merge 스토리지 엔진은 주어진 키와 가장 근접하게 일치하는 테이블을 확인하기 위해 모든 기본 테이블을 읽어야 합니다.)
주요 스토리지 엔진 기능 요약
Feature | MyISAM | Memory | InnoDB | Archive | NDB |
B-tree indexes | Yes | Yes | Yes | No | No |
Backup/point-in-time recovery (note 1) | Yes | Yes | Yes | Yes | Yes |
Cluster database support | No | No | No | No | Yes |
Clustered indexes | No | No | Yes | No | No |
Compressed data | Yes (Note 2) | No | Yes | Yes | No |
Data caches | No | N/A | Yes | No | Yes |
Encrypted data | Yes (Note 3) | Yes | Yes (Note 4) | Yes (Note 3) | Yes (Note 3) |
Foreign key support | No | No | Yes | No | Yes (Note 5) |
Full-text search indexes | Yes | No | Yes (Note 6) | No | No |
Geospatial data type support | Yes | No | Yes | Yes | Yes |
Geospatial indexing support | Yes | No | Yes (Note 7) | No | No |
Hash indexes | No | Yes | No (Note 8) | No | Yes |
Index caches | Yes | N/A | Yes | No | Yes |
Locking granularity | Table | Table | Row | Row | Row |
MVCC | No | No | Yes | No | No |
Replication support (note 1) | Yes | Limited (Note 9) | Yes | Yes | Yes |
Storage limits | 256TB | RAM | 64TB | None | 384EB |
T-tree indexes | No | No | No | No | Yes |
Transactions | No | No | Yes | No | Yes |
Update statistics for data dictionary | Yes | Yes | Yes | Yes | Yes |
Notes:
- 스토리지 엔진이 아닌 Server에서 구현됩니다.
- 압축된 MyISAM 테이블은 압축된 Row 포맷을 사용할 때만 지원됩니다. MyISAM에서 압축된 Row 포맷을 사용하는 테이블은 읽기 전용입니다.
- 암호화 기능을 통해 Server에서 구현됩니다.
- 암호화 기능을 통해 Server에서 구현됩니다. (MySQL 5.7 이상에서는 미사용 Data 암호화를 지원합니다.)
- Foreign key 지원은 MySQL C luster NDB 7.3 이상에서 사용할 수 있습니다.
- Full-text Index에 대한 지원은 MySQL 5.6 이상에서 사용할 수 있습니다.
- Geospatial 인덱싱 지원은 MySQL 5.7 이상에서 사용할 수 있습니다.
- InnoDB는 Adaptive Hash Index 기능을 위해 내부적으로 Hash Index를 활용합니다.
- MEMORY 스토리지 엔진은 Replication 기능이 제한됩니다.
- Replication Source Server가 종료된 후 재시작되면, 해당 MEMORY 테이블은 비어 있게 됩니다.
- Source Server가 시작 후 처음으로 지정된 MEMORY 테이블을 사용할 때, 해당 테이블에 대한 Delete 또는 Truncate table 문을 Binary Log에 작성함으로써 테이블을 비워야 함을 복제본에 알리는 이벤트를 기록합니다.
- Replication Server가 종료되었다가 다시 시작되면 해당 MEMORY 테이블도 비워지고 Delete 또는 Truncate table 문을 자신의 Binary Log에 기록하여 이후 복제본에 전달합니다.
기획 및 글 | 기술기획팀
이미지 제작 | 디자인그룹 이민석
'엑셈 경쟁력 > DB 인사이드' 카테고리의 다른 글
DB 인사이드 | MySQL Architecture - 4. Memory (0) | 2022.06.30 |
---|---|
DB 인사이드 | MySQL Architecture - 3. Thread (0) | 2022.06.30 |
DB 인사이드 | MySQL Architecture - 1. MySQL 엔진 (0) | 2022.06.30 |
DB 인사이드 | PostgreSQL Vacuum - 6. Autovacuum (4) | 2022.04.29 |
DB 인사이드 | PostgreSQL Vacuum - 5. Manual Vacuum (0) | 2022.04.29 |
댓글