mita2 database life

主にMySQLに関するメモです

MySQL 8.0 の binlog_row_metadata オプションを試す

TL;DR

  • MySQL 8.0 で導入された binlog_row_metadata について調べた
  • 今のところデータ連携用途以外では使うところはなさそう

binlog_row_metadata オプションとは何か

マニュアルでは以下のように記載されています。

  • デフォルトはMINIMAL(最小限)
  • ROWベースのみ有効
  • MINIMALでは、SIGNEDフラグ、カラムの文字コードセット、Geometoryタイプのみをバイナリログに記録する。

Configures the amount of table metadata added to the binary log when using row-based logging. When set to MINIMAL, the default, only metadata related to SIGNED flags, column character set and geometry types are logged. When set to FULL complete metadata for tables is logged, such as column name, ENUM or SET string values, PRIMARY KEY information, and so on. https://dev.mysql.com/doc/refman/8.0/en/replication-options-binary-log.html#sysvar_binlog_row_metadata

実際にMINIMALとFULLで比較してみます。 メタデータmysqlbinlog コマンドに --print-table-metadata オプションを指定し、確認します。

テスト用のテーブル:

mysql> DESC t.bin_meta_t;
+-------+---------------------+------+-----+---------+----------------+
| Field | Type                | Null | Key | Default | Extra          |
+-------+---------------------+------+-----+---------+----------------+
| pk    | bigint(20) unsigned | NO   | PRI | NULL    | auto_increment |
| col1  | varchar(255)        | YES  |     | NULL    |                |
+-------+---------------------+------+-----+---------+----------------+
2 rows in set (0.01 sec)

MINIMAL

# mysqlbinlog -vv --print-table-metadata binlog.000009
<snip>
# at 306
#191231 16:52:57 server id 1  end_log_pos 367 CRC32 0x99f3c5db  Table_map: `t`.`bin_meta_t` mapped to number 93
# Columns(BIGINT UNSIGNED NOT NULL,
#         VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci)
# at 367
#191231 16:52:57 server id 1  end_log_pos 425 CRC32 0xd85ee9d6  Write_rows: table id 93 flags: STMT_END_F

BINLOG '
Wf4KXhMBAAAAPQAAAG8BAAAAAF0AAAAAAAEAAXQACmJpbl9tZXRhX3QAAggPAvwDAgEBgAID/P8A
28XzmQ==
Wf4KXh4BAAAAOgAAAKkBAAAAAF0AAAAAAAEAAgAC/wABAAAAAAAAAAwATUlOSU1BTCBNRVRB1ule
2A==
'/*!*/;
### INSERT INTO `t`.`bin_meta_t`
### SET
###   @1=1 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='MINIMAL META' /* VARSTRING(1020) meta=1020 nullable=1 is_null=0 */
# at 425
#191231 16:52:57 server id 1  end_log_pos 456 CRC32 0xaedc614c  Xid = 179
<snip>

FULL

# mysqlbinlog -vv  --print-table-metadata binlog.000009
<snip>
# at 306
#191231 16:53:49 server id 1  end_log_pos 380 CRC32 0xd2360199  Table_map: `t`.`bin_meta_t` mapped to number 93
# Columns(`pk` BIGINT UNSIGNED NOT NULL,
#         `col1` VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci)
# Primary Key(pk)
# at 380
#191231 16:53:49 server id 1  end_log_pos 435 CRC32 0x5826b7f8  Write_rows: table id 93 flags: STMT_END_F

BINLOG '
jf4KXhMBAAAASgAAAHwBAAAAAF0AAAAAAAEAAXQACmJpbl9tZXRhX3QAAggPAvwDAgEBgAID/P8A
BAgCcGsEY29sMQgBAJkBNtI=
jf4KXh4BAAAANwAAALMBAAAAAF0AAAAAAAEAAgAC/wACAAAAAAAAAAkARlVMTCBNRVRB+LcmWA==
'/*!*/;
### INSERT INTO `t`.`bin_meta_t`
### SET
###   @1=2 /* LONGINT meta=0 nullable=0 is_null=0 */
###   @2='FULL META' /* VARSTRING(1020) meta=1020 nullable=1 is_null=0 */
# at 435
<snip>

Columns の部分が異なっています。 FULL の場合は以下のようにカラム名メタデータに含まれていることが確認できました。また、プライマリキーになっているカラム名も追加されています。MINIMAL ではカラム名は含まれません。「テーブルの何番目のカラムが変更されたか」のみが記載されています。

# Columns(`pk` BIGINT UNSIGNED NOT NULL,
#         `col1` VARCHAR(255) CHARSET utf8mb4 COLLATE utf8mb4_0900_ai_ci)
# Primary Key(pk)

どういう時に役に立つのか

マニュアルには以下の2つが記載されてます。

1つ目:データ連携がやりやすくなる。データが変更されたカラムの名前がバイナリログを見れば、すぐ判断できるため、データを連携する仕組みがこれまでより用意に実装できるということでしょう。

  • External software can use the metadata to decode row events and store the data into external databases, such as a data warehouse.

2つ目:マスターとスレーブで構成が異なるテーブルであってもレプリケーションが可能になるマスターとスレーブでカラムの順番が異なるとかそういうケースを指していると思われる。

  • Slaves use the metadata to transfer data when its table structure is different from the master's.

これは実際試してみたのですが、うまく動きませんでした(レプリケーションが普通に止まります)。 Worklogを見ると、「スコープ外」と記載されているので、まだ実装されてないようです。

There is a online DDL solution, which first changes slave's data structure and then change master's data structure. So the table on slave may have more or less columns, different column types and different column orders. If required metadata is logged, then slave can support the online DDL solution better. However, making the applier aware of the additional metadata when applying ROW events is out of this worklog scope.