GA

2020/06/23

utf8mb3なマスターに絵文字を突っ込んだ時にバイナリログってどうなるんだっけ

TL;DR

  • マスター上で、3バイトUTF-8なカラムとコネクションのcharsetの対応(いずれもsql_mode = ‘STRICT_TRANS_TABLES’ でない )
SET NAMES utf8 SET NAMES utf8mb4
utf8なカラム 絵文字から後ろが切れる 絵文字が ‘?’ になる
utf8mb4なカラム 絵文字が ‘????’ になる 絵文字が入る
  • マスターが3バイトutf8でスレーブが4バイトutf8(utf8mb4)の場合と↑の対応
ROW STATEMENT
マスターでは後ろが切れた スレーブでも後ろが切れる スレーブでは絵文字が入る
マスターでは ‘?’ になった スレーブでも ‘?’ になる スレーブでは絵文字が入る
  • 「後ろが全部切れる」のが「’?’ に変換される」のはまだインパクト少なそう(絵文字を入れたら後ろが全部切れるのを前提にしているエンドユーザーはきっといない)
  • binlog_format=ROW の方が安牌
    • マスター切り替え前後でエンドユーザーに見える値は変わらない
    • スレーブの CONVERT TO CHARSET utf8mb4 後すぐにマスターを切り替えるなら binlog_format= STATEMENT にしたくなる気持ちはわからなくもない(が、やりたくない)

以下、ログ

binlog_format = ROW

CREATE TABLE .. CHARACTER SET utf8mb3

mysql80 54> CREATE TABLE t1 (num int, val varchar(32)) CHARSET utf8mb3;
Query OK, 0 rows affected, 1 warning (0.03 sec)

