Loading...
MySQL 9.5 Reference Manual 9.5의 18.3 The MEMORY Storage Engine의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
MEMORY 스토리지 엔진(이전 이름은
HEAP)은 내용을 메모리에 저장하는 특수 목적의 테이블을 생성합니다. 데이터는 크래시, 하드웨어 문제, 전원 장애에 취약하므로, 이러한 테이블은 임시 작업 영역이나 다른 테이블에서 가져온 데이터를 위한 읽기 전용 캐시 용도로만 사용해야 합니다.
Table 18.4 MEMORY Storage Engine Features
| Feature | Support |
|---|---|
| B-tree indexes | Yes |
| Backup/point-in-time recovery (스토리지 엔진이 아닌 서버에서 구현됨.) | Yes |
| Cluster database support | No |
| Clustered indexes | No |
| Compressed data | No |
| Data caches | N/A |
| Encrypted data | Yes (암호화 함수를 통해 서버에서 구현됨.) |
| Foreign key support | No |
| Full-text search indexes | No |
| Geospatial data type support | No |
| Geospatial indexing support | No |
| Hash indexes | Yes |
| Index caches | N/A |
| Locking granularity | Table |
| MVCC | No |
| Replication support (스토리지 엔진이 아닌 서버에서 구현됨.) | Limited (이 섹션 후반부의 설명을 참조하십시오.) |
| Storage limits | RAM |
| T-tree indexes | No |
| Transactions | No |
| Update statistics for data dictionary | Yes |
| Feature | Support |
|---|
중요하고, 고가용성이 필요하거나, 자주 업데이트되는 데이터를 위해
MEMORY 스토리지 엔진을 사용하는 애플리케이션을 배포하려는 개발자는 NDB
Cluster가 더 나은 선택인지 고려해야 합니다. MEMORY
엔진의 전형적인 사용 사례는 다음과 같은 특성을 갖습니다:
세션 관리나 캐싱과 같이 순간적이고 중요하지 않은 데이터를 다루는 작업. MySQL 서버가 중지되거나
재시작되면, MEMORY 테이블의 데이터는
소실됩니다.
빠른 접근과 낮은 지연 시간을 위한 인메모리 저장소. 데이터 양은 운영체제가 가상 메모리 페이지를 스와핑하지 않고도 전부 메모리에 들어갈 수 있어야 합니다.
읽기 전용 또는 대부분 읽기 위주의 데이터 접근 패턴(제한적인 업데이트).
NDB Cluster는 MEMORY
엔진과 동일한 기능을 더 높은 성능 수준으로 제공하며,
MEMORY에는 없는 추가 기능도 제공합니다:
클라이언트 간 경합을 낮추기 위한 로우 수준 잠금 및 멀티스레드 연산.
쓰기가 포함된 구문 혼합에서도 확장 가능성.
데이터 영속성을 위한 선택적 디스크 기반 연산.
단일 장애 지점이 없는 공유-없음 아키텍처와 멀티 호스트 연산으로 99.999% 가용성 제공.
노드 전체에 대한 자동 데이터 분산; 애플리케이션 개발자는 커스텀 샤딩 또는 파티셔닝 솔루션을 직접 만들 필요가 없습니다.
MEMORY 테이블은 파티셔닝할 수 없습니다.
MEMORY의 성능은 업데이트를 처리할 때 싱글 스레드 실행과 테이블 잠금 오버헤드에서
발생하는 경합에 의해 제약됩니다. 이는 부하가 증가할 때, 특히 쓰기가 포함된 구문 혼합의 경우
확장성을 제한합니다.
MEMORY 테이블에 대해 인메모리 처리를 수행함에도 불구하고, 일반적인 용도의 쿼리나
읽기/쓰기가 혼합된 워크로드가 있는 바쁜 서버에서는
InnoDB 테이블보다 반드시 더 빠른 것은 아닙니다. 특히, 업데이트를 수행할 때 수반되는 테이블 잠금은
여러 세션에서 MEMORY 테이블을 동시에 사용할 때 속도를 떨어뜨릴 수 있습니다.
MEMORY 테이블에 대해 수행되는 쿼리 종류에 따라, 인덱스를 기본 해시 데이터 구조(고유 키를 기준으로 단일 값을 검색하는 경우)로 생성하거나, 모든 종류의 쿼리(등호, 부등호, 보다 작음 또는 보다 큼과 같은 범위 연산자를 포함)에 사용할 수 있는 범용 B-tree 데이터
구조로 생성할 수 있습니다. 다음 섹션에서는 두 종류의 인덱스를 생성하기 위한 구문을 설명합니다. 흔한 성능 문제는, B-tree 인덱스가 더 효율적인 워크로드에서 기본 해시 인덱스를 사용하는 것입니다.
MEMORY 스토리지 엔진은 디스크에 어떠한 파일도 생성하지 않습니다. 테이블 정의는 MySQL 데이터
사전에 저장됩니다.
MEMORY 테이블은 다음과 같은
특성을 가집니다:
MEMORY 테이블을 위한 공간은 작은 블록 단위로 할당됩니다. 테이블은 삽입에 대해 100% 동적 해싱을 사용합니다. 오버플로 영역이나 추가 키 공간은 필요하지 않습니다. 프리 리스트를 위한 추가 공간도 필요하지 않습니다. 삭제된 로우는 링크드 리스트에 저장되며, 테이블에 새 데이터를 삽입할 때 재사용됩니다.
MEMORY 테이블에는 해시 테이블에서 흔히 발생하는 삭제와 삽입 조합 관련 문제가 없습니다.
MEMORY 테이블은 고정 길이
로우 저장 형식을 사용합니다.
VARCHAR와 같은 가변 길이 타입은
고정 길이로 저장됩니다.
MEMORY는
AUTO_INCREMENT 열을 지원합니다.
non-TEMPORARY``MEMORY
테이블은 다른 non-TEMPORARY 테이블과 마찬가지로 모든 클라이언트 간에 공유됩니다.
MEMORY 테이블을 생성하려면
CREATE TABLE 구문에
ENGINE=MEMORY 절을 지정합니다.
1CREATE TABLE t (i INT) ENGINE = MEMORY;
엔진 이름에서 알 수 있듯이, MEMORY 테이블은 메모리에 저장됩니다. 이 테이블은 기본적으로 해시 인덱스를 사용하므로, 단일 값 조회에 매우 빠르며, 임시 테이블을 생성하는 데 매우 유용합니다. 그러나 서버가 종료되면,
MEMORY 테이블에 저장된 모든 로우는 소실됩니다.
테이블 자체는 정의가 MySQL 데이터 사전에 저장되므로 계속 존재하지만, 서버가 재시작되면 비어 있게 됩니다.
다음 예제는 MEMORY 테이블을 생성하고, 사용하고, 제거하는 방법을 보여줍니다:
1mysql> CREATE TABLE test ENGINE=MEMORY 2 SELECT ip,SUM(downloads) AS down 3 FROM log_table GROUP BY ip; 4 5mysql> SELECT COUNT(ip),AVG(down) FROM test; 6 7mysql> DROP TABLE test;
MEMORY 테이블의 최대 크기는 기본값 16MB인
max_heap_table_size 시스템
변수에 의해 제한됩니다.
MEMORY 테이블에 대해 서로 다른 크기 제한을 적용하려면 이 변수의 값을 변경하십시오.
CREATE TABLE 시점 또는 이후의
ALTER TABLE 또는
TRUNCATE TABLE 시점에 유효한 값이 테이블의 수명 동안 사용됩니다. 서버 재시작 시에도 기존
MEMORY 테이블의 최대 크기는 글로벌
max_heap_table_size 값으로 설정됩니다. 개별 테이블에 대해 크기를 설정하는 방법은 이 섹션 후반에서 설명합니다.
MEMORY 스토리지 엔진은
HASH와 BTREE 인덱스를 모두 지원합니다.
다음과 같이 USING 절을 추가하여 특정 인덱스에 대해 둘 중 하나를 지정할 수 있습니다:
1CREATE TABLE lookup 2 (id INT, INDEX USING HASH (id)) 3 ENGINE = MEMORY; 4CREATE TABLE lookup 5 (id INT, INDEX USING BTREE (id)) 6 ENGINE = MEMORY;
B-tree와 해시 인덱스의 일반적인 특성에 대해서는 Section 10.3.1, “How MySQL Uses Indexes”를 참조하십시오.
MEMORY 테이블은 테이블당 최대 64개의 인덱스, 인덱스당 16개의 열, 그리고 최대 키 길이 3072
바이트를 가질 수 있습니다.
MEMORY 테이블의 해시 인덱스에 키 중복도가 높은 경우(동일한 값을 포함하는 인덱스 엔트리가 많은 경우), 키 값을 변경하는 업데이트와 모든 삭제 작업이 상당히 느려집니다. 이러한 속도 저하는 중복도의 정도에 비례합니다(또는 인덱스 카디널리티에 반비례). 이 문제를 피하려면 BTREE 인덱스를 사용할 수 있습니다.
MEMORY 테이블은 비고유(nonunique) 키를 가질 수 있습니다. (이는 해시 인덱스 구현에서는 흔하지 않은 기능입니다.)
인덱스가 설정된 열에는 NULL
값을 포함할 수 있습니다.
MEMORY 테이블의 내용은 메모리에 저장되며, 이는 쿼리를 처리하는 동안 서버가 실시간으로 생성하는 내부 임시 테이블과 공유하는 속성입니다. 그러나 두 테이블 유형은
MEMORY 테이블은 스토리지 변환 대상이 아닌 반면, 내부 임시 테이블은 그렇다는 점에서 차이가 있습니다:
내부 임시 테이블이 너무 커지면, 서버는 Section 10.4.4, “Internal Temporary Table Use in MySQL”에 설명된 대로 자동으로 디스크 기반 스토리지로 변환합니다.
사용자가 생성한 MEMORY 테이블은 디스크 테이블로 변환되지 않습니다.
MySQL 서버가 시작될 때 MEMORY 테이블을 채우려면
init_file 시스템 변수를 사용할 수 있습니다. 예를 들어, 영속적인 데이터 소스에서 테이블을 로드하기 위해
INSERT INTO ...\\ SELECT 또는 LOAD DATA와 같은 구문을 파일에 넣고,
init_file을 사용하여 그 파일 이름을 지정할 수 있습니다.
Section 7.1.8, “Server System Variables” 및
Section 15.2.9, “LOAD DATA Statement”를 참조하십시오.
복제 소스 서버가 종료되었다가 재시작되면, 그 서버의
MEMORY 테이블은 비어 있게 됩니다. 이 효과를 레플리카에 복제하기 위해, 소스가 시작 이후 특정
MEMORY 테이블을 처음 사용할 때, 해당 테이블을 비워야 함을 레플리카에 알리는 이벤트를 기록하기 위해 그 테이블에 대한 TRUNCATE\\ TABLE 구문을 바이너리 로그에 기록합니다. 레플리카 서버가 종료되었다가 재시작될 때에도 그 서버의
MEMORY 테이블은 비게 되며, 그 서버는 자체 바이너리 로그에
TRUNCATE TABLE 구문을 기록하고, 이는 모든 다운스트림 레플리카에 전달됩니다.
복제 토폴로지에서 MEMORY 테이블을 사용하는 경우, 몇몇 상황에서는 소스의 테이블과 레플리카의 테이블이 서로 다를 수 있습니다. 이러한 각 상황을 처리하여 오래된 읽기나 오류를 방지하는 방법에 대한 정보는
Section 19.5.1.22, “Replication and MEMORY Tables”를 참조하십시오.
서버는 동시에 사용되는 모든
MEMORY 테이블을 유지할 수 있을 만큼 충분한 메모리가 필요합니다.
MEMORY 테이블에서 개별 로우를 삭제하더라도 메모리는 회수되지 않습니다. 메모리는 전체 테이블이 삭제될 때만 회수됩니다. 이전에 삭제된 로우에 사용되었던 메모리는 같은 테이블 내의 새로운 로우에 대해 재사용됩니다.
더 이상 MEMORY 테이블의 내용이 필요 없을 때 해당 테이블이 사용하던 모든 메모리를 해제하려면,
DELETE 또는
TRUNCATE TABLE을 실행하여 모든 로우를 제거하거나, DROP\\ TABLE을 사용하여 테이블 자체를 제거하십시오. 삭제된 로우가 사용하던 메모리를 해제하려면,
ALTER TABLE ENGINE=MEMORY를 사용하여 테이블 재구성을 강제하십시오.
MEMORY 테이블에서 로우 하나에 필요한 메모리는 다음 식을 사용하여 계산됩니다:
1SUM_OVER_ALL_BTREE_KEYS(max_length_of_key + sizeof(char*) * 4) 2+ SUM_OVER_ALL_HASH_KEYS(sizeof(char*) * 2) 3+ ALIGN(length_of_row+1, sizeof(char*))
ALIGN()은 로우 길이가
char 포인터 크기의 정확한 배수가 되도록 반올림하는 요소를 나타냅니다.
sizeof(char*)는 32-bit 머신에서 4, 64-bit 머신에서 8입니다.
앞서 언급했듯이,
max_heap_table_size 시스템
변수은 MEMORY 테이블의 최대 크기 한도를 설정합니다. 개별 테이블의 최대 크기를 제어하려면 각 테이블을 생성하기 전에 이 변수의 세션 값을 설정하십시오. (MEMORY 테이블이 모든 클라이언트에 의해 생성될 때 해당 값이 사용되기를 의도하지 않는 한, 글로벌
max_heap_table_size 값을 변경하지 마십시오.) 다음 예제는 최대 크기가 각각 1MB와 2MB인 두 개의
MEMORY 테이블을 생성합니다:
1mysql> SET max_heap_table_size = 1024*1024; 2Query OK, 0 rows affected (0.00 sec) 3 4mysql> CREATE TABLE t1 (id INT, UNIQUE(id)) ENGINE = MEMORY; 5Query OK, 0 rows affected (0.01 sec) 6 7mysql> SET max_heap_table_size = 1024*1024*2; 8Query OK, 0 rows affected (0.00 sec) 9 10mysql> CREATE TABLE t2 (id INT, UNIQUE(id)) ENGINE = MEMORY; 11Query OK, 0 rows affected (0.00 sec)
서버가 재시작되면 두 테이블 모두 서버의 글로벌
max_heap_table_size 값으로 되돌아갑니다.
또한 MEMORY 테이블에 대해
CREATE TABLE 구문에서 MAX_ROWS 테이블 옵션을 지정하여 저장할 계획인 로우 수에 대한 힌트를 제공할 수 있습니다. 이는 테이블이 여전히 최대 테이블 크기에 대한 제약 조건으로 작용하는
max_heap_table_size 값을 넘어 성장하도록 허용하지는 않습니다.
MAX_ROWS를 최대한 유연하게 사용하려면, 각 MEMORY 테이블이 성장할 수 있기를 원하는 값만큼
max_heap_table_size를 최소한 그 이상으로 설정하십시오.
MEMORY 스토리지 엔진 전용 포럼은 https://forums.mysql.com/list.php?92에서 이용할 수 있습니다.
18.2.4 MyISAM Table Problems
18.4 The CSV Storage Engine