Java11のSpringBootのプロジェクトからMySQL8へ接続した時に発生した問題の解決と、Windows10でのMySQLの操作について
#環境
Windows10
MySQL 8.0.15(記述時点の最新)
Scoopによるインストール1
##mysql.ini内の[mysqld]の編集
###default-time-zone
サーバー全体のデフォルトのタイムゾーン。
デフォルトのタイムゾーンを指定していないとJDBCからの接続の際にエラーが発生2する。
タイムゾーンはデフォルトではUTCからの時差の指定でないと設定できない模様で、日本(JST)の場合は+9:00
と設定する。
###collation_server
サーバー全体の照合順序。MySQL8以降デフォルトの文字セットがutf8mb4になったが、設定がない場合の照合順序はutf8mb4_0900_ai_ciで、これだとアクセントを無視してしまう。
日本語では濁音、半濁音を区別せず、絵文字の一部などでも問題が発生するため、utf8mb4_0900系列の新しい照合順をデフォルトに設定する。
ひらがな、カタカナの区別が必要か、ソートの順序などでいくつか選択肢があるが、使用するのはおそらくutf8mb4_ja_0900_as_csかutf8mb4_ja_0900_as_cs_ks。
カタカナと平仮名の区別を行うのがutf8mb4_ja_0900_as_cs_ks。
条件が増えるほど負荷が高くなると思われるので要件に合わせて検討してテストも必要。
####character_set_serverについて
MySQL8ではutf8mb4がデフォルトで指定されている。新規に使い始めるなら特に設定は要らない。
##MySQLの操作
###mysqldの起動
コマンドプロンプトからmysqld --console
を実行3。プロンプトを閉じるとサーバーも落ちる。このため、プロンプトを開きっぱなしで作業をすることになる。
###mysqldの停止
正式な手順としてはmysqladmin shutdown
。起動させたプロンプトを閉じても停止するが正式なシャットダウンの手順を踏まない可能性があるので避けている。
###サーバーへの接続
mysqldを起動したものとは別のコマンドプロンプトかPowerShellからmysql -u root
4。
##JDK11.0.11-28以降とConnctor/Jの問題
###アプリケーションを一定時間以上動作させるとSSLのエラーが発生する
javax.net.ssl.SSLException
MESSAGE: closing inbound before receiving peer's close_notify
スタックを追うとコネクションプールから発生していた。Connection.close()
を実行するとエラーが発生するとの情報を発見。
その後さらに調査すると、JDKとConnector/jの間でどちらに原因があるが議論されていたようだが、JDK11のバグである模様。既に修正案も出ているようなので近い将来には解消されると期待したい5。
####2019/11/19追記
上記の問題はConectorJの問題としてJavaコミュニティでは修正されないことになった
###SSLExceptionの回避策
URLにパラメータを追加してSSLを無効にする。
#<=8.0.12
jdbc:mysql://localhost:3306/db_name?useSSL=false
#>=8.0.13
jdbc:mysql://localhost:3306/db_name?sslMode=DISABLED
8.0.13以降でも経過措置でuseSSL=falseも使えるが、非推奨。
アプリケーションからのみ接続するのであればこれで対応するのもあるかと思う。
##2019/03/06追記:Spring Boot(HiKariCP)とMySQL8の問題
###コネクションプールにHikariCPを使用するとDB内で文字化けが発生する
Spring Bootで追加設定なしで使用していると特に問題は発生しないのだが、コネクションプールをHikariCPに変更すると、DB内への書き込み時に文字化けが発生する。
HikariCPはMySQLの使用に消極的なようで、また、上記のSSLの例外の問題もあってか、最新のドライバをあえて使用しないようになっているのかもしれない。
これはJDBCのurlのパラメーターにcharacterEncoding=utf8を追加することで解消できる6。
-
--initialize-insecureによる簡略化されたインストール。ツールでインストールを自動化するときはこのオプションが必須。
Java11(OpenJDK11.0.11-28,11.0.2-9)でSpringBootを使用してMySQLへの接続を試した ↩ -
URLのパラメータで接続時のtime_zoneを指定していても発生する。仕様かバグかは未調査。 ↩
-
コマンドプロンプトが最も軽いから。 ↩
-
--initialize-insecureでインストールされているため。インストール時の設定やオプションで当然変わる。短時間のテスト時以外はパスワードは必ず設定、変更する。 ↩
-
11-28からバージョンアップしていなかったので2-9にしてみたが解消されていなかった ↩
-
ようやくこのおまじないから解放されると思っていたのに…。 ↩