MySQL 8.0에서 추가된 모든 기능

MySQL 8.0에서 추가된 모든 기능 – InnoDB

Estimated reading: 3 minutes 62 views

1. 고확장성 래치 프리 리두 로그 구현

[원본제공링크 1 2]

MySQL 8.0부터 리두 로그에 래치 프리 기술을 적용하여 성능을 대폭 향상시켰습니다. 래치로 인한 경합을 제거하여 동시에 여러 스레드가 리두 로그를 기록할 수 있게 되었고, 이는 높은 동시성 환경에서도 뛰어난 성능을 제공합니다.

2. LOB 인프라 재설계를 통한 성능 향상

[원본제공링크 1 2 3]

MySQL 8.0에서는 LOB (Large Object) 데이터 유형의 성능을 개선하기 위해 내부 저장 방식과 액세스 메커니즘을 재설계했습니다. 이를 통해 LOB 데이터의 읽기 및 쓰기 성능이 향상되었고, 저장 공간 효율성도 높아졌습니다. 특히 큰 LOB 데이터를 처리하는 애플리케이션에서 성능 향상을 체감할 수 있습니다.

3. 최첨단 잠금 스케줄러, 경합 인식 트랜잭션 스케줄링 (CATS) 사용 (미시간 대학교 기여)

[원본제공링크 1]

미시간 대학교의 연구 결과를 바탕으로 개발된 경합 인식 트랜잭션 스케줄링 (Contention Aware Transaction Scheduling) 기법을 통해 잠금 경합을 효과적으로 관리하고 트랜잭션 처리량을 향상시켰습니다. CATS는 트랜잭션 실행 전에 잠금 경합을 예측하고, 경합이 발생할 가능성이 높은 트랜잭션의 우선순위를 조정하여 데드락 발생 가능성을 줄이고 전체적인 시스템 성능을 높입니다.

CATS 알고리즘의 주요 특징:
스케줄링 가중치 부여: 각 트랜잭션이 차단하는 다른 트랜잭션의 수를 기반으로 가중치를 계산하여, 더 많은 트랜잭션을 차단하는 트랜잭션에 높은 우선순위를 부여합니다.
대기 시간 고려: 가중치가 동일한 경우, 더 오래 대기한 트랜잭션에 우선권을 부여합니다.

4. 잠금 없는 병렬 읽기를 위한 인프라 (현재 CHECK TABLE에서 사용)

[원본제공링크 1]

CHECK TABLE 명령어는 테이블의 무결성을 검사하는 데 사용되며, 특히 대용량 테이블에서는 시간이 많이 소요될 수 있습니다. MySQL 8.0.14에서는 이러한 검사의 효율성을 높이기 위해 병렬 클러스터 인덱스 읽기 기능이 도입되었습니다. 이 기능은 클러스터 인덱스를 병렬로 읽어들여 검사 속도를 높입니다.

주요 특징:
병렬 읽기 지원: 클러스터 인덱스를 여러 스레드를 사용하여 병렬로 읽어들입니다.
설정 가능: 세션 변수 innodb_parallel_read_threads를 통해 병렬 읽기에 사용할 스레드 수를 지정할 수 있습니다. 기본값은 4이며, 1로 설정하면 병렬 읽기가 비활성화됩니다
적용 범위: 현재는 CHECK TABLE 명령어에서만 적용되며, 보조 인덱스 스캔에는 적용되지 않습니다.

5. 인스턴트 컬럼 추가 및 가상 컬럼 지원

[원본제공링크 1]

인스턴트 컬럼 추가는 MySQL 8.0에서 테이블의 데이터 재작성 없이 새로운 컬럼을 추가하는 기능으로, 특히 대규모 테이블에서도 매우 빠르게 컬럼 추가가 가능합니다. 가상 컬럼(Virtual Column)은 물리적으로 저장되지 않고 계산된 값을 반환하는 컬럼으로, 데이터 무결성을 유지하면서 저장소를 절약할 수 있습니다.

6. 정보 스키마(Information Schema)를 통해 인덱스별로 버퍼 풀에 캐시된 페이지 보고

[원본제공링크 1]

MySQL 8.0에서는 INFORMATION_SCHEMA.INNODB_CACHED_INDEXES 테이블을 통해 InnoDB 버퍼 풀에 캐시된 각 인덱스의 페이지 수를 확인할 수 있습니다. 이를 통해 데이터베이스 성능 최적화를 위한 인덱스 활용 현황을 모니터링할 수 있습니다.

