PolarDB MySQL 8.0 互換版の X-Engine にちょっとだけ触れてみる

この記事は、**[MySQL Advent Calendar 2021](https://qiita.com/advent-calendar/2021/mysql)** 25 日目のエントリです。

昨日（24 日目）は **meijik** さんの **[TRUNCATE TABLEの実装とDELETE FROM](http://blog.kimuradb.com/?eid=877664)** でした。

しばらく触っていなかった Alibaba Cloud の PolarDB MySQL 8.0 互換版ですが、触っていないうちに（1 年以上前ですが）アーカイブ用の X-Engine が追加されていたので、今さらですがちょっとだけ触れてみました。

# PolarDB（MySQL 8.0）X-Engine とは

LSM-tree と ZSTD データ圧縮アルゴリズムを使い、データ容量を圧縮保存するストレージエンジンです。

このストレージエンジンを使うと、最大 200TB までデータを保存することができます。

 - **[X-Engine overview](https://www.alibabacloud.com/help/ja/doc-detail/148660.htm#concept-2377809)**

# X-Engine を有効にして PolarDB を起動する

**「アーカイブデータベース（高圧縮率）」**を選択して起動します。

![2021-12-24 (13).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/9ba220c1-2b9c-7388-1c76-8b279730b3c3.png)

起動したらホワイトリスト（またはセキュリティグループ）を設定し、
![2021-12-24 (14).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/79f0bacf-c7d6-36b9-8771-05442af0d6ee.png)

アカウント（データベースの管理ユーザ）を登録します。
![2021-12-24 (15).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/e2b69e91-4af8-b962-6bdf-99ae5a775c16.png)
※「admin」など既に予約されているアカウント名は登録できません（半ばネタ化していますが「aurora」さんも（中に居るので）使えません）。

# DB に接続してみる

ECS（AWS でいうところの EC2）から接続してみます。

```sql:接続してみる
# mysql -u polaradmin -h pc-0iwz7qwh279194m8k.mysql.polardb.japan.rds.aliyuncs.com -p
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1110
Server version: 8.0.13 Source distribution

Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SELECT version();
+-----------+
| version() |
+-----------+
| 8.0.13    |
+-----------+
1 row in set (0.00 sec)
```

リリース当初からベースのバージョンは 8.0.13 です（なおプレビューで Hash join に対応した 8.0.18 をベースにしたバージョンも使える模様。プレビューのまま長期間更新されていないように見えますが）。

データベースエンジン一覧を見てみます。

```sql:エンジン一覧
mysql> SHOW ENGINES;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine             | Support | Comment                                                        | Transactions | XA   | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED          | NO      | Federated MySQL storage engine                                 | NULL         | NULL | NULL       |
| BLACKHOLE          | YES     | /dev/null storage engine (anything you write to it disappears) | NO           | NO   | NO         |
| XENGINE            | DEFAULT | X-Engine storage engine                                        | YES          | YES  | YES        |
| MEMORY             | YES     | Hash based, stored in memory, useful for temporary tables      | NO           | NO   | NO         |
| InnoDB             | YES     | Supports transactions, row-level locking, and foreign keys     | YES          | YES  | YES        |
| PERFORMANCE_SCHEMA | YES     | Performance Schema                                             | NO           | NO   | NO         |
| MyISAM             | YES     | MyISAM storage engine                                          | NO           | NO   | NO         |
| MRG_MYISAM         | YES     | Collection of identical MyISAM tables                          | NO           | NO   | NO         |
| CSV                | YES     | CSV storage engine                                             | NO           | NO   | NO         |
| ARCHIVE            | YES     | Archive storage engine                                         | NO           | NO   | NO         |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
10 rows in set (0.01 sec)
```

**`XENGINE`**が入っています。
また、「アーカイブデータベース（高圧縮率）」を選択して起動した場合でも **`InnoDB`** が併用できるようですね。

`SHOW ENGINE XENGINE STATUS`を見てみます。

```sql:エンジンステータス
mysql> SHOW ENGINE XENGINE STATUS\G
*************************** 1. row ***************************
  Type: DBSTATS
  Name: xengine
Status:
** DB Stats **
Uptime(secs): 1197.8 total, 67.9 interval
Cumulative writes: 0 writes, 0 keys, 0 commit groups, 0.0 writes per commit group, ingest: 0.00 GB, 0.00 MB/s
Cumulative WAL: 0 writes, 0 syncs, 0.00 writes per sync, written: 0.00 GB, 0.00 MB/s
Cumulative stall: 00:00:0.000 H:M:S, 0.0 percent
Interval writes: 0 writes, 0 keys, 0 commit groups, 0.0 writes per commit group, ingest: 0.00 MB, 0.00 MB/s
Interval WAL: 0 writes, 0 syncs, 0.00 writes per sync, written: 0.00 MB, 0.00 MB/s
Interval stall: 00:00:0.000 H:M:S, 0.0 percent

*************************** 2. row ***************************
  Type: Memory_Stats
  Name: xengine
Status:
ActiveMemTableTotalNumber: 0
ActiveMemTableTotalMemoryAllocated: 0
ActiveMemTableTotalUsed: 0
UnflushedImmTableTotalNumber: 0
UnflushedImmTableTotalMemoryAllocated: 0
UnflushedImmTableTotalMemoryUsed: 0
TableReaderTotalNumber: 0
TableReaderTotalMemoryUsed: 0
BlockCacheTotalPinnedMemory: 0
BlockCacheTotalMemoryUsed: 65
DBTotalMemoryAllocated: 65
2 rows in set (0.00 sec)
```

詳しいことは分かりませんが、何か出てきました。

# `mysqlslap`で軽くベンチマークを走らせてみる

というわけで、このインスタンスで`mysqlslap`を使って、InnoDB と X-Engine を比較してみます。

こちらで使ったのと同じ 5 パターンで負荷を掛けてみました。

 - **[MySQL を使って EC2 r6g.large vs r5.large（mysqlslap 対決）をやってみた](https://qiita.com/hmatsu47/items/e20c4d69b0af465b0b12)**

## パターン

 - **(1) `mixed`**（混合）

```
mysqlslap --auto-generate-sql --auto-generate-sql-guid-primary --engine=innodb --number-int-cols=20 --number-char-cols=20 --concurrency=150 --auto-generate-sql-write-number=2000 --auto-generate-sql-execute-number=2000 --auto-generate-sql-load-type=mixed -u 【管理ユーザ名】 -h 【エンドポイント】 -p
```

※X-Engine に対しては`--engine=xengine`を追加。以降同じ。

 - **(2) `read`**（テーブルスキャン）

```
mysqlslap --auto-generate-sql --auto-generate-sql-guid-primary --engine=innodb --number-int-cols=20 --number-char-cols=20 --concurrency=150 --auto-generate-sql-execute-number=2000 --auto-generate-sql-load-type=read -u 【管理ユーザ名】 -h 【エンドポイント】 -p
```

 - **(3) `key`**（主キーで読み取り）

```
mysqlslap --auto-generate-sql --auto-generate-sql-guid-primary --engine=innodb --number-int-cols=20 --number-char-cols=20 --concurrency=150 --auto-generate-sql-execute-number=2000 --auto-generate-sql-load-type=key -u 【管理ユーザ名】 -h 【エンドポイント】 -p
```

 - **(4) `write`**（挿入）

```
mysqlslap --auto-generate-sql --auto-generate-sql-guid-primary --engine=innodb --number-int-cols=20 --number-char-cols=20 --concurrency=150 --auto-generate-sql-write-number=2000 --auto-generate-sql-execute-number=2000 --auto-generate-sql-load-type=write -u 【管理ユーザ名】 -h 【エンドポイント】 -p
```

 - **(5) `update`**（主キーで更新）

```
mysqlslap --auto-generate-sql --auto-generate-sql-guid-primary --engine=innodb --number-int-cols=20 --number-char-cols=20 --concurrency=150 --auto-generate-sql-write-number=2000 --auto-generate-sql-execute-number=2000 --auto-generate-sql-load-type=update -u 【管理ユーザ名】 -h 【エンドポイント】 -p
```

## 結果

DB Engine | (1) mixed | (2) read | (3) key | (4) write | (5) update
----------|--------:|-------:|--------:|--------:|--------:
InnoDB    |  25.000 | 66.701 |  11.358 |  33.190 |  35.949
X-Engine  |  52.836 | 66.865 |  11.092 |  84.626 |  89.650

※数値は 3 回実行した平均。単位は秒。

書き込みが含まれる (1)・(4)・(5) で倍以上の時間が掛かった一方で、読み取りのみの (2)・(3) では InnoDB と変わらないようです。

バッファプールサイズを超えるデータの読み取りが発生するケースを試していないので断定はできませんが、アーカイブ目的以外にも、書き込み頻度が低いか、書き込みを非同期に処理可能なアプリケーションに使えるかもしれませんね。