본문 바로가기

MySQL/8.0 New Feature

MySQL 8.0 binlog_row_value_options (JSON Type option)

1. binlog_row_value_options

해당 parameter 는 MySQL 8.0.3 에 적용된 신규 옵션이다.
JSON document 를 update 시 효과적인 binary log 공간을 확보하기위해 도입된 개념이다.

 

default 값은 " " (공백) 값이며,
Valid Values 는 "PARTIAL_JSON" 이다.

 

  • Scope : Global / Session Dynamic : Yes
  • Default : ' '
  • Valid Values : PARTIAL_JSON

 

1) MySQL 8.0.3

JSON 데이터 형태는 JSON 필드를 update 시에, 변경되는 key 와 value 가 아닌, JSON 필드의 모든 key : value 형태가 binary log 에 작성되었다. 무조건 모든 value 들을 setting 하기때문에, binary log 공간을 많이 사용할 수 밖에 없는 형태이다. (key:value 값이 1,2개가 아닌 이상..)

 

2) MySQL 8.0.3 이후

binlog_row_value_options 라는 신규 parameter 가 생겼고, 해당 옵션을 이용하여 "PARTIAL_JSON" 이라는 value 를 사용할 수 있다. "PARTIAL_JSON" 옵션을 설정 시, JSON update 에서 사용되는 function 형태로 로깅을 할 수 있다.

 

 

2. binlog_row_value_options 시 binary log 변화

1) TEST DATA

> create table t1 (c1 JSON);

> insert into t1 values ('{"txt1": "my name is uzi!", "txt2": "my real name is wooseok, lee", "txt3": "my first name is wooseok", "txt4": "my last name is lee"}');


> select * from t1;
+------------------------------------------------------------------------------------------------------- ---------------------------------+
| c1 |
+------------------------------------------------------------------------------------------------------- ---------------------------------+
| {"txt1": "my name is uzi!", "txt2": "my real name is wooseok, lee", "txt3": "my first name is wooseok", "txt4": "my last name is lee"} |
+------------------------------------------------------------------------------------------------------- ---------------------------------+

 

 

2) binlog_row_value_options=" "

" UPDATE 구문 실행 "

> UPDATE t1
SET c1 = JSON_REPLACE (`c1`, '$.txt1', 'no name'); WHERE JSON_EXTRACT(`c1` , '$.txt1') like '%uzi%';

> select * from t1;
+------------------------------------------------------------------------------------------------------- -------------------------+
| c1 |
+------------------------------------------------------------------------------------------------------- -------------------------+
| {"txt1": "no name", "txt2": "my real name is wooseok, lee", "txt3": "my first name is wooseok", "txt4": "my last name is lee"} |
+------------------------------------------------------------------------------------------------------- -------------------------+

" binary log 확인 "

'/*!*/;
### UPDATE `d1`.`t1`
### WHERE
### @1='{"txt1": "my name is uzi!", "txt2": "my real name is wooseok, lee", "txt3": "my first name is wooseok", "txt4": "my last name is lee"}' /* JSON meta=4 nullable=1 is_null=0 */
### SET
### @1='{"txt1": "no name", "txt2": "my real name is wooseok, lee", "txt3": "my first name is wooseok", "txt4": "my last name is lee"}' /* JSON meta=4 nullable=1 is_null=0 */

→ update 구문에서 "SET" 부분을 보면, JSON_REPLACE 하는 key 가 아닌 모든 key:value 가 나열되는 것을 볼 수 있다.

 

3) binlog_row_value_options="PARTIAL_JSON"

" 옵션 설정 "

> set global binlog_row_value_options=partial_json;

> show global variables like 'binlog_row_value%';
+--------------------------+--------------+
| Variable_name | Value |
+--------------------------+--------------+

| binlog_row_value_options | PARTIAL_JSON |
+--------------------------+--------------+


> flush logs;

" UPDATE 구문 실행 "

> UPDATE t1
SET c1 = JSON_REPLACE (`c1`, '$.txt1', 'my name is uzi!') WHERE JSON_EXTRACT(`c1` , '$.txt1') like '%no name%';

> select * from t1;
+------------------------------------------------------------------------------------------------------- -------------------------+
| c1 |
+------------------------------------------------------------------------------------------------------- -------------------------+
| {"txt1": "no name", "txt2": "my real name is wooseok, lee", "txt3": "my first name is wooseok", "txt4": "my last name is lee"} |
+------------------------------------------------------------------------------------------------------- -------------------------+

 

" binary log 확인 "

'/*!*/;
### UPDATE `d1`.`t1`
### WHERE
### @1='{"txt1": "no name", "txt2": "my real name is wooseok, lee", "txt3": "my first name is wooseok", "txt4": "my last name is lee"}' /* JSON meta=4 nullable=1 is_null=0 */
### SET
### @1=JSON_REPLACE(@1, '$.txt1', 'my name is uzi!') /* JSON meta=4 nullable=1 is_null=0 */

→ "SET" 부분에서 {key:value} 의 모든 값이 아닌, JSON function 형태 로 남는 것을 확인할 수 있다.

 

 

3. 결론

보통 JSON 필드의 데이터는 예시처럼 짧지 않고 데이터의 길이가 긴 경우가 많다.

그러한 서비스에서는 binary log 의 사이즈를 효과적으로 줄일 수 있다.

 

다만, 해당 옵션 적용 시에는 text 형태로 set 하는 형태가 아닌 slave 에서도 json function 을 사용하게 된다.

그 말은 곧 슬레이브에서 적어도 한번의 function 을 사용한다는 이야기가 될 것이고, 자연스럽게 CPU 의 자원 또한 더 소모하게 된다.

 

정확한 벤치마크 테스트를 수행하지는 않아서 슬레이브의 CPU 부하에 대한 감은 없지만 크리티컬하지는 않을 것이라고 생각한다.

그에 반해 binary log 에 대해서는 확실하게 사이즈를 줄일 수 있고, 이는 disk iops 는 물론 network traffic 또한 줄일 수 있다는 이야기가 될 것이다.

 

따라서 개인적인 생각으로는 JSON 필드에 대해 write 가 많은 서비스라면 해당 옵션을 적용하는 것도 유의미해보인다.

 

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

MySQL 8.0 Atomic DDL (data definition statement)  (0) 2020.02.03
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