MySQL8.0 Document Store関連技術まとめ

Summary

  • ver 5.7.12 で追加された「3つのX」。ver 8.0からGA
    • X Protocol
    • X DevAPI
    • X Plugin
  • X Protocol
    • アプリケーションがX Pluginと通信するために使われる新プロトコル。MySQLへの(これまで通りの)SQLインターフェース + NoSQLインタフェースの両方をサポートしている
  • X DevAPI
    • MySQL用のNoSQLソリューションを開発したり、Document StoreとしてMySQLを使用したりすることを可能にするAPI
    • Connectors
      • X DevAPIをサポートしている、言語別クライアント
      • C++, Java, Node.js, .NET, Python の各言語向けライブラリが公式に提供されている
    • MySQL Shell
      • MySQLサーバへの新しい対話型インタフェースで、Connector同様にX DevAPIをサポートしている
      • 以前からのmysqlコマンドと同じSQLインタフェースに加えて、JavaScript, Pythonでもコンソール上での各種操作が可能。 JSやPythonでmysqlコンソールを操作できる
  • X Plugin
    • X Protocolをサーバー側で有効にして、X Protocolを使ってクライアントとの通信を可能にする為のプラグイン
    • Document StoreとしてMySQLを使用する為にはX Pluginが有効化されていなければならない
      • ver 8.0.11以降はデフォルトで有効化されている
  • Document Store
    • 「3つのX」を使って、JSON DocumentをNoSQL/DocumentDB likeに取り扱う仕組み

X Protocol

公式 - MySQL :: MySQL Internals Manual :: 15 X Protocol

  • X Protocolは、X DevAPIを使用してサーバーと通信するように設計されている
  • X Protocolは、通常のSQLインターフェースもサポートしている。つまり先述のDocument Storeの機能と合わせてSQL/NoSQL両方のインタフェースを使用するアプリケーションを構築できる

worklogで言及されている 通り、X Protocolは拡張性・パフォーマンス・セキュリティ、の3点に主眼を置いて設計された新しいClient/Serverプロトコルです。過去のバージョンのC/Sプロトコルはこれらに課題を抱えていたという事ですが、下位互換性を維持しながら機能修正を行っていく事が厳しいという事情がありました。そうした経緯で全く新しいプロトコルが新たに開発されました。

X Protocolの特徴として、まずセキュリティに関してはTLS, SASLといった信頼性が証明されている標準技術が採用されています。またパフォーマンスに関してはClient/Server間のやり取りのパイプライン化や、サーバー側でのマルチスレッド化といった対応 で改善されています。

過去のC/Sプロトコルとの比較はこちら が詳しいですが、セキュリティ対策やパフォーマンス改善も含めて、機能追加・修正が行いやすい事に貢献している大きな材料がC/S間のメッセージのやり取りにProtocol Buffersを採用している 事ではないかと思います。言語・プラットフォームに依存せず・厳密な型定義を保ちながら・拡張可能なメカニズムでデータをserialize可能である、という特徴がX Protocolで実現したかった要件とマッチしていて、現状ベストな選択と言えそうです。

X Protocolのprotobuf定義はgithubで公開されています

X DevAPI

公式 - MySQL :: X DevAPI User Guide

  • X DevAPIは、JSON Documentおよび(従来からの)リレーショナルデータと簡単にやり取りできるように設計されている。両方をサポートしているAPIである、という事が特徴
    • 前者がDocument Store機能。NoSQLインタフェースを実装するクラスとメソッドのライブラリが提供されている

X DevAPIはX Protocolを実装しているクライアントからのみ利用可能です。X DevAPIをサポートしているクライアントは下記の通りです。

X DevAPIでは mysqlx というモジュールを使って Session と呼ばれるX Protocol接続オブジェクトを取得し、mysqlサーバに接続します。これにより、JSONデータをDocument Storeとして取り扱うクラスやメソッド群が使用可能になります。逆にX Pluginが有効ではない(古い)プロトコルでの接続は Classic Session と呼ばれるオブジェクトで管理されます。各言語のConnectorでは、共通してmysqlxと呼ばれるモジュールにより、従来の機能(API)とは独立した形でX DevAPIの機能が提供されています。

接続を司るSessionオブジェクトも含め、X DevAPIを実装している各クライアント(のmysqlxモジュール)は下記構成で機能が提供されています。

(mysqlxモジュールの構成図)

現状では先程のリストに挙がっていない言語、例えばRubyやGoでは公式にConnectorは提供されていませんが、各言語のconnector APIリファレンス(例:Node.jsのもの)や、拡張BNF(CRUD関連式関連 )が公開されており、これらを参考に独自実装する事も不可能では無さそうです。

(Databaseオブジェクトのクラス図)

(Resultオブジェクトのクラス図)

MySQL Shell

公式 - MySQL :: MySQL Shell 8.0

公式 - MySQL Shell: Main Page(JavaScript)

  • MySQL Shellでは、過去のmysqlクライアントと同じ操作が可能な SQLモード が提供されている
    • 従来の mysql コマンドで立ち上げたmysqlコンソールと全く同じ操作が、MySQL Shellでも可能
  • 加えて、JavaScript, Pythonの2言語が対話型インタフェースとして追加された
    • 両言語では、対話型だけでなくバッチモードで・各言語でのスクリプト処理も開発・実行できる
  • MySQL Shellを立ち上げてからでも、言語の切り替えが出来る
    • 例えば \js と打てばJavaScriptモードになる

