MySQL 8 min read

mysql -u root -pの意味 ― -pの後の空白で変わる動作とERROR 1045/2002/2003

mysql -u root -p は、mysql クライアントで root ユーザーとしてログインし、パスワードを入力させるコマンドです。-u がユーザー名、-p が「パスワードを使う」の指定です。この記事の出力は MySQL 8.4.6 で採りました。

まず見る(結論)

  • -p だけ書けば、実行後にパスワードを聞かれる。これが一番安全
  • パスワードを続けて書くなら -pパスワード と空白なしにする。-p パスワード だと、パスワードではなくデータベース名として扱われる
  • -h localhost(または -h なし)はソケット、-h 127.0.0.1 は TCP で接続する
  • エラー番号で原因が分かれる。1045 はユーザー名かパスワード、2002 はソケット、2003 はホストかポート

-p とパスワードの間の空白

$ mysql -uroot -p****** -e 'SELECT 1'
mysql: [Warning] Using a password on the command line interface can be insecure.
+---+
| 1 |
+---+
| 1 |
+---+

接続はできますが、警告が出ます。コマンドラインに書いたパスワードは、シェルの履歴や ps の表示から他人に見えることがあるためです。

空白を入れると、意味が変わります。

$ mysql -uroot -p ****** -e 'SELECT DATABASE()'
Enter password:
ERROR 1049 (42000): Unknown database '******'

-p の後に値が無いのでパスワードを聞かれ、後ろの ****** は接続先のデータベース名として扱われました。正しいパスワードを入力しても、その名前のデータベースは無いので ERROR 1049 になります。ユーザー名の -u root は空白があってもなくても同じです。

localhost と 127.0.0.1 は接続方法が違う

status の Connection 行で、どちらの方法でつながったかが分かります。

$ mysql -h 127.0.0.1 -u root -p -e 'status' | grep -A1 Connection
Connection:             127.0.0.1 via TCP/IP
TCP port:               3306

$ mysql -h localhost -u root -p -e 'status' | grep -A1 Connection
Connection:             Localhost via UNIX socket
UNIX socket:            /var/run/mysqld/mysqld.sock

Linux の mysql クライアントは、localhost を指定する(または -h を省く)と、TCP ではなく UNIX ソケットのファイルで接続します。127.0.0.1 と書くと TCP の 3306 番です。

この違いは、どのアカウントで認証されるかにも影響します。MySQL のアカウントは「ユーザー名@host」の組です。ソケットなら 'root'@'localhost' として、TCP なら接続元 127.0.0.1 として照合されます。一方では入れるのにもう一方では入れないときは、SELECT user, host FROM mysql.user; で、該当する host のアカウントがあるかを見ます。

エラー番号で原因を分ける

ERROR 1045: ユーザー名かパスワードが違う

$ mysql -uroot -pwrong
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)

サーバーまでは届いていて、認証で拒否されています。'root'@'localhost' の部分が、サーバーが照合しようとしたアカウントです。using password: NO と出たら、パスワードを渡せていません(-p の付け忘れなど)。

ERROR 2002: ソケットにつながらない

$ mysql -uroot -p --socket=/tmp/nosuch.sock
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/nosuch.sock' (2)

localhost でソケット接続しようとして、ソケットファイルが無いときのエラーです。末尾の (2) は「ファイルが無い」という OS のエラー番号です。原因は、サーバーが止まっているか、クライアントが見ているソケットの場所とサーバーの設定(socket)が食い違っているかです。-h 127.0.0.1 で TCP 接続を試すと、どちらの問題かを切り分けられます。

ERROR 2003: ホストかポートにつながらない

$ mysql -h 127.0.0.1 -P 3307 -uroot -p
ERROR 2003 (HY000): Can't connect to MySQL server on '127.0.0.1:3307' (111)

TCP で接続できないときのエラーです。(111) は接続を拒否された(そのポートで誰も待ち受けていない)という意味です。ポート番号の間違い、サーバー停止、bind_address の設定、ファイアウォールを順に疑います。

毎回パスワードを打たない(~/.my.cnf)

ホームディレクトリの ~/.my.cnf に接続情報を書くと、mysql だけで入れます。

[client]
user=root
password=******
$ mysql -e 'SELECT CURRENT_USER();'
+----------------+
| CURRENT_USER() |
+----------------+
| root@localhost |
+----------------+

パスワードが平文で入るので、chmod 600 ~/.my.cnf で本人以外が読めないようにします。ファイルを消すと、引数なしの mysql は ERROR 1045 ... (using password: NO) に戻りました。