Payara ServerでMySQL 8.0を使用する

Payara Server 5.184以降では、JDBC接続プールのドライバ選択に “MySql8” が追加されました。今回は新しく追加された “MySql8” を使用して、MySQL 8.0に接続する方法についてまとめます。 “MySql” を使用してMySQL 5.xに接続する方法については、Payara Blogの “Using MySQL with Payara Server” をご覧ください(Payara Server 4.x向けの解説ですが、Payara Server 5でもそのまま当てはまります)。

Payara Server 5.183以前から存在する “MySql” はMySQL 5.x用のJDBCドライバであるConnector/J 5.1向けのテンプレートであり、MySQL 8.0用のJDBCドライバであるConnector/J 8.0を使用するためにはJDBCドライバのクラス名の変更や追加のプロパティ設定などが必要でした。Payara Server 5.184で追加された “MySql8” では初期値がConnector/J 8.0に合わせて変更されています。

今回はMySQL 8.0.13とConnector/J 8.0.13を使用します。MySQL 8.0はマイナーバージョン間でUnicodeやSSLに関する仕様が異なっており、JDBCドライバの既定値も8.0.13と8.0.12以前では一部異なります(開発バージョンである8.0.14以降でもさらに変更があるようです)。その点についてご注意ください。

なお、本稿執筆に当たっては検証用としてWindows 10にMySQL 8.0.13(および比較検討用のMySQL 5.7.24)を簡易的にインストールしました。

Connector/J 8.0について

Connector/J 8.0は、MySQL 8.0に合わせて開発された新しいJDBCドライバです。前バージョンのConnector/J 5.1とは非互換部分が多く、ソフトウェアとしては全くの別物とみて良いでしょう。ただし、MySQLの接続プロトコル自体は変わらないため、MySQL 5.xへの接続もサポートしています。

  • Connector/J 8.0 : MySQL 8.0 および MySQL 5.x をサポート
  • Connector/J 5.1 : MySQL 5.x のみサポート

Payara ServerのMySQL 8.0接続プール設定

前述の通り、Payara Server 5.184以降では、JDBC接続プール画面のDatabase Driver Vendorで “MySql8” が選択できるようになっています(図1)。

図1 Payara Server 5.184のJDBC接続プール作成画面

以下の項目を入力して、次の画面でJDBC接続プールのプロパティを設定します。手順そのものはPayara ServerにおけるJDBC接続プール作成の標準的なものです。

  • Pool Name : 接続プール名を入力(必須)
  • Resource Type : javax.sql.DataSource を選択
  • Database Driver Vendor : MySql8 を選択
  • Introspect : チェックしない

また、JDBC接続プールを作成するに当たって、適切なJDBCドライバをPayara Serverにインストールする必要があります。JDBCドライバは、Payara Serverの起動前に所定のディレクトリ※1にJARファイルをコピーするか、Payara Serverの稼働中に asadmin add-library コマンド(推奨)を使用してインストールします。以下に asadmin add-library コマンドの使用例を示します。

asadmin add-library C:\Users\hasunuma\downloads\mysql-connector-java-8.0.13.jar

※1 JDBCドライバは以下のいずれかに配置することでロードされます。

  1. payara5/glassfish/lib
  2. payara5/glassfish/domains/<domain-name>/lib

通常は特定のドメインでのみロードされる 2 に配置します(asadmin add-library も 2 を使用します)。1 に配置した場合はすべてのドメインでロードされます。なお、JDBCドライバを payara5/glassfish/modules 以下に配置してもロードされないため注意が必要です。これはPayara ServerのOSGiモジュールが modules から、非OSGiモジュールが lib からそれぞれロードされるためです。1 はサーバー共通のモジュールを配置する場所であることを考慮すると、ドメインが管理するJDBCドライバの配置場所としては適切とは言えません。

