1. 개요
8.0 에서 새롭게 "Atomic Data Definition Statement Support" 에 대한 내용이 소개 되었다.
2. Atomic DDL
1) 지원되는 DDL 문
Atomic DDL 기능은 DDL 이 지원되는 테이블과 지원되지 않는 테이블 모두 지원한다.
- table DDL Statement : CREATE / ALTER / DROP ( for databases, tablespaces, tables, indexes, truncate table )
- non-table DDL Statement : stored programs, triggers, views, user-defined functions
- user management Statement : CREATE / ALTER / DROP / RENAME / GRANT / REVOKE
2) Atomic DDL 의 특성
- metadata 업데이트 / binary log 쓰기 / Storage Engine 작업은 단일 트랜잭션으로 사용된다.
- DDL 작업 중 SQL parse 에는 중간 커밋이 없다.
- 적용되는 내용들
- 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
- Prepare : mysql.innodb_ddl_log 라는 system table 에 "roll forward+roll back" 을 위한 DDL Operation 을 정의한다.
- Perform : 실제 DDL Operation 수행 (ex. create table / drop table ... )
- Commit : Data Dictionary 를 갱신하고 Data Dictionary Transaction 을 Commit
- 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 |