ここでは、MySQL サーバに接続しようとして Access denied エラーが発生した場合の対処法について説明します。
まず、サーバが起動していることを確認します。起動していなければ接続はできません。たとえば、サーバに接続しようとして、次のようなメッセージが出るときには、サーバが立ち上がっていない可能性があります。
shell>mysql
ERROR 2003: Can't connect to MySQL server on 'host_name
' (111) shell>mysql
ERROR 2002: Can't connect to local MySQL server through socket '/tmp/mysql.sock' (111)
サーバは起動しているが、TCP/IP
ポート、名前付きパイプ、Unix ソケット
ファイルで接続しようとしている場合に、サーバが使用しているものが異なる場合があります。これを修正するには、クライアント
プログラムを呼び出すときに、--port
オプションを適切なポート番号を指すように指定します。または
--socket
で適切な名前付きパイプまたは Unix ソケット
ファイルを指定します。ソケット
ファイルの場所を検索するには、次のコマンドを使用します。
shell> netstat -ln | grep mysql
サーバがアクセス制御に使用する権限テーブルは正確にセットアップする必要があります。Windows
のバイナリ配布、または Linux の RPM
配布など、配布の種類よっては、インストールのプロセスで、権限テーブルがある
mysql
データベースを初期化します。これをしない種類の配布では、手動で権限テーブルを初期化する必要があります。これには、mysql_install_db
スクリプトを実行します。詳細は
項2.10.2. 「Unix のインストール後のプロシージャ」
を参照してください。
権限テーブルを初期化する必要があるかどうかを調べるには、データ
ディレクトリの mysql
をチェックします。通常、データ
ディレクトリは、data
または
var
と名前で、MySQL
をインストールしたディレクトリ下にあります。mysql
データベース ディレクトリに
user.MYD
ファイルがあることを確認してください。これをしない場合は、mysql_install_db
スクリプトを実行してください。このスクリプトを実行してから、サーバを起動し、次のコマンドを実行して、イニシャル権限をテストします。
shell> mysql -u root test
これで、エラーなしでサーバに接続できます。
問題なくインストールできたら、サーバに接続して、ユーザとアクセス制限についてセットアップします。
shell> mysql -u root mysql
MySQL root
には最初からパスワードがありません。そのため、サーバへの接続は問題なくできます。これには、セキュリティ面でのリスクが伴うため、root
アカウントのパスワードは、MySQL
アカウントをセットアップするときに、セットすることをお勧めします。初期パスワードの設定手順に関しては、項2.10.3. 「最初の MySQL アカウントの確保」
を参照してください。
MySQL ネットワーク. MySQL Network Monitoring and Advisory Service では、セキュリティ関連の最適化を励行しています。購読者には、パスワードなしのユーザを検出すると、それを警告しています。詳細は、http://www-jp.mysql.com/products/enterprise/advisors.html を参照してください。
MySQL のバージョンを更新するときには、mysql_upgrade スクリプトを実行する必要があります。新バージョンの機能によっては、権限テーブルのストラクチャを変更することがあります。そのため、アップグレードした後は、常に、テーブルがカレント ストラクチャであるかどうかを確かめてください。この手順に関しては 項4.5.4. 「mysql_upgrade — MySQL アップグレードのテーブル チェック」 を参照してください。
クライアント プログラムで接続時に次のようなエラー メッセージが出る場合、そのクライアントが生成する形式よりも新しい形式でのパスワードをサーバが必要としている、ということを示します。
shell> mysql
Client does not support authentication protocol requested
by server; consider upgrading MySQL client
これに関する対処法に関しては、項4.7.9. 「MySQL 4.1 のパスワードハッシュ」
および 項B.1.2.3. 「Client does not support authentication protocol
」
を参照してください。
root
で接続をしようとする場合に、次のようなエラーが出るときには、'root'
の User
フィールドに、user
テーブルのエントリがないことを示します。そのため、mysqld
がクライアントのホスト名を識別できない状態です。
Access denied for user ''@'unknown' to database mysql
この場合、--skip-grant-tables
オプションでサーバを立ち上げ、/etc/hosts
ファイル、または \windows\hosts
で、ホストのエントリを付加します。
クライアント
プログラムは、環境変数またはオプション
ファイルで指定する接続パラメータを使用します。そのため、コマンドラインからデフォルトの接続パラメータを指定していない場合には、適切ではないパラメータを送ることがあります。そのときは、環境変数、および該当するオプション
ファイルを調べます。たとえば、オプションなしでクライアントを実行するときに、Access
denied
となる場合、オプション
ファイルのどこかで古いパスワードを指定している可能性があります。
使用しているオプション
ファイルをクライアント
プログラムで抑制することができます。これには、
--no-defaults
を行使します。
shell> mysqladmin --no-defaults -u root version
クライアントが使用するこのオプション ファイルの一覧は、項3.3.2. 「オプションファイルの使用」 を参照してください。環境変数の一覧は、項2.14. 「環境変数」 を参照してください。
次のエラーが出る場合は、 使用している
root
のパスワードが誤っていることを示します。
shell> mysqladmin -u root -pxxxx
ver
Access denied for user 'root'@'localhost' (using password: YES)
パスワードを指定していない場合に、このようなエラーが出るときには、オプション
ファイルのどこかに誤ったパスワードがあることを示します。前述の項目で説明したように、--no-defaults
で確かめてください。
パスワードの変更に関する情報は、項4.8.5. 「パスワードの設定」 を参照してください。
root
パスワードを忘れた場合、--skip-grant-tables
で mysqld
を再起動して、パスワードを変更します。詳細は
項B.1.4.1. 「How to Reset the Root Password」
を参照してください。
パスワードの変更に、SET
PASSWORD
、INSERT
、
UPDATE
を使用する場合は、PASSWORD()
関数でそのパスワードを暗号化します。これらのステートメントを使用するときに、PASSWORD()
関数を使用しないと、パスワードは機能しません。たとえば、次にようなすテーとメントでパスワードをセットしても、それを暗号化していない場合、そのユーザはそれ以降の接続ができません。
SET PASSWORD FOR 'abe'@'host_name
' = 'eagle';
そのため、パスワードを次のようにセットします。
SET PASSWORD FOR 'abe'@'host_name
' = PASSWORD('eagle');
GRANT
または CREATE
USER
ステートメント、あるいは
mysqladmin password
コマンドでパスワードを指定するときは、PASSWORD()
関数は不要です。これらの方法では、自動的に、PASSWORD()
をパスワードの暗号化に適用します。詳細は
項4.8.5. 「パスワードの設定」 および
項12.5.1.1. 「CREATE USER
構文」 を参照してください。
localhost
はローカル
ホスト名のシノニムです。ホストを明示的に指定しないときには、これがクライアント接続でのデフォルトのホストとなります。
このような問題を回避するには、--host=127.0.0.1
オプションをサーバ
ホストを明示的に指名します。その場合、TCP/IP
で、ローカルの mysqld
サーバに接続します。TCP/IP
接続には、--host
オプションで実際のローカル
ホストのホスト名を使用できます。この場合、そのサーバの同じホストでクライアント
プログラムを実行している場合でも、ホスト名をサーバホストの
user
テーブル
エントリで指定する必要があります。
mysql -u
でデータベースに接続しようとするときに、user_name
Access
denied
エラーが出る場合は、user
テーブルに問題がある可能性があります。これをチェックするには、mysql
-u root mysql
の実行し、次の SQL
ステートメントを発行します。
SELECT * FROM user;
結果には、コンピュータのホスト名と MySQL
ユーザ名と一致する Host
と
User
のカラムのエントリが出ます。
Access denied
というエラー
メッセージは、ログインしようとしているユーザ名、接続元のホスト、およびパスワードを使用したかどうかを通知します。通常、user
テーブルに、ホスト名とユーザ名に完全にマッチするエントリが
1
つあり、これが このエラーメッセージに出ます。たとえば、エラーメッセージに
using password: NO
と出る場合、パスワードなしでログインしようとしたことを示します。
MySQL
サーバを実行しているホストではないホストから接続しようとして以下のエラーが発生する場合、クライアント
ホストと一致する Host
値では、レコードが user
テーブルにないということを示します。
Host ... is not allowed to connect to this MySQL server
これは、接続時に使用するクライアント ホスト名とユーザ名を組み合わせたアカウントをセットアップすることで解決します。
接続元のコンピュータの IP
アドレスまたはホスト名がわからない場合、user
テーブルの Host
カラムに
'%'
を使用します。そして、そのクライアント
コンピュータから接続しようとするときに、SELECT
USER()
クエリを使用して、実際にどのように接続したか確認します。そのときに、user
テーブル エントリの
'%'
をログにある実際のホスト名と置き換えます。この作業を行なわない場合、どのホストからでもそのユーザ名での接続ができることになるので、セキュリティ上の問題になります。
Linux
上で、このエラーが発生する別の理由として、使用しているバイナリ
MySQL バージョンが、glibc
ライブラリが異なるバージョンを使用してコンパイルしている可能性があります。この場合、OS
または glibc
をアップグレードするか、または MySQL
のソース配布をダウンロードして
(自分で) コンパイルします。ソース RPM
は通常、コンパイルおよびインストールが簡単です。そのため、これは大した問題ではありません。
ホスト名で接続しようとしたにもかかわらず、エラーメッセージにホスト名がない、またはホスト名が IP アドレスである場合は、MySQL サーバで、 クライアント ホストの IP アドレスを解決しようとしてエラーになったことを示します。
shell> mysqladmin -u root -pxxxx
-h some_hostname
ver
Access denied for user 'root'@'' (using password: YES)
これは、DNS に問題があることを示します。これを修正するには、mysqladmin flush-hosts を実行して、内部 DNS ホスト名キャッシュをリセットします。項6.5.6. 「MySQLの DNS の使用」 を参照してください。
この解決策としては、次のことを検討します。
DNS サーバの問題を割り出し、それを修正する。
ホスト名ではなく、IP アドレスを MySQL の権限テーブルで指定する。
/etc/hosts
または
\windows\hosts
にクライアントのマシン名のエントリを入力する。
mysqld を
--skip-name-resolve
オプションで起動する。
mysqld を
--skip-host-cache
で起動する。
Unix
では、サーバとクライアントを同じマシンで実行している場合、localhost
に接続する。localhost
への
Unix 接続は、TCP/IP ではなく Unix ソケット
ファイルを使用する。
Windows
では、サーバとクライアントを同じマシンで実行して、サーバが名前付きパイプ接続をサポートしている場合、ホスト名
.
(ピリオド)
に接続する。.
(ピリオド) への接続には、TCP/IP
ではなく、名前付きパイプを使用する。
mysql -u root test
は機能するけれども、your_hostname
がローカル
ホストの実際のホスト名であるにも関わらず、mysql
-h
で your_hostname
-u root
testAccess denied
が出る場合、user
テーブルにホストへの正確な名前がない可能性があります。この場合によくある問題として、user
テーブル エントリの Host
値が適切ではないホスト名を指定して、システムでの名前解決ルーチンが完全に適切であるドメイン名を返すことがあります
(またはこの逆の場合もあります)。たとえば、ホストを
'tcx'
とするエントリが
user
テーブルにあるにも関わらず、DNS で MySQL
にホスト名は
'tcx.subnet.se'
であると伝えてしまうと、そのエントリが適用になりません。そのため、user
テーブルに、ホストの IP アドレスを
Host
のカラム値として付加します。または、user
テーブルに、'tcx.%'
というように、ワイルドカード文字を
Host
値に使用します。しかし、‘%
’
をホスト名の終わりに付けるのは、セキュリティ面での安全を確保できない
という理由から
推奨はしていません。
mysql -u
は機能するけれども、user_name
testmysql
-u
が機能しない場合、そのユーザには、
user_name
other_db_name
other_db_name
のデータベース
アクセスを許可していないことを意味します。
mysql -u
はサーバ
ホストで実行したときには機能するけれども、user_name
mysql
-h
がリモートのクライアント
ホストから実行したときに機能しない場合、リモート
ホストからはそのユーザ名でサーバにアクセスできないようになっていることを意味します。
host_name
-u
user_name
Access denied
エラーの原因がわからない場合、user
テーブルのエントリから、‘%
’
または ‘_
’
などのワイルドカード文字が付いている
Host
値をすべて削除します。ここで、Host
= '%'
および
User
=
'
という新しいエントリを挿入して、これで同じマシンから接続するために
some_user
'localhost
を指定することができるようになると考えることは誤りです。これは機能しません。その理由は、デフォルト権限で、Host
= 'localhost'
および
User
= ''
というエントリを含むためです。このエントリには、Host
カラムに 'localhost'
という '%'
よりも明確な値があるため、localhost
から接続するときに新しいエントリよりもデフォルトのエントリが優先になります。そのため、正確な手順としては、Host
= 'localhost'
および
User
=
'
と改めて指定するか、または
some_user
'Host
=
'localhost'
および
User
= ''
のエントリを削除します。このエントリを削除したら、
FLUSH PRIVILEGES
ステートメントを発行して、権限テーブルのリロードを必ず行なってください。
次のようなエラーが出る場合、db
または host
のいずれかのテーブルで問題がある可能性があります。
Access to database denied
db
テーブルで選択するエントリに空白の
Host
カラムがある場合、db
テーブルのエントリで適用するホストを指定するときに、対応するエントリが
host
テーブルに、 1
つ以上あることを確認してください。
MySQL
サーバに接続はできるけれども、SELECT
... INTO OUTFILE
または LOAD DATA
INFILE
を発行すると、Access
denied
が出る場合は、user
テーブルのエントリで、FILE
権限がないことを意味します。
INSERT
, UPDATE
または DELETE
などのステートメントを使用して、直接に権限テーブルを変更するときに、それが効力を発揮していない場合は、FLUSH
PRIVILEGES
ステートメント、または
mysqladmin flush-privileges
コマンドを実行して、サーバへのその権限テーブルの再読み込みを行ないます。これをしないと、変更した内容が次にサーバを起動するまで発効しません。UPDATE
コマンドで root
パスワードを変更した場合は、その権限をフラッシュするまで、新たなパスワードを使用する必要はありません。その時点
(変更しただけ)
では、サーバがまだパスワードを変更したことを認識していません。
セッション中に権限が変更された可能性がある場合、MySQL の管理者がそれを変更した可能性があります。権限テーブルのリロードは、それ以降のクライアント接続に影響します。これは、既存の接続に対しても影響します。これに関しては、項4.7.7. 「権限の変更が反映するタイミング」 を参照してください。
Perl、PHP、Python、ODBC
プログラムでアクセスに問題がある場合は、mysql
-u
または
user_name
db_name
mysql -u
で、サーバへの接続を試行します。
mysql
クライアントを使用して接続できる場合は、問題の根源は、アクセス権限ではなく、プログラムにあります。user_name
-pyour_pass
db_name
-p
とパスワードの間には、空白はありませんが、
--password=
シンタックスを使用して、パスワードを指定することもできます。パスワードなしで
your_pass
-p
--password
オプションを使用すると、MySQL
でパスワードの入力を指示します。
テストするときは、mysqld
サーバを --skip-grant-tables
オプションで起動します。そのとき、MySQL
権限テーブルを変更でき、mysqlaccess
スクリプトを使用して、変更内容に目的の効力があるかどうかをチェックできます。その内容が意図していたものである場合、mysqladmin
flush-privileges
を実行して、mysqld
サーバに新たな権限テーブルを使用するよう指示できます。権限テーブルのリロードは、--skip-grant-tables
オプションを上書きします。そのため、この上書きでサーバにリロードした権限テーブルをサーバのシステム終了や再起動をしなくても使い始めることができます。
前述の事柄を試しても、解決しない場合、--debug=d,general,query
などの mysqld サーバをデバッグ
オプションで立ち上げます。つまり、接続試行に関するホストとユーザの情報と、使用したコマンドも関する情報を出力します。Creating Trace Files
を参照してください。
MySQL
権限テーブルについて、ここで示したこと以外の問題がある場合は、メーリング
リストで問題提起してください。そのときには、MySQL
権限テーブルのダンプも添付してください。テーブルのダンプは、mysqldump
mysql
コマンドでします。バグのレポートは、項1.7. 「質問またはバグの報告」
の手順に従ってください。場合によっては、mysqldump
を実行するためには、--skip-grant-tables
オプションで、mysqld
を再起動する必要があります。