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 |