예시:

-- 테이블 및 인덱스별 버퍼풀에 캐시된 페이지 
SELECT
    tables.NAME AS table_name,
    indexes.NAME AS index_name,
    cached.N_CACHED_PAGES AS n_cached_pages
FROM
    INFORMATION_SCHEMA.INNODB_CACHED_INDEXES AS cached
    JOIN INFORMATION_SCHEMA.INNODB_INDEXES AS indexes ON cached.INDEX_ID = indexes.INDEX_ID
    JOIN INFORMATION_SCHEMA.INNODB_TABLES AS tables ON indexes.TABLE_ID = tables.TABLE_ID
limit 5;

-- 결과 예시
+-----------------------------------------+-----------------------------------+----------------+
| table_name                              | index_name                        | n_cached_pages |
+-----------------------------------------+-----------------------------------+----------------+
| guacamole_db/guacamole_connection_group | guacamole_connection_group_ibfk_1 |              1 |
| guacamole_db/guacamole_connection       | guacamole_connection_ibfk_1       |              1 |
| guacamole_db/guacamole_connection       | PRIMARY                           |              1 |
| minhang/aaa                             | idxid                             |           4731 |
| minhang/aaa                             | PRIMARY                           |          18990 |
+-----------------------------------------+-----------------------------------+----------------+
5 rows in set (0.00 sec)

7. Auto Increment 값의 영구 저장

[원본제공링크 1]

이전의 MySQL 버전에서는 InnoDB 테이블의 자동 증가 값이 메모리에만 저장되어, 서버를 재시작하면 해당 값이 초기화되었습니다. 이로 인해 새로운 삽입 시 기존 최대 값보다 작은 값이 할당되어 중복 키 오류가 발생하거나, 예상치 못한 값이 할당되는 문제가 있었습니다.

MySQL 8.0에서는 이러한 문제를 해결하기 위해 자동 증가 값을 디스크에 지속적으로 저장하는 방식을 도입하였습니다. 자동 증가 값이 변경될 때마다 해당 값이 redo log에 기록되며, 각 체크포인트에서 스토리지 엔진의 시스템 테이블에 저장됩니다. 이를 통해 서버 재시작 후에도 가장 최근의 자동 증가 값이 유지되어, 데이터 무결성과 일관성이 향상되었습니다.

8. SQL 문법을 사용한 UNDO 테이블스페이스 관리

[원본제공링크 1]

SQL 명령어를 통해 UNDO 테이블스페이스를 관리할 수 있게 되었습니다. CREATE UNDO TABLESPACE, ALTER UNDO TABLESPACE, DROP UNDO TABLESPACE 등의 명령을 사용하여 UNDO 테이블스페이스를 생성, 변경, 삭제할 수 있습니다.

예시:

CREATE UNDO TABLESPACE undo_001 ADD DATAFILE 'undo_001.ibt';
DROP UNDO TABLESPACE undo_001;
SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE SPACE_TYPE = 'Undo';

9. 옵티마이저에서 사용하는 새로운 인메모 임시 테이블 스토리지 엔진

[원본제공링크 1]

이전 버전의 MySQL에서는 내부 임시 테이블을 저장하기 위해 기본적으로 MEMORY 스토리지 엔진이 사용되었습니다. 그러나 MEMORY 엔진은 BLOBTEXT와 같은 대용량 데이터 타입을 지원하지 않으며, 고정 길이의 행 형식을 사용하여 메모리 효율성이 떨어지는 단점이 있었습니다.

이를 개선하기 위해 MySQL 8.0에서는 TempTable 스토리지 엔진이 도입되었습니다. TempTable 엔진은 VARCHARVARBINARY와 같은 가변 길이의 데이터 타입을 사용하여 메모리 사용을 최적화하며, BLOBTEXT 타입을 포함한 다양한 데이터 타입을 지원합니다. 또한, 메모리 사용 한도를 설정하고 이를 초과할 경우 데이터를 디스크의 임시 파일로 오버플로우하여 저장할 수 있습니다.

10. 새로운 TempTable 엔진에서 BLOB 지원

[원본제공링크 1 2]

