WindowsのPythonでMySQL80を触ろうとしたら躓いた話

本題

MySQLが8.0になった際、認証周りで変更があったため、Pythonから触ろうとしたらいろいろ躓いたのでそれらをまとめた。

なお環境は下記のとおりである。

OS:Windows 10
Mysql 8.0
Driver: mysql-connector-python-rf

発生したエラー

Traceback (most recent call last):
  File "****.py", line 46, in <module>
    charset = 'utf8')
  File "C:\Users\***\Local\Programs\Python\Python35\lib\site-packages\mysql\connector\__init__.py", line 179, in connect
    return MySQLConnection(*args, **kwargs)
  File "C:\Users\***\Local\Programs\Python\Python35\lib\site-packages\mysql\connector\connection.py", line 95, in __init__
    self.connect(**kwargs)
  File "C:\Users\***\Local\Programs\Python\Python35\lib\site-packages\mysql\connector\abstracts.py", line 716, in connect
    self._open_connection()
  File "C:\Users\***\Local\Programs\Python\Python35\lib\site-packages\mysql\connector\connection.py", line 210, in _open_connection
    self._ssl)
  File "C:\Users\***\Local\Programs\Python\Python35\lib\site-packages\mysql\connector\connection.py", line 142, in _do_auth
    auth_plugin=self._auth_plugin)
  File "C:\Users\***\Local\Programs\Python\Python35\lib\site-packages\mysql\connector\protocol.py", line 102, in make_auth
    auth_data, ssl_enabled)
  File "C:\Users\***\Local\Programs\Python\Python35\lib\site-packages\mysql\connector\protocol.py", line 58, in _auth_response
    auth = get_auth_plugin(auth_plugin)(
  File "C:\Users\***\Local\Programs\Python\Python35\lib\site-packages\mysql\connector\authentication.py", line 191, in get_auth_plugin
    "Authentication plugin '{0}' is not supported".format(plugin_name))
mysql.connector.errors.NotSupportedError: Authentication plugin 'caching_sha2_password' is not supported

発生した理由はMySQL8.0で追加されたchaching_sha2_password機能のせい

簡単な理由説明

MySQL8.0になってからユーザ認証方式として従来のmysql_native_passwordとは別にcaching_sha2_passwordが追加された。しかしプログラミング言語からMySQLにつなぐためのドライバの多くがcaching_sha2_passwordに対応していないために認証時にエラーが発生する。

やること

検索すると下記二つのどちらかでいいという記事が出てくるが、私は両方やらないと解決しなかった。

  • MySQLの特定のユーザの認証方式を変える。
  • MySQLのパスワードの認証方式を変える。

MySQLの特定のユーザの認証方式を変える。

MySQLにrootでログインし、変更したいユーザのパスワードを変更する。usernameとpasswordは各々の設定したいユーザ名と認証するときに利用するパスワードを入れてください。

mysql> alter user 'username'@'localhost' identified WITH mysql_native_password by 'password';

設定が反映されたことの確認

mysqlのプロンプトからSELECT user, host, plugin FROM mysql.user;と打ち込んでください。

設定したユーザのpluginがmysql_native_passwordになっていればよいようです。

この段階でうまくいく人もいるらしいです。わたしはうまくいかなかったのでmysql自体の設定をいじりに行きます。

mysql> SELECT user, host, plugin FROM mysql.user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| ******           | localhost | caching_sha2_password |
| mysql.infoschema | localhost | mysql_native_password |
| mysql.session    | localhost | mysql_native_password |
| mysql.sys        | localhost | mysql_native_password |
| root             | localhost | caching_sha2_password |
| ****             | localhost | mysql_native_password |
+------------------+-----------+-----------------------+

MySQLの認証方式を変える

MySQLの設定ファイルであるmy.iniを変更しに行きます。

my.iniC:\Program Data\MySQL\MySQL Server 8.0\にあります。

