小ネタ／MySQL 8.0 のダブルライトバッファがどのバージョンで暗号化されるようになったのか調べた

以前、MySQL 8.0 ではテーブルスペースや REDO ログ／UNDO ログ・システムテーブルを暗号化しても、ダブルライトバッファには対象データが平文で書き出されていました。

 - **[MySQL 8.0.16 でテーブルスペース・REDO ログ／UNDO ログ・システムテーブル暗号化](https://qiita.com/hmatsu47/items/bae53fd0f6d09511732c)**

先日、MySQL 関連のオンラインイベントの Q&A で、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">あれ、ダブルライトバッファってGA後に実験したときに平文で書かれちゃってたけど、それはもう直ったのか…あらためて試さないと（Q&amp;Aに質問入れたのわたしじゃないけど）。<a href="https://twitter.com/hashtag/mysql_jp?src=hash&amp;ref_src=twsrc%5Etfw">#mysql_jp</a></p>&mdash; hmatsu47(まつ) (@hmatsu47) <a href="https://twitter.com/hmatsu47/status/1298875594906599424?ref_src=twsrc%5Etfw">August 27, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

という話を聞いたので、8.0.17 から順番に確認していきました。

---

**2021/01/31 追記：**
MySQL 8.0.23 でダブルライトファイル暗号化がサポートされたとのことだったので、あらためて確認しました。

 - **[MySQL 8.0.23 でダブルライトファイル暗号化がサポートされたと聞いて「？」となったのであらためて確認してみた](https://qiita.com/hmatsu47/items/596496b814b6905e1463)**

---

# 確認内容

 - CentOS 8.2 64 ビット環境で実行
 - MySQL 8.0 Community Server の対象バージョンを dnf インストール
 - /etc/my.cnf に以下の内容を追記して起動

```text:my.cnf追記部分
early-plugin-load=keyring_file.so
keyring_file_data=/var/lib/mysql-keyring/keyring
innodb_redo_log_encrypt=1
innodb_undo_log_encrypt=1

server-id=1
binlog_format=MIXED
binlog_encryption=ON
binlog_rotate_encryption_master_key_at_startup=ON
```

 - `mysql_secure_installation`を実行
 - MySQL に暗号化有効でデータを入れる

```sql:MySQLで操作
mysql> ALTER TABLESPACE mysql ENCRYPTION = 'Y';
Query OK, 0 rows affected (2.12 sec)

mysql> CREATE DATABASE encryption_test;
Query OK, 1 row affected (0.01 sec)

mysql> USE encryption_test;
Database changed
mysql> CREATE TABLE enc_test (id INT PRIMARY KEY AUTO_INCREMENT, value VARCHAR(100)) ENGINE=innodb ENCRYPTION='Y';
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO enc_test SET value='234567890ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst1234567890ABCDEFGHIJKLMNOPQRSTabcdefghijklmnopqrst';
Query OK, 1 row affected (0.00 sec)

（計 5 行挿入）

mysql> SET AUTOCOMMIT=0;
Query OK, 0 rows affected (0.00 sec)

mysql> UPDATE enc_test SET value='ENCRYPTED' WHERE id=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> COMMIT;
Query OK, 0 rows affected (0.00 sec)
```

 - ファイル検索で確認

```bash:ファイル検索
# fgrep -r 'ENCRYPTED' /var/lib/mysql
```

# 結果

## MySQL 8.0.17

```bash:確認（8.0.17）
# fgrep -r 'ENCRYPTED' /var/lib/mysql
Binary file /var/lib/mysql/ibdata1 matches
```

8.0.16 の時と同様に見つかりました。

※バイナリエディタで開いてみたところ、対象のデータが（更新前の行に上書きされる形で）見つかりました（ここでは省略）。

## MySQL 8.0.18

```bash:確認（8.0.18）
# fgrep -r 'ENCRYPTED' /var/lib/mysql
```

今度は見つかりませんでした。

MySQL 8.0.19 以降も同じ結果でした。

**MySQL 8.0.18 から暗号化されるようになった**ことがわかりました。

## 余談

テストに使ったテーブル名を、

```bash:テーブル名でファイル検索
# fgrep -r 'enc_test' /var/lib/mysql
```

で検索してみたところ、どのバージョンでもテーブル名が見つかりました。

```bash:テーブル名確認（8.0.17～19）
# fgrep -r 'enc_test' /var/lib/mysql
Binary file /var/lib/mysql/ibdata1 matches
```

```bash:テーブル名確認（8.0.20～21）
# fgrep -r 'enc_test' /var/lib/mysql
Binary file /var/lib/mysql/#ib_16384_0.dblwr matches
```

バイナリエディタで開いてみたところ、いずれも SQL 文やテーブル定義ではありませんでしたが、いくつかデータベース名やテーブル名が平文で保管されている様子でした。

---

 - **[Qiitaに投稿したMySQL 8.0関連記事](https://hmatsu47.hatenablog.com/qiita_mysql80)**
 - **[MySQL 8.0 の薄い本](https://github.com/hmatsu47/mysql80_no_usui_hon)（無料で配布中！）**