mysql80 54> SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                     |
+---------+------+---------------------------------------------------------------------------------------------+
| Warning | 1287 | 'utf8mb3' is deprecated and will be removed in a future release. Please use utf8mb4 instead |
+---------+------+---------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql80 54> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` int DEFAULT NULL,
  `val` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.01 sec)

SET NAMES utf8mb3

mysql80 54> INSERT INTO t1 VALUES (1, 'utf8mb3による🍣だよ');
Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql80 54> SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------------------+
| Level   | Code | Message                                                                         |
+---------+------+---------------------------------------------------------------------------------+
| Warning | 1300 | Invalid utf8 character string: 'F09F8D'                                         |
| Warning | 1366 | Incorrect string value: '\xF0\x9F\x8D\xA3\xE3\x81...' for column 'val' at row 1 |
+---------+------+---------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql80 54> SELECT * FROM t1;
+------+------------------+
| num  | val              |
+------+------------------+
|    1 | utf8mb3による    |
+------+------------------+
1 row in set (0.00 sec)

# at 772
#200623 13:53:33 server id 1080  end_log_pos 851 CRC32 0x9517e90e       Rows_query
# INSERT INTO t1 VALUES (1, 'utf8mb3による🍣だよ')
### INSERT INTO `d11`.`t1`
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2='utf8mb3による' /* VARSTRING(96) meta=96 nullable=1 is_null=0 */

SET NAMES utf8mb4

mysql80 54> INSERT INTO t1 VALUES (1, 'utf8mb4による🍣だよ');
Query OK, 1 row affected, 1 warning (0.01 sec)

mysql80 54> SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------------------+
| Level   | Code | Message                                                                         |
+---------+------+---------------------------------------------------------------------------------+
| Warning | 1366 | Incorrect string value: '\xF0\x9F\x8D\xA3\xE3\x81...' for column 'val' at row 1 |
+---------+------+---------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql80 54> SELECT * FROM t1;
+------+-------------------------+
| num  | val                     |
+------+-------------------------+
|    1 | utf8mb3による           |
|    1 | utf8mb4による?だよ      |
+------+-------------------------+
2 rows in set (0.00 sec)

# at 1145
#200623 13:54:54 server id 1080  end_log_pos 1224 CRC32 0x4357ac1b      Rows_query
# INSERT INTO t1 VALUES (1, 'utf8mb4による🍣だよ')
### INSERT INTO `d11`.`t1`
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2='utf8mb4による?だよ' /* VARSTRING(96) meta=96 nullable=1 is_null=0 */

CREATE TABLE .. CHARSET utf8mb4

mysql80 54> CREATE TABLE t1 (num int, val varchar(32)) CHARSET utf8mb4;
Query OK, 0 rows affected (0.04 sec)

mysql80 54> SHOW CREATE TABLE t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `num` int DEFAULT NULL,
  `val` varchar(32) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)

SET NAMES utf8mb3

mysql80 54> INSERT INTO t1 VALUES (1, 'utf8mb3による🍺だよ');
Query OK, 1 row affected, 2 warnings (0.01 sec)

mysql80 54> SHOW WARNINGS;
+---------+------+---------------------------------------------------------------------------------+
| Level   | Code | Message                                                                         |
+---------+------+---------------------------------------------------------------------------------+
| Warning | 1300 | Invalid utf8 character string: 'F09F8D'                                         |
| Warning | 1366 | Incorrect string value: '\xF0\x9F\x8D\xBA\xE3\x81...' for column 'val' at row 1 |
+---------+------+---------------------------------------------------------------------------------+
2 rows in set (0.00 sec)

mysql80 54> SELECT * FROM t1;
+------+----------------------------+
| num  | val                        |
+------+----------------------------+
|    1 | utf8mb3による????だよ      |
+------+----------------------------+
1 row in set (0.00 sec)

# at 1948
#200623 13:57:06 server id 1080  end_log_pos 2027 CRC32 0xccae4843      Rows_query
# INSERT INTO t1 VALUES (1, 'utf8mb3による🍺だよ')
### INSERT INTO `d11`.`t1`
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2='utf8mb3による????だよ' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */

SET NAMES utf8mb4

mysql80 54> INSERT INTO t1 VALUES (1, 'utf8mb4による🍺だよ');
Query OK, 1 row affected (0.01 sec)

mysql80 54> SELECT * FROM t1;
+------+----------------------------+
| num  | val                        |
+------+----------------------------+
|    1 | utf8mb3による????だよ      |
|    1 | utf8mb4による🍺だよ          |
+------+----------------------------+
2 rows in set (0.00 sec)

# at 2333
#200623 13:58:52 server id 1080  end_log_pos 2412 CRC32 0xbc81cf0a      Rows_query
# INSERT INTO t1 VALUES (1, 'utf8mb4による🍺だよ')
### INSERT INTO `d11`.`t1`
### SET
###   @1=1 /* INT meta=0 nullable=1 is_null=0 */
###   @2='utf8mb4による🍺だよ' /* VARSTRING(128) meta=128 nullable=1 is_null=0 */

binlog_format = STATEMENT

CREATE TABLE .. CHARACTER SET utf8mb3

SET NAMES utf8mb3

mysql80 57> INSERT INTO t1 VALUES (1, 'utf8mb3による🍣だよ');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql80 57> SELECT * FROM t1;
+------+------------------+
| num  | val              |
+------+------------------+
|    1 | utf8mb3による    |
+------+------------------+
1 row in set (0.00 sec)

# at 1584
#200623 14:05:34 server id 1080  end_log_pos 1714 CRC32 0xb7219e87      Query   thread_id=57    exec_time=0     error_code=0
SET TIMESTAMP=1592888734/*!*/;
INSERT INTO t1 VALUES (1, 'utf8mb3による🍣だよ')

SET NAMES utf8mb4

mysql80 57> INSERT INTO t1 VALUES (1, 'utf8mb4による🍣だよ');
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql80 57> SELECT * FROM t1;
+------+-------------------------+
| num  | val                     |
+------+-------------------------+
|    1 | utf8mb3による           |
|    1 | utf8mb4による?だよ      |
+------+-------------------------+
2 rows in set (0.00 sec)

# at 1904
#200623 14:06:17 server id 1080  end_log_pos 2034 CRC32 0xae911ee8      Query   thread_id=57    exec_time=0     error_code=0
SET TIMESTAMP=1592888777/*!*/;
INSERT INTO t1 VALUES (1, 'utf8mb4による🍣だよ')

CREATE TABLE .. CHARACTER SET utf8mb4

SET NAMES utf8mb3

mysql80 57> INSERT INTO t1 VALUES (1, 'utf8mb3による🍺だよ');
Query OK, 1 row affected, 2 warnings (0.00 sec)

mysql80 57> SELECT * FROM t1;
+------+----------------------------+
| num  | val                        |
+------+----------------------------+
|    1 | utf8mb3による????だよ      |
+------+----------------------------+
1 row in set (0.00 sec)

# at 2647
#200623 14:07:40 server id 1080  end_log_pos 2777 CRC32 0xf21371cd      Query   thread_id=57    exec_time=0     error_code=0
SET TIMESTAMP=1592888860/*!*/;
INSERT INTO t1 VALUES (1, 'utf8mb3による🍺だよ')
/*!*/;

SET NAMES utf8mb4

mysql80 57> INSERT INTO t1 VALUES (1, 'utf8mb4による🍺だよ');
Query OK, 1 row affected (0.01 sec)

mysql80 57> SELECT * FROM t1;
+------+----------------------------+
| num  | val                        |
+------+----------------------------+
|    1 | utf8mb3による????だよ      |
|    1 | utf8mb4による🍺だよ          |
+------+----------------------------+
2 rows in set (0.00 sec)

# at 2967
#200623 14:08:25 server id 1080  end_log_pos 3097 CRC32 0x29b3d896      Query   thread_id=57    exec_time=0     error_code=0
SET TIMESTAMP=1592888905/*!*/;
INSERT INTO t1 VALUES (1, 'utf8mb4による🍺だよ')
/*!*/;

0 件のコメント :

コメントを投稿