JDBC接続プールのプロパティは多数ありますが、いくつかの必須項目と設定に注意が必要な項目を除けば、初期値のまで問題ありません。

1. Connector/J必須項目

MySQLのバージョンによらず、以下の項目は接続プール作成時に必ず指定しなければなりません。PortNumberのみ、MySQLのwell-knownポートである 3306 が既定値として設定されています。Connector/J 8.0で追加されたプロパティであるPortは、PortNumberと同じ働きをします。

  • ServerName
  • DatabaseName
  • User
  • Password
  • PortNumber

2. JDBC接続URL

JDBC接続URLを指定することができます。UrlURL はいずれも同じ働きをします。

  • Url
  • URL

URLの書式は jdbc:mysql://<server-name>:<port>/<database-name> です。

上記の必須項目が正しく設定されている場合、接続 URL は特に設定しなくてかまいません(初期値 jdbc:mysql://:3306/ のままでよい)。

3. サーバーのタイムゾーン設定

MySQLのバージョンによらずConnector/J 8.0使用時は必須となります。Connector/J 5.1からの大きな変更点のひとつです。

  • ServerTimezone

日本国内で使用する場合は、ServerTimeZone=Asia/Tokyoで問題ないでしょう。他のタイムゾーンを使用している場合にはそれに合わせます。基本的にはtzdb形式ですが、JSTなどの3文字コードも使用できるかもしれません(未検証)。

4. Connector/JのSSL設定

MySQL 8.0(またはSSL 対応済MySQL 5.x)と非SSL通信で接続するための設定を行います。MySQL 5.xは標準で SSL 非対応のため既定値のままでかまいません。

MySQL 8.0(または SSL 対応済 MySQL 5.x)とSSL/TLS通信で接続する場合には、公開鍵認証の設定を行うなど異なる手順を必要とします。

  • SslMode

Connector/JのSSL設定を行います。既定値は PREFERRED で、状況に合わせてSSL有効/無効を切り替えるという、一見するとスマートな方法ですが、下記のように実はトリッキーな仕組みになっています(私はWireshark 2.9で4時間もパケットを監視し続けてようやく突き止めました)。
MySQL 8.0では既定でSSLが有効となっています。既定値 PREFERRED はサーバー側の設定に合わせるため、Connector/J 8.0はSSL/TLS 通信での接続を試みます。クライアント・サーバー間で公開鍵認証が通らない場合(初期設定など)には、証明書不備が起因となりPing時にサーバーから “Communications link failure – Last packet sent to the server was 0 ms ago” のようなエラーが返ります。このエラーは、一般的な通信エラー・メッセージのため、他の問題との切り分けが非常に困難です。
SslMode=DISABLED に設定してクライアント側からSSLを明示的に無効化することで、非SSL通信に切り替えることができます(逆に SSL を明示的に有効化する場合には REQUIRED を設定する)。
MySQL 5.xでは既定で SSL が無効です。既定値 PREFERERED はサーバー側の設定に合わせるため、Connector/J 8.0は非SSL通信での接続を行います。当然ながら公開鍵認証の設定は不要のため、初期状態で問題なく通信が可能です。

  • UseSSL

Connector/J 5.1以前から存在するSSL有効化/無効化設定のプロパティで既定値は true です。Connector/J 8.0では非推奨となっており、 SslMode の設定が優先されます。そのため、 SslMode=DISABLED を設定した場合は既定値のままで問題ありません。ただし、紛らわしいため敢えて UseSSL=false と設定するのも一案かもしれません。

5. ユーザー認証プラグイン設定

MySQLは認証方式をプラグイン形式で選択する仕組みになっており、そのための設定がConnector/Jにも用意されています。標準でいくつかのユーザー認証プラグインが用意されており、既定のプラグインを含めそれらを使用する限りでは特別な設定は必要ありません。ここでは参考までに取り上げます。

  • AuthenticationPlugins

使用するユーザー認証プラグインのリストをカンマ区切りで指定します。既定値は null です。この設定値にかかわらずConnector/J組み込みのプラグインは(DisabledAuthenticationPlugins で禁止しない限り)すべて使用可能です。

  • DisabledAuthenticationPlugins

使用を禁止するユーザー認証プラグインのリストをカンマ区切りで指定します。既定値は null で、すべてのプラグインが使用可能となっています。

  • DefaultAuthenticationPlugin

既定のユーザー認証プラグインを指定します(1つだけ)。既定値は com.mysql.cj.protocol.a.authentication.MysqlNativePasswordPlugin です。
MySQL 8.x が標準で用意しているユーザー認証プラグインのうち主なものを以下に示します。商用版MySQL(MySQL Enterprise Edition)ではより多くのプラグイン(Windows 認証プラグインなど)が提供されています。

  • com.mysql.cj.protocol.a.authentication.MysqlNativePasswordPlugin (mysql_native_password) : MySQLネイティブ認証を使用するプラグインでMySQL 5.xの既定値となっています。
  • com.mysql.cj.protocol.a.authentication.MysqlClearPasswordPlugin (mysql_clear_password) : クリアテキスト認証を使用するプラグインです。LDAP認証やUnix/LinuxのPAM認証と組み合わせて使用するために用意されています。
  • com.mysql.cj.protocol.a.authentication.Sha256PasswordPlugin (sha256_password) : 認証パスワードに SHA-256(SHA-2)ハッシュ方式を使用するプラグインで mysql_native_password よりも強力な認証方式です。
  • com.mysql.cj.protocol.a.authentication.CachingSha2PasswordPlugin (caching_sha2_password) : 認証パスワードに SHA-256(SHA-2)ハッシュ方式を使用するプラグインです。 sha256_password 同様に mysql_native_password よりも強力な認証方式であり、キャッシュを使用するため sha256_password よりもパフォーマンスに優れているという特徴があります。MySQL 8.x の既定値です。

MySQL 8.xでは、ユーザー作成時に認証方式を明示しない場合には caching_sha2_password が使用されます。通常はConnector/Jが対応する com.mysql.cj.protocol.a.authentication.CachingSha2PasswordPlugin を自動的に選択するため問題は発生しません。ただし、DisabledAuthenticationPluginscom.mysql.cj.protocol.a.authentication.CachingSha2PasswordPlugin を含めると接続できなくなるため注意してください。

6. その他

  • AllowPublicKeyRetrieval

サーバー側から公開鍵を取得するための特別な Handshake を許可/禁止します。既定値は false(禁止)です。Ping送信時に “Public Key Retrieval is not allowed” というエラーが返ってきた場合、この値を true に設定すると Ping が成功するようになります。

JDBC接続プール・プロパティのまとめ

以上より、localhost上でPayara ServerからMySQL 8.0に(非SSL)接続するには、JDBC接続プールのプロパティを以下のように設定します。

  • ServerName=localhost
  • DatabaseName=${database-name}
  • User=${username}
  • Password=${password}
  • PortNumber=3306
  • ServerTimezone=Asia/Tokyo
  • SslMode=DISABLED

もし、Ping送信時に “Public Key Retrieval is not allowed” が返ってきたら以下を追加します。

  • AllowPublicKeyRetrieval

プロパティのリストは項目が多いため、 “Name” ヘッダーをクリックしてプロパティ名でソートすると作業がしやすくなります。

まとめに代えて

少し前に、以下のようなツイートをしました。


MySQLはコンパクトなDBMSのため、DerbyやH2の代用としてローカルのPCにインストールしてもそれほど負荷にはなりません。しかし、MySQL 8.0の場合はJDBC接続プールの設定が少々分かりづらく、私自身も13時間を要しました。他にも設定上の落とし穴はあるかと思いますが、「SSL無効化」と「認証プラグインの選択」という大きな難所はこれでクリアできるかと思います。