새로운 TempTable 스토리지 엔진BLOB, TEXT와 같은 가변 길이 대규모 데이터를 지원합니다. 이전 MEMORY 엔진이 고정 크기 데이터만 처리했던 한계를 극복하여, 더 다양한 데이터 타입을 효율적으로 저장하고 처리할 수 있게 되었습니다. 이로써 대규모 데이터 작업에서의 유연성과 성능이 향상되었습니다.

11. 전용 서버 모드: 버퍼 풀과 리두 로그 크기의 자동 구성

[원본제공링크 1 2]

전용 서버 모드MySQL이 시스템 리소스를 독점적으로 사용할 때 적합한 설정을 자동으로 구성합니다. 이 모드는 서버의 총 메모리를 기반으로 InnoDB 버퍼 풀과 리두 로그 크기를 동적으로 조정하여 성능을 최적화합니다. 이를 통해 수동 설정의 번거로움을 줄이고 시스템 자원을 최대한 활용할 수 있습니다.

예시:

-- 전용 서버 모드 활성화 
SET GLOBAL innodb_dedicated_server = ON;
-- 재시작 해야 적용됩니다. 따라서 my.cnf를 수정하시는 쪽으로 적용하시면 될 것입니다.

-- 버퍼풀 및 리두로그 크기 확인
SHOW VARIABLES LIKE 'innodb_buffer_pool_size';
SHOW VARIABLES LIKE 'innodb_redo_log_capacity';

12. 버퍼 풀 뮤텍스 제거 (Percona의 기여)

[원본제공링크 1]

이전의 InnoDB 버퍼 풀은 단일 뮤텍스(buf_pool_mutex)로 보호되어 여러 데이터 구조를 동시에 관리했습니다. 이로 인해 다중 스레드 환경에서 잠금 경합이 발생하여 성능 저하의 원인이 되었습니다. InnoDB의 버퍼 풀 관리에서 사용되던 전역 뮤텍스를 제거하여 동시성 문제를 해결하고 성능을 향상시켰습니다. Percona의 기여로 구현된 이 기능은 여러 쓰레드가 동시에 버퍼 풀에 접근할 때 발생할 수 있는 병목 현상을 방지합니다. 이를 통해 트랜잭션 처리량과 데이터베이스 응답 속도가 개선됩니다.
MySQL 8.0에서는 버퍼 풀 뮤텍스를 다음과 같이 세분화하였습니다:
LRU_list_mutex: LRU 리스트 보호
free_list_mutex: 자유 리스트 및 철회 리스트 보호
zip_free_mutex: 압축 페이지를 위한 버디 할당자 보호
zip_hash_mutex: 압축 페이지 해시 및 관련 플래그 보호
flush_state_mutex: 플러시 상태 보호

13. 향상된 Purge 프로세스

[원본제공링크 1]

Purge는 InnoDB에서 트랜잭션 롤백 로그를 제거해 디스크 공간을 회수하는 작업입니다. 향상된 Purge 프로세스는 멀티 스레드 병렬 처리를 도입해 Purge의 속도를 높이고, 오래된 데이터로 인해 발생할 수 있는 잠재적인 성능 저하를 방지합니다. 이로써 대규모 트랜잭션 처리 환경에서도 데이터 정리가 효율적으로 이루어집니다.

14. 데드락 감지기 동적 활성화/비활성화

[원본제공링크 1]

데드락 감지기를 동적으로 활성화하거나 비활성화할 수 있는 기능이 추가되었습니다. 이 기능은 높은 동시성 환경에서 데드락 감지의 오버헤드를 줄이거나, 특정 상황에서 필요한 경우에만 데드락 감지를 활성화할 수 있도록 설계되었습니다. 이를 통해 성능과 유연성을 모두 확보할 수 있습니다.

예시:

SET GLOBAL innodb_deadlock_detect = ON;  -- 활성화
SET GLOBAL innodb_deadlock_detect = OFF; -- 비활성화

15. IO 레이어의 확장성과 효율성 개선

[원본제공링크 1]

입출력(IO) 레이어의 성능과 확장성이 대폭 개선되었습니다. MySQL은 비동기 IO와 쓰레드 관리 방식을 최적화하여 디스크 및 네트워크 작업의 처리량을 높이고 지연 시간을 줄였습니다. 이러한 개선은 특히 높은 동시성 환경에서 데이터베이스 성능을 안정적으로 유지하는 데 도움을 줍니다.

