본문 바로가기

MySQL/8.0 New Feature

MySQL 8.0 Atomic DDL (data definition statement)

1. 개요

8.0 에서 새롭게 "Atomic Data Definition Statement Support" 에 대한 내용이 소개 되었다.

 

2. Atomic DDL

1) 지원되는 DDL 문

Atomic DDL 기능은 DDL 이 지원되는 테이블과 지원되지 않는 테이블 모두 지원한다.

  1. table DDL Statement : CREATE / ALTER / DROP ( for databases, tablespaces, tables, indexes, truncate table )
  2. non-table DDL Statement : stored programs, triggers, views, user-defined functions
  3. user management Statement : CREATE / ALTER / DROP / RENAME / GRANT / REVOKE

 

 

2) Atomic DDL 의 특성

  1. metadata 업데이트 / binary log 쓰기 / Storage Engine 작업은 단일 트랜잭션으로 사용된다.
  2. DDL 작업 중 SQL parse 에는 중간 커밋이 없다.
  3. 적용되는 내용들
    - Data Dictionary, Routine, event, UDF(user-defined) 등의 cache 상태는 DDL operation 의 커밋 / 롤백 여부에 일치된다. (DDL operation 에 따라 즉시 반영)
    - 스토리지엔진은 "Post-DDL" 단계에서 DDL 작업의 redo 및 rollback 을 지원한다.
    - DDL 작업의 보이는 동작은 Atomic 이며, 일부 DDL Operation 들의 동작은 변경되었다. ("Changes in DDL Statement Behavior") 

 

※ Exam 1. Table Drop

** in 5.7
mysql> CREATE TABLE t1 (c1 INT);
mysql> DROP TABLE t1, t2;
ERROR 1051 (42S02): Unknown table 'test.t2'

mysql> SHOW TABLES; Empty set (0.00 sec)

** in 8.0
mysql> CREATE TABLE t1 (c1 INT);
mysql> DROP TABLE t1, t2;
ERROR 1051 (42S02): Unknown table 'd1.t2'

mysql> SHOW TABLES;
+----------------+
| Tables_in_test |
+----------------+

| t1 |
+----------------+

  • 여러 개의 drop database 도 위 예시 처럼 atmoic 처리된다.
  • 그러나 파일 시스템에서 database 디렉토리 제거 작업은 Atomic 처리에 포함되지않는다. (= 롤백 불가)

 

※ Exam 2. User Manage

** in 5.7
mysql> CREATE USER userA;
mysql> CREATE USER userA, userB;
ERROR 1396 (HY000): Operation CREATE USER failed for 'userA'@'%'

mysql> SELECT User FROM mysql.user WHERE User LIKE 'user%';
+-------+
| User |
+-------+

| userA |
| userB |
+-------+

** in 8.0
mysql> CREATE USER userA;
mysql> CREATE USER userA, userB;
ERROR 1396 (HY000): Operation CREATE USER failed for 'userA'@'%'

mysql> SELECT User FROM mysql.user WHERE User LIKE 'user%';
+-------+
| User |
+-------+

| userA |
+-------+

  • 예시와 같이 계정 생성 문의 부분 실행은 허용되지 않는다.
  • 5.7 에서는 부분 실행이 허용되기때문에 binary log 에는 "create user userA, userB" 를 사용하는 구문으로 남는다.
  • 8.0 에서 replication 을 통해 해당 구문을 가져오면 userB 의 경우 만들어지지않는다.
  • IF EXISTS / IF NOT EXISTS 를 사용하여 해결가능하다.

 

3. 지원되는 스토리지엔진

  • 현재는 InnoDB 만 Atomic DDL 을 지원한다.
  •  DDL 작업의 redo / rollback 을 위해 DDL 로그를 "mysql.innodb_ddl_log" 라는 Data Dictionary 공간에 write 한다.
  • innodb_ddl_log 는 "mysql.ibd" 파일에 숨겨져있는 테이블이다.
  • Innodb 엔진은 Commit 단계 전에 Prepare 및 Perform 단계를 수행한다.

 

DDL Parse

  1. Prepare : mysql.innodb_ddl_log 라는 system table 에 "roll forward+roll back" 을 위한 DDL Operation 을 정의한다.
  2. Perform : 실제 DDL Operation 수행 (ex. create table / drop table ... )
  3. Commit : Data Dictionary 를 갱신하고 Data Dictionary Transaction 을 Commit
  4. Post-DDL : 1번에서 정의한 DDL operation 을 실행하고 삭제, Post-DDL 단계에서 DROP TABLE / TRUNCATE TABLE 같이 테이블을 rollback 할 필요성이 있는 DDL 들을 지원하는 "mysql.innodb_dynamic_metadata" 의 dynamic metadata 를 삭제한다.

※ DDL Log 는 트랜잭션의 commit/rollback 여부와 상관없이 "Post-DDL" 단계에서 innodb_ddl_table 의 내용을 실행하고 삭제한다. 즉, DDL 작업 중에 서버가 중지 된 경우 DDL 로그는 테이블에 남아있어야 한다. (For Crash Recovery)

 

 

4. Viewing DDL Log

"innodb_print_ddl_logs = ON" 이 되면 DDL logs 를 stderr 로 쓴다.

매뉴얼 상에는 위 옵션만 ON 시키는 것으로 나와있지만,

 

set global log_error_verbosity = 3;

 

위 옵션도 같이 세팅해주어야한다.

 

 

> SET GLOBAL innodb_print_ddl_log = 1;
> SET GLOBAL log_error_verbosity = 3;

$ vi mysql.err
2019-03-13T11:57:12.639120+09:00 14 [Note] [MY-012475] [InnoDB] DDL log insert : [DDL record: DROP, id=78874, thread_id=14, table_id=16832]

2019-03-13T11:57:12.639831+09:00 14 [Note] [MY-012473] [InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=78875, thread_id=14, space_id=15775, old_file_path=./d1/t1.ibd] 2019-03-13T11:57:12.662668+09:00 14 [Note] [MY-012485] [InnoDB] DDL log post ddl : begin for thread id : 14

2019-03-13T11:57:12.662885+09:00 14 [Note] [MY-012479] [InnoDB] DDL log replay : [DDL record: DELETE SPACE, id=78875, thread_id=14, space_id=15775, old_file_path=./d1/t1.ibd] 2019-03-13T11:57:12.664149+09:00 14 [Note] [MY-012479] [InnoDB] DDL log replay : [DDL record: DROP, id=78874, thread_id=14, table_id=16832]

2019-03-13T11:57:12.666878+09:00 14 [Note] [MY-012486] [InnoDB] DDL log post ddl : end for thread id : 14

 

 

'MySQL > 8.0 New Feature' 카테고리의 다른 글

MySQL 8.0 binlog_row_value_options (JSON Type option)  (0) 2020.02.10
MySQL 8.0 binlog_row_metadata  (1) 2020.01.29
MySQL 8.0 Optimizer Trace  (1) 2020.01.17
Descending Index  (0) 2019.02.18