このProgram Dataというディレクトリは通常隠しファイル扱いになるのでエクスプローラの表示から隠しファイルのチェックボックスを入れてください。

f:id:kataware8136:20180530213537p:plain

my.iniの変更ですが、default_authentication_plugin=mysql_native_passwordとしてください。

[mysqld]

---(snip)

#default_authentication_plugin=caching_sha2_password
default_authentication_plugin= mysql_native_password

設定ファイルを変更したらMySQLのデーモンを再起動します

コマンドプロンプトから再起動

管理者用のコマンドプロンプトで実行してください

> net stop MySQL80
> net start MySQL80

サービス管理画面から再起動

win + rここに入力して検索のところでservices.mscと打ち込むとサービス管理画面を起動できます。

ここからMySQLのサービスを選んで右クリック、再起動してください。

設定が反映されたことの確認

mysqlのプロンプトからshow variables like 'default_authentication_plugin';を打ち込み、valuemysql_native_passwordとなっていれば大丈夫です。

mysql> show variables like 'default_authentication_plugin';
+-------------------------------+-----------------------+
| Variable_name                 | Value                 |
+-------------------------------+-----------------------+
| default_authentication_plugin | mysql_native_password |
+-------------------------------+-----------------------+

さいごに

pythonのドライバだけではなくphpのドライバでも同様の問題は起こっているみたいです。直にドライバも対応していくでしょうし、ドライバのほうがcaching_sha2_passwordに対応したら今回の設定内容を直すのが無難です。

というのもmysql_native_passwordよりも安全な認証方式になっているようです。なので今回の方法は一時しのぎといった感じでしょうが役に立てば幸いです。

参考文献

MySQL8.0新機能 (caching_sha2_password 認証プラグイン)

caching_sha2_passwordをサポートされているコネクタ一覧

コンボリューションを考える

数学ガールの第7章、コンボリューションを読んでるだけでは理解できなかったので手を動かしてみることにした

母関数の積までは読んでて理解できたので図書室からスタート

前提の問題

 \displaystyle

\begin{align} 0 + 1 + 2 &= (0 + (1 + 2) ) \\ &= ((0 + 1) + 2) \\ \end{align} 2なら2通り ( C_2 = 2 ) \begin{align} 0 + 1 + 2+ 3 + ... + n &= ? \\ \end{align} nなら何通りか( C_n = ?)

だいたいこんな感じ、正直詳しく知りたい人は本買おう

ミルカさんの解

