mysql 5.6ユーザーパスワードの期限切れの問題


1.バージョン
1)オペレーティングシステム
 cat/etc/issue cat/etc/issue CentOS release 6.6 (Final) Kernel\r on an\m
 cat/proc/version cat/proc/version Linux version 2.6.32-504.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) ) #1 SMP Wed Oct 15 04:27:16 UTC 2014
2)mysqlデータベースバージョン
mysql --version mysql  Ver 14.14 Distrib 5.6.26, for linux-glibc2.5 (x86_64) using  EditLine wrapper
2.問題の説明
2.1問題の発見
今日、監視レポートが突然mysqlデータベースのバックアップに失敗しました(mysqlアーキテクチャがプライマリで、ライブラリからmysqldumpとmebの2つのバックアップが導入されました).バックアップログには、次のエラーが表示されます.
Warning: Using a password on the command line interface can be insecure.
mysqldump: Got error: 1862: Your password has expired. To log in you must change it using a client that supports expired passwords. when trying to connect
##バックアップスクリプトは長い時間がかかりました.これまでバックアップは正常でした. 
バックアップ・スクリプトの主な文は次のようになります.
mysqldump -uroot -p -h127.0.0.1 --all-databases --events --routines --triggers --single-transaction --default-character-set=utf8 --complete-insert --flush-privileges --hex-blob --dump-slave=2 >database_3307.sql

3.問題分析
上記のエラーから私たちはユーザーが期限切れになったことを知っています.mysql 5.6はすでにユーザーを期限切れにする機能を持っていますが、ALTER USER account PASSWORD EXPIRE文を通じてしかユーザーを期限切れにすることはできません.ユーザーは自動的に期限切れになりません(例えば、ユーザーがしばらく使用してから自動的に期限切れになり、5.6はしばらくこの機能がありません)
しかし、会社は私のdbaだけで、他の人もデータベースのsuper権限を持っていません.では、ユーザーはなぜ期限切れになったのでしょうか.次にゆっくり分析します
1)表示127.0.0.1対応rootユーザーが期限切れになったかどうか
mysql -uroot -p -S/tmp/3306.sock
mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

mysql> select user,host,password,password_expired from mysql.user where user = 'root';
+------+---------------------+-------------------------------------------+------------------+
| user | host                | password                                  | password_expired |
+------+---------------------+-------------------------------------------+------------------+
| root | localhost           | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | N                |
| root | all-middle-mysql-10 | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | Y                |
| root | 127.0.0.1           | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | Y                |
| root | ::1                 | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B | Y                |
+------+---------------------+-------------------------------------------+------------------+
4 rows in set (0.00 sec)

##ここでは、「root'@'localhost」ユーザーが期限切れになっていないことを除いて、他の3人のrootユーザーが期限切れになっていることを見ました(これらのユーザーがなぜ期限切れになったのかについては、こちらのブログでは説明しません.興味のある人は私の別のブログを見てください).
2)root'@'127.0を使用してみる.0.1'ユーザーログインデータベース
mysql -uroot -h127.0.0.1 -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 5.6.26-log

Copyright (c) 2000, 2015, 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 user,host,password,password_expired from mysql.user;
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
mysql> 
##コマンドラインで使用されていることに注意してください.
'root'@'127.0.0.1'はデータベースにログインできますが、任意の操作を行うとパスワードの変更を求めるメッセージが表示されます.
3)手動でバックアップスクリプトを実行する
 ./mysqlbak3306.sh
Warning: Using a password on the command line interface can be insecure.
mysqldump: Got error: 1862: Your password has expired. To log in you must change it using a client that supports expired passwords. when trying to connect
##バックアップスクリプトを呼び出すと、2.1でエラーが発生しました.
4)データベースの最近の変更
以前はバックアップスクリプトが正常に動作していたため、突然エラーが発生しました(root'@'127.0.0.1'ユーザーに対して期限切れの操作をしたことがないと確信しています).では、前回の正常なバックアップが発生した後、今回の失敗したバックアップとの間でデータベースに対してどのような操作を行ったかを考慮する必要があります.最も問題になる可能性が高いのは、データベースにskipを設定することです.name_resolve=1パラメータでデータベースを再起動しました.
##実はこれを分析して、mysqlの登録の原理に対して比較的に熟知している友达はすでに問題の所在を知っているはずです.skipを設定しないとname_resolve=1で、「root'@'127.0」を使用します.0.1'ログイン時、実際には逆解析後に'root'@'localhost'でログインしたデータベース(/etc/hostsファイルでは127.0.0.1がlocalhostに対応しているため)であり、このユーザーは期限切れではないので、バックアップが正常に行われることがわかります.
skip_を指定したらname_resolve=1であれば、ログイン時に逆解析するステップはありません.この場合、私たちは'root'@'127.0を使用します.0.1'このユーザーはログインしていますが、このユーザーは期限切れなので、バックアップエラーが発生しました.次にskipを設定するか設定しないかを見てみましょう.name_resolveでは'root'@'127.0を使用する.01'ログインの違い
....................................................................................................................................................................................................................................
skipを設定しないとname_resolve=1で、「root'@'127.0」を使用します.01'ユーザーがデータベースにログインすると、次のユーザー情報が表示されます.
mysql> select user();
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
<pre name="code" class="html">mysql> select user();
+----------------+
| user()         |
+----------------+
| [email protected] |
+----------------+
1 row in set (0.00 sec)
   如果我们设置了skip_name_resolve = 1后使用'root'@'127.0.0.1'登录数据库后看到的用户信息如下: 
  
 

mysql> select user();
+----------------+
| user()         |
+----------------+
| [email protected] |
+----------------+
1 row in set (0.00 sec)
mysql> select current_user();
+----------------+
| current_user() |
+----------------+
| [email protected] |
+----------------+
1 row in set (0.00 sec)

4.ソリューション
実はこの問題の解決策は簡単で、期限切れのユーザーのパスワードをリセットすればいい(update mysql.userメソッドでパスワードをリセットできないことに注意)
mysql -uroot -p -h127.0.0.1
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.6.26-log

Copyright (c) 2000, 2015, 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 user();
ERROR 1820 (HY000): You must SET PASSWORD before executing this statement
mysql> set password for 'root'@'127.0.0.1' = password('root');
Query OK, 0 rows affected (0.05 sec)

##問題の解決方法は簡単ですが、問題の原因を見つけることは、問題を解決することよりも重要だと思います.