16. Skip 및 No-Wait를 통한 확장된 잠금 의미론

[원본제공링크 1 2]

확장된 잠금 의미론은 트랜잭션 잠금 대기 중단(Skip) 또는 즉시 실패(No-Wait) 옵션을 추가로 제공하여 유연성과 성능을 향상시켰습니다. 이를 통해 트랜잭션이 잠금 충돌로 인해 대기하지 않고, 상황에 따라 즉시 다음 작업을 시도하거나 에러를 반환할 수 있습니다. 이 기능은 높은 동시성 환경에서 데드락과 대기 시간을 줄이는 데 유용합니다.

예시:

BEGIN;
SELECT * FROM orders WHERE order_id = 123 FOR UPDATE NOWAIT;
-- 잠금 충돌 시 즉시 에러 반환

BEGIN;
SELECT * FROM orders WHERE status = 'pending' FOR UPDATE SKIP LOCKED;
-- 이미 처리 중인 작업을 건너뛰고 새로운 작업만 진행

17. 새로운 에러 로깅 인프라 사용

[원본제공링크 1]

MySQL 8.0의 새로운 오류 로깅 시스템은 컴포넌트 아키텍처를 기반으로 설계되었습니다. 이 시스템은 로그 이벤트를 처리하는 필터 컴포넌트와 로그를 특정 형식으로 출력하는 싱크 컴포넌트로 구성됩니다. 이러한 컴포넌트들은 시스템 변수인 log_error_services를 통해 로드 및 활성화됩니다.

주요 컴포넌트:
log_filter_internal: 기본 필터 컴포넌트로, 로그 이벤트의 우선순위와 오류 코드를 기반으로 필터링합니다.
log_sink_internal: 기본 싱크 컴포넌트로, 전통적인 오류 로그 형식으로 로그를 출력합니다.
log_sink_json: JSON 형식으로 로그를 출력하는 싱크 컴포넌트입니다.
log_sink_syseventlog: 시스템 로그(예: Unix 계열의 syslog, Windows의 이벤트 로그)로 로그를 출력하는 싱크 컴포넌트입니다.

18. 시스템 데이터 사전이 이제 InnoDB에 저장됨

[원본제공링크 1]

이전 버전의 MySQL에서는 테이블 정의와 같은 메타데이터를 .frm 파일과 시스템 테이블에 분산하여 저장했습니다. 그러나 MySQL 8.0부터는 이러한 메타데이터를 InnoDB 기반의 통합 데이터 사전에 저장하여 관리합니다. 시스템 데이터 사전(System Data Dictionary)InnoDB 테이블로 저장되면서, MySQL의 메타데이터 관리가 통합되었습니다. 이로 인해 테이블 및 스키마 정보를 보다 효율적으로 관리할 수 있으며, 데이터 일관성과 복구 가능성이 향상되었습니다.

19. 더 작은 코어 파일 생성을 위한 새로운 구성

[원본제공링크 1]

코어 파일은 프로세스의 메모리 이미지와 상태를 기록하여, 비정상 종료 시 디버깅에 활용됩니다. 그러나 대용량 InnoDB 버퍼 풀을 사용하는 시스템에서는 코어 파일이 매우 커질 수 있어, 생성 시간 증가와 디스크 공간 부족 등의 문제가 발생할 수 있습니다.

이를 해결하기 위해 MySQL 8.0.14에서는 innodb_buffer_pool_in_core_file 변수를 도입하였습니다. 이 변수를 OFF로 설정하면, 코어 덤프에서 InnoDB 버퍼 풀 페이지를 제외하여 코어 파일 크기를 줄일 수 있습니다.

20. 파티션 테이블에서 공유 테이블스페이스 지원 중단

[원본제공링크 1]

이전에는 파티션 테이블의 각 파티션을 공유 테이블스페이스에 저장할 수 있었습니다. 그러나 공유 테이블스페이스에서 일부 테이블은 암호화되고, 일부는 암호화되지 않는 상황을 효과적으로 관리할 수 있는 메커니즘이 부족했습니다. 이로 인해 데이터 보안 및 일관성에 문제가 발생할 수 있었습니다.