私が理解したところ

  •  C_n =(SからGまでの経路数) - (SからG'までの経路数)

やること

  • 下降階乗冪をフル回転

下降階乗冪をフル回転

\begin{align} \begin{split} C_n &= \begin{pmatrix} 2n \\ n \end{pmatrix} - \begin{pmatrix} 2n \\ n+1 \end{pmatrix} \\ &= \frac{(2n-0)(2n-1)(2n-2)...\bigl(2n - (n-1) \bigr) }{(n-0)(n-1)(n-2)...\bigl(n-(n-1) \bigr)} - \\ &\quad \frac{(2n-0)(2n-1)(2n-2)...\bigl(2n-(n+1-1)\bigr)}{(n+1-0)(n+1-1)(n+1-2)...\bigl(n+1-(n+1 -1)\bigr)} \\ &= \frac{(2n)^\underline{n}}{(n)^\underline{n}} - \frac{(2n)^\underline{n+1}}{(n+1)^\underline{n+1}} \end{split} \end{align}

でこの後通分を行う。書籍にはない2番目の式を見ると

分子は \begin{align} &\quad(2n-0)(2n-1)(2n-2)...\bigl(2n-(n+1-1)\bigr) \\ &=(2n-0)(2n-1)(2n-2)...\bigl(2n-(n-1)\bigr)(n) \\ &= (2n)^\underline{n}・n \end{align}

分母は \begin{align} &\quad(n+1-0)(n+1-1)(n+1-2)...\bigl(n+1-(n+1 -1)\bigr) \\ &=(n+1)・(n-0)・(n-1)・...・3・2・1 \\ &= (n+1)・(n)^\underline{n} \end{align}

ということで最終的な式は以下のようになる

\begin{align} \frac{(n+1)・(2n)^\underline{n}}{(n+1)・(n)^\underline{n}} -\frac{(2n)^\underline{n}・(n)}{(n+1)・(n)^\underline{n}} \end{align}

後は計算をするだけだった。要は私は下降階乗冪がよくわかってなかったため理解できなかった。

結論は

\begin{align} C_n = \frac{1}{n+1} \begin{pmatrix} 2n \\ n \end{pmatrix} \end{align}

母関数へ旅をする

読んでて理解したのは母関数の閉じた式を入手したところ、そこから先を「僕」と同じように手を動かして進める。

まずは母関数の式

\begin{align} C(x) = \frac{1 \pm \sqrt{1-4x}}{2x} \end{align}

C(0)を考えると C_+(x)は不適であることになる。 そのため下の式を考える \begin{align} C(x) = \frac{1 - \sqrt{1-4x}}{2x} \end{align}

 \sqrt{1-4x}が邪魔なのでこれを冪級数 [tex:\sum_{k=0}^∞ K_k xk]を利用する

で、ここまで来て何なのだが、texで書くの疲れたのでこっからは写真.....、メモに見えてる某企業は何も関係ありません。たまたま近くにあったメモだったので使いました。

f:id:kataware8136:20180501151810j:plain

f:id:kataware8136:20180501152450j:plain f:id:kataware8136:20180501152457j:plain

母関数の国から数列の国へと帰ってきました。

感想

手を動かしてみると、読んでる時わからなかったのが理解できるようになったので、もし読んでるだけでわかりにくかったら手を動かすといいと思います。

無限級数の時の和の順序の変更には条件をきちんと述べる必要があるらしいのでそこらへんを調べにいってきます。

大学院に行くということ

卒業式は迎えてないのですが、卒業式参加者のリストに自分の名前があったので、私が大学院に進んだモチベーション、およびそれを達成できたのかどうかということを書き連ねたいと思います。

要はポエム記事、長いです。基本的に文句っぽいものがでたとしても文句ではないです。

私の院に行ったモチベーション

院に行く理由は人によって違うと思います。研究したいとかモラトリアム延長とかみんなが行くからとかあると思いますが私は

  • 自分の実力不足を強く感じていたから
  • 研究をするのに1年は少ないかなぁと思っていたから

という理由でした。

実力不足を感じた理由はCTFとセキュキャンに関する話ですね。国公立に行ってたから上位クラスだろとか思ってたんですが、情報系に関してはただの雑魚だということを思い知らされたので社会に出るのが怖い印象を持ってました。

なので実力不足に関しては院進含めた3年間あれば多少は補えるかなぁと思っていました。実力不足感は今もありますが社会に対する不安は今は全然ないです。

研究に関しては先輩の卒論発表見てこれよりももうちょっと進めていきたいなとか思っていました。

この2つを院に入ってどのような感じで解消したのかとか結果どうだったのかというのを書いていこうかなと

実力不足について

学部3年の時にセキュリティミニキャンプに参加しました。思い返せばこれが私の初めての学業方面での学外の活動です。誘ってくれた大学同期の実力が高いのは知っていたのですが、それ以外にもやばい人がいっぱいいた(あのミニキャンプ私のテーブルにやばい人が集中してた可能性あるんだけど)。ということで普段の授業を受けてただけの人間としては実力不足かつ社会に対する怖さ(このレベルの人間がいっぱいいるのが社会なのかという思い)を受けてもっと勉強しなきゃという思いに駆られました。

そのあとまじめに勉強したのかというと勉強はしていきました。ただ某氏とか某氏に比べたら成長速度とか遅いかったのでそこは自分のやる気不足でもあるなぁとお思うこともありました。またそういった存在がいることを知って同年代の人たちに追いつきたいという思いもでてきたので、個人的にはがんばったつもりです。

ただ同期がセキュリティばりばりの人間ではなかったので、外部からの刺激を得るためにセキュリティ勉強会やらに参加して、勉強する意識が低下しないようには心掛けていました。

社会に対する怖さってのはインターンに行ってなくなりました。院1年でインターンに行って、その当時の実力で2weekのインターンを難なくやっていけたので社会に出ても問題なさそうっていう判断ができました。

結論として実力不足は今も感じていますが社会に対しての恐怖心はないので社会人がんばれます。

研究期間と研究について

研究期間

まぁ研究を進めていきたい人にとってはやっぱり短いかなと思います。まぁ研究室にもよると思います。うちの研究室は遅めのスタートだったのでそれを考えると3年間研究してていいと思いました。ただ私は結構興味が移りやすい部分はあるので1年なら1年でまとまってはいたので後悔はしなかっただろうなぁとも思いますね。

研究

私の研究内容を知りたい人は調べてください。自分としては納得いかない部分(主にコーディング技術)がありました。ただ研究内容に関してはあんまり詰まることがなかったので研究としてはある程度の満足はあります。 あとは研究を進めていくにあたって、研究内容を論文にする際に私の文章力がひどいことがわかりました(多分このポエムもそうとう読みにくいし誤字もあると思います)。まぁそんな感じで自分の苦手な部分を知ることができました。何気に研究って調査力、文章力、実装力等多方面の能力を鍛えていく必要があります。

結論、研究期間として1年でも3年でも私は問題なかった。3年あった分いろいろ同期や後輩の研究を見てきたので知識は増えたのでそういう意味でとてもよかった。 研究内容が自由に決めれて研究内容は有意義だった、自分の苦手な点はわかったのでよかったかなと。

マイナス面

だらけた....いやもっとできただろっ的な感覚はある、実務をいきなりやった方が実力はつきそう。やっぱ世の中お金、お金を稼ぎつつ実力つけれるのが便利、ただ自由な時間はあるのか...ここらへんはわからん

総じて

院進自体に後悔はないです。これは研究室の雰囲気、院進するための目的そこらへんが自分に合っていたと思います。むしろ私にとってはプラスだったと思います。

プラスの要素として、下の感じかなと思います。

  • 外部の勉強会に行っても特に問題なかった(コアタイムがなかったので)
    • ミーティングにかぶってても進捗さえ書いておけば許されたと思う(多分なかったけど)
  • 研究でやりたいことをやらせてもらえた
  • 研究室で好き放題にいろいろやれた(ラズパイ使ったり,学内CTFもどきやれたり)

院進して増えた2年を有益に使えたと感じます。

院進にあたって

最後にいろいろと、院進するかどうか悩む人はこの時期はもう就活始まってるのでないと思いますが今後考えていく人向けとかもう卒業して院行ったならどうだったんだろうとか考える人向けに少し書きます。

正直学んでいきたい人は院進して後悔するのは少ないと思います。研究は学びつつ新たなところを開拓していくのでそういう意味で公開しないと思います。しかし研究室の相性はすごく重要です。研究室と合わないのであれば研究したい・学びたい人でも後悔すると思います。同期にも精神をすり減らしていた人がいました。

研究室を選ぶ優先度として研究室の雰囲気>研究内容だと思います。それで問題なく研究したい・学びたい人は院進してもいい感じに学べていけると思います。なんだかんだ今はいろんな人が技術ブログ書いてたりするので学ぶ部分に関してはやる気さえあれば学ことはできます(私の場合ももいろテクノロジー様には大変感謝しております)ので、そういうことを考えて院進や研究室選びするといいんではないかと思います。

おわり

春から新社会人です。まぁ社会人として仕事もがんばりつつ、セキュリティに関しても勉強していく感じで私はがんばっていきます。ここまでお読みいただきありがとうございます。