MySQL Shellは「X Pluginを介してサーバーと通信する為にX Protocolを使用するように設計されているクライアント」で、つまりリレーショナル(SQL)、Document Store(NoSQL) いずれの方式にも対応しているクライアントです。

Macなどでサクッとver8のMySQLを立ち上げて試したければ、8系のDockerfileが公開されているのでこれを使うのが良いでしょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# docker-compose.yml

version: '3'
services:
  mysql:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=root
    volumes:
      - ./.data/mysql:/var/lib/mysql
    ports:
      - "3306:3306"
      - "33060:33060"
1
$ docker-compose up

Mac向けのMySQL Shellはdmgで公開されているのでこれをインストールし、SQLモードでshellを立ち上げてみるとプロンプトがシャレオツなmysqlコンソールが立ち上がります。ポート番号は後述のX Pluginが接続を待ち受ける番号を指定します(デフォルトが33060)

--sql とSQLモードで立ち上げたMySQL Shellは、過去バージョンのmysqlコマンドで利用可能な機能が全てそのまま使えます。

1
$ mysqlsh -u root -proot -h localhost -P33060 --sql
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
:

Creating a session to 'root@localhost:33060'
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 1 (X protocol)

:
:

MySQL  localhost:33060+ ssl  SQL >

\jsと入力するとJavaScriptモードに、\pyと入力するとPythonモードに切り替わります

1
2
3
4
5
6
7
MySQL  localhost:33060+ ssl  SQL > \js
Switching to JavaScript mode...

MySQL  localhost:33060+ ssl  JS > \py
Switching to Python mode...

MySQL  localhost:33060+ ssl  Py >

mysqlshコマンドで、従来のmysqlコマンド(C/Sプロトコル)による接続を行う事も可能です。その場合portにはサーバが使用している待受ポートを指定し、合わせて--classicというオプションを指定します。X Protocolで接続した場合と異なり、

  • Creating a Classic session... というメッセージが表示される
  • 接続後のプロンプトのポート番号部分に+表記が無い

という違いがあります。

1
$ mysqlsh -u root -proot -h localhost -P3306 --sql --classic
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
:

Creating a Classic session to 'root@localhost:3306'
Fetching schema names for autocompletion... Press ^C to stop.
Your MySQL connection id is 2

:
:

MySQL  localhost:3306 ssl  SQL >

X Plugin

公式 - MySQL :: MySQL 8.0 Reference Manual :: 20.5 X Plugin

  • X Pluginは、実行タイミングで有効化・無効化が可能
    • ver 8.0からは、デフォルトで有効化されている
  • X Pluginがロードされると、X Protocolを使用した通信も有効化される
    • つまりX Pluginがロードされて初めてDocument Storeの機能も有効になる
  • X Pluginは、MySQLサーバのポート(=3306)とは別のポートで接続を待ち受ける
    • デフォルト = 33060
  • 関連するサーバ設定は mysqlx_xxx という名前になっている

X Protocolをサーバー側で有効にして、X Protocolを使ってクライアントとの通信を可能にする為のプラグインがX Pluginです。MySQLをDocument Storeとして活用するにはX Protocolでの通信が必須であり、つまりDocument Storeとして活用する為の前提条件はX Pluginを有効にする事と言えます。

X Pluginの特徴の1つとして、クライアント/サーバ間の通信で使っているSSL証明書と別のSSL証明書を使って(プラグインへの)接続を行う事が可能という点が挙げられます。下記がmy.cnfの設定例ですが、mysqld セクションのSSL関連の設定パラメータに mysqlx_ というprefixを付けたパラメータで、サーバで使っているSSL証明書と別の証明書を指定する事ができます。

1
2
3
4
5
6
7
8
[mysqld]
ssl-ca = /path/to/ca_server.pem
ssl-cert = /path/to/server-cert.pem
ssl-key = /path/to/server-key.pem

mysqlx-ssl-ca = /path/to/ca_xplugin.pem
mysqlx-ssl-cert = /path/to/xplugin-cert.pem
mysqlx-ssl-key = /path/to/xplugin-key.pem

X PluginはMySQLサーバとは別のポート=デフォルトで33060番ポートを使って通信を行います。先述のMySQL Shellを使ってX Pluginと対話型インタフェースで接続するには下記コマンドで接続します。

1
2
# ポート番号として33060を指定
$ mysqlsh -u root -proot -h localhost -P33060 --sql

ver 8.0からX Pluginがデフォルトで有効化されている事は、下記の通りshow plugin文を実行すると確認する事ができます。例えばこの記事執筆時点で公開されてるver8系の公式Docker imageは8.0.15が使われていますが、このimageを使っても確認可能です。

1
2
3
4
5
6
> show plugins;

+---------------------------------+----------+--------------------+---------+---------+
| Name                            | Status   | Type               | Library | License |
+---------------------------------+----------+--------------------+---------+---------+
| mysqlx                          | ACTIVE   | DAEMON             | NULL    | GPL     |

ブックマーク