이를 해결하기 위해 MySQL 5.7.24에서는 파티션을 공유 테이블스페이스에 저장할 때 경고를 발생시키도록 하였으며, MySQL 8.0.13부터는 이러한 지원을 완전히 제거하였습니다. 따라서 파티션 테이블의 각 파티션은 파일별 테이블스페이스에 저장되어야 합니다.

21. 온라인으로 임시 테이블스페이스 디스크 공간 회수

[원본제공링크 1]

이전에는 모든 임시 테이블이 글로벌 임시 테이블스페이스(ibtmp1)에 저장되었으며, 이로 인해 디스크 공간이 증가하면 서버를 재시작해야만 공간을 회수할 수 있었습니다. MySQL 8.0부터는 각 세션마다 별도의 세션 임시 테이블스페이스가 할당되어, 세션이 종료되면 해당 테이블스페이스가 자동으로 정리되고 디스크 공간이 반환됩니다. 이를 통해 서버를 재시작하지 않고도 임시 테이블로 인한 디스크 공간 증가를 효과적으로 관리할 수 있습니다

22. 유휴 상태에서 쓰기 IOPs를 제어하기 위한 새로운 옵션

[원본제공링크 1]

이전에는 InnoDB가 유휴 상태에서도 innodb_io_capacity에 설정된 값의 100%로 쓰기 I/O 작업을 수행하여, 불필요한 디스크 쓰기가 발생하고 스토리지 장치의 수명이 단축되는 문제가 있었습니다. 이를 개선하기 위해 innodb_idle_flush_pct 변수가 도입되었습니다.

innodb_idle_flush_pct는 InnoDB가 유휴 상태일 때 innodb_io_capacity의 몇 퍼센트로 쓰기 I/O 작업을 수행할지 결정합니다. 기본값은 100으로, 이는 기존 동작과 동일합니다. 이 값을 낮추면 유휴 시 쓰기 I/O 작업이 감소하여 스토리지 장치의 수명을 연장할 수 있습니다.

예시:

set global innodb_idle_flush_pct=0; 
-- 해당 값은 innodb_io_capacity 설정에 대한 비율이며, 100보다 적게 설정하면, 해당 비율 이상의 유휴 상태에서는 디스크 플러쉬를 멈춥니다.

23. 히스토그램을 위한 테이블 데이터 샘플링 지원

[원본제공링크 1]

히스토그램 생성을 위해 테이블 데이터의 샘플링을 지원합니다. 히스토그램은 데이터 분포를 표현하는 통계 도구로, MySQL 옵티마이저가 데이터 분포를 더 정확하게 파악하여 쿼리 실행 계획을 개선할 수 있습니다.

예시:

ANALYZE TABLE products UPDATE HISTOGRAM ON price WITH 256 BUCKETS;

24. 파티션 테이블의 대소문자 구분 없는 이름 지원

[원본제공링크 1]

이전에는 파티션 및 서브파티션 이름이 대소문자를 구분하여 처리되었습니다. 그러나 MySQL 8.0부터는 이러한 이름들을 대소문자를 구분하지 않고 처리하며, 내부적으로는 소문자로 저장합니다. 예를 들어, 사용자가 ‘PART_1’이라는 파티션을 생성하면, MySQL은 이를 ‘part_1’으로 저장하고 대소문자 구분 없이 인식합니다.

25. 개선된 CATS 구현 (잠금 관리자)

[원본제공링크 1]

경합 인식 트랜잭션 스케줄링(CATS)의 구현이 더욱 향상되어 락 관리자의 성능과 효율성이 개선되었습니다. InnoDB는 트랜잭션이 잠금을 기다릴 때, 각 트랜잭션이 차단하고 있는 다른 트랜잭션의 수를 기반으로 스케줄링 가중치를 할당합니다. 예를 들어, 두 개의 트랜잭션이 동일한 객체에 대한 잠금을 기다리고 있을 때, 더 많은 트랜잭션을 차단하고 있는 트랜잭션이 더 높은 가중치를 부여받아 우선적으로 잠금을 획득합니다. 만약 가중치가 동일하다면, 더 오래 기다린 트랜잭션이 우선권을 가집니다

26. Lock-sys 최적화: 샤드 기반 lock_sys 뮤텍스

[원본제공링크 1]

