我有一个脚本来安装 MySQL 5.7 并在Travis CI(运行 Ubuntu 12)上运行测试。
该脚本包含这些行,以非交互模式安装 MySQL,没有密码:
add-apt-repository 'deb http://repo.mysql.com/apt/ubuntu/ precise mysql-5.7-dmr'
apt-get update
echo mysql-community-server mysql-community-server/root-pass password "" | debconf-set-selections
echo mysql-community-server mysql-community-server/re-root-pass password "" | debconf-set-selections
DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold -q -y install mysql-server libmysqlclient-dev
Run Code Online (Sandbox Code Playgroud)
安装运行顺利,使用mysql
命令行实用程序,我可以不用密码连接到服务器:
mysql --user=root -e "SELECT VERSION();"
Run Code Online (Sandbox Code Playgroud)
+-----------+
| VERSION() |
+-----------+
| 5.7.8-rc |
+-----------+
Run Code Online (Sandbox Code Playgroud)
现在,如果我尝试使用 PHP PDO进行连接:
new PDO('mysql:host=localhost', 'root', '');
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
SQLSTATE[HY000] [1045] 用户 'root'@'localhost' 的访问被拒绝(使用密码:NO)
我试图允许root
从任何主机连接:
GRANT ALL ON *.* to root@'%' IDENTIFIED BY '';
FLUSH PRIVILEGES;
Run Code Online (Sandbox Code Playgroud)
没有成功。
可能是什么问题?
在 MySQL 手册Pluggable Authentication 中找到了答案:
从 MySQL 5.5.7 开始,服务器使用插件对客户端进行身份验证。从 mysql.user 表中选择正确的帐户行是基于用户名和客户端主机,如前所述,但服务器通过从帐户行中确定哪个身份验证插件适用于客户端来对客户端进行身份验证。
MySQL 包root
使用auth_socket
身份验证插件创建用户,因此只允许通过套接字连接,并且还会检查 Linux 帐户的用户名。
该mysql
命令默认使用套接字,并root
在我的脚本中运行,因此允许连接。
根据 PHP 手册,PDO MySQL 连接localhost
也使用套接字;但是 PHP 以非特权用户身份运行,因此auth_socket
插件拒绝了连接。
我通过添加以下行来修复我的脚本:
mysql --user=root -e \
"UPDATE mysql.user SET plugin='mysql_native_password'; FLUSH PRIVILEGES";
Run Code Online (Sandbox Code Playgroud)
它现在工作正常。