락 시스템(lock_sys)뮤텍스를 샤딩(sharding)하여 병렬 처리 성능을 향상시켰습니다. 이전에는 InnoDB의 lock_sys 뮤텍스가 단일 뮤텍스로 구현되어, 여러 스레드가 동시에 잠금 큐에 접근할 때 병목이 발생할 수 있었습니다. MySQL 8.0.21에서는 이러한 문제를 해결하기 위해 lock_sys 뮤텍스를 샤딩하여, 잠금 큐를 테이블 및 페이지 잠금 큐 샤드로 그룹화하고, 각 샤드를 전용 뮤텍스로 보호하도록 개선하였습니다.

27. 원자적 쓰기를 보장하기 위해 더블 라이트 버퍼를 별도 파일로 저장

[원본제공링크 1]

데이터 무결성을 향상시키기 위해 이중 쓰기 버퍼(doublewrite buffer)를 별도의 파일에 작성하도록 변경되었습니다. 이중 쓰기 버퍼는 InnoDB 스토리지 엔진이 페이지 쓰기 도중 발생할 수 있는 찢어진 페이지(torn page) 문제를 방지하기 위해 사용합니다. 이전에는 이중 쓰기 버퍼가 시스템 테이블스페이스 내에 위치하여, 모든 데이터가 동일한 스토리지 장치에 기록되었습니다. 그러나 MySQL 8.0.20부터는 이중 쓰기 버퍼를 별도의 파일로 분리하여, 더 빠른 스토리지 장치에 저장할 수 있게 되었습니다.

28. 리두 로그의 전역 활성화/비활성화

[원본제공링크 1]

리두 로그(redo log)를 전역적으로 활성화하거나 비활성화할 수 있는 옵션이 추가되었습니다. 이는 특정 상황에서 리두 로그를 비활성화하여 데이터 복구와 무결성이 필요하지 않은 작업(예: 대량 데이터 로드)에서 성능을 높일 수 있습니다. 작업 완료 후 다시 활성화할 수 있습니다.

예시:

SET GLOBAL innodb_redo_log_enabled = OFF;

29. UNDO 테이블스페이스의 CREATE/TRUNCATE 작업이 리두 로그에 기록됨

[원본제공링크 1]

MySQL 8.0.21부터 UNDO 테이블스페이스생성(CREATE) 및 잘림(TRUNCATE) 작업이 REDO 로그에 기록됩니다. 이로 인해 이러한 작업의 내구성이 향상되고, 시스템 충돌 시에도 데이터 무결성이 보장됩니다.

30. 테이블스페이스 파일 이름 검증을 선택적으로 변경

[원본제공링크 1]

기본적으로 InnoDB는 서버 시작 시 innodb_directories 변수에 정의된 디렉토리를 스캔하여 테이블스페이스 파일을 찾고, 발견된 파일의 경로를 데이터 딕셔너리에 기록된 경로와 비교하여 일치하지 않을 경우 데이터를 업데이트합니다. 이러한 경로 검증은 테이블스페이스 파일이 많은 시스템에서 서버 시작 시간을 지연시킬 수 있습니다.

innodb_validate_tablespace_paths 변수를 사용하면 이러한 경로 검증을 비활성화할 수 있습니다. 이 기능은 테이블스페이스 파일이 수동으로 이동되지 않는 환경, 예를 들어 관리형 서비스에서 유용합니다. 경로 검증을 비활성화하면 서버 시작 시 테이블스페이스 파일 경로를 확인하지 않으므로, 테이블스페이스 파일이 많은 시스템에서 시작 시간이 크게 단축될 수 있습니다.

예시:

SHOW VARIABLES LIKE 'innodb_validate_tablespace_paths';

31. 테이블스페이스를 지정된 디렉터리로 제한

[원본제공링크 1 2]

MySQL 8.0.21부터 테이블스페이스 파일의 생성 및 사용이 지정된 디렉토리로 제한되었습니다. 이를 통해 데이터 보안과 무결성을 강화하고, 테이블스페이스 파일의 관리와 모니터링을 용이하게 합니다.

예시:

  • 테이블스페이스 디렉터리를 innodb_directories 옵션으로 지정합니다.
[mysqld]
innodb_directories=/path/to/directory1;/path/to/directory2

Leave a Comment



이 문서 공유

MySQL 8.0에서 추가된 모든 기능 – InnoDB

링크 복사

CONTENTS