MySQL PHP 不兼容性

24

我在本地运行WAMP,但连接到远程MySQL数据库。本地版本的PHP是最新的5.3.0。

其中一个远程数据库,即版本为5.0.45的数据库可以正常工作。然而,我正在尝试连接的另一个远程数据库,即版本为5.0.22的数据库在死机前会抛出以下错误:

警告:mysql_connect() [function.mysql-connect]:OK数据包比预期短6个字节。PID=5880 in ...

警告:mysql_connect() [function.mysql-connect]:mysqlnd无法使用旧身份验证与MySQL 4.1+建立连接。在…

什么鬼?

更新:

回退到PHP 5.2.*即低于5.3.0的任何版本都可以完全解决该问题。只要我不运行5.3.0,我就可以连接到这两个数据库。我不确定这种怪异现象的解释是什么。


mysqlnd不是5.2的一部分,也就是说,你现在已经回退到php 5.2并使用了另一个连接器/库。 - VolkerK
那么5.3会有什么可能的问题? - Evernoob
10个回答

45

你使用的MySQL账户可能有一个旧的16个字符长的密码(哈希值)。


你可以使用MySQL客户端(如HeidiSQL、MySQL控制台客户端或任何其他客户端)和具有访问mysql.user表的权限的账户进行测试。如果Password字段包含16个字符,则它是旧密码,mysqlnd无法使用它连接到MySQL服务器。


你可以为该用户设置新密码,方法如下:

SET PASSWORD FOR 'username'@'hostmask' = PASSWORD('thepassword')

请参考dev_mysql_set_password

编辑:
您还应检查服务器是否设置为默认使用/创建旧密码

编辑2:
请运行查询

SELECT
  Length(`Password`),
  Substring(`Password`, 1, 1)
FROM
  `mysql`.`user`
WHERE
  `user`='username'

在5.0.22服务器上(即"失败"的那个),用mysql_connect()中正在使用的帐户替换username
返回的是什么?


没有两个认证是完全相同的,也不会像那样冗长。 - Evernoob
“不是那么长?” 我的意思不是明文密码,而是存储在用户表中的哈希值;-)旧算法使用16个字符,新算法...嗯...40个字符? - VolkerK
是的...还是不行,抱歉。这是一个奇怪的错误,真让我烦恼。 - Evernoob
我从来没想到会是这个答案。你太棒了!总有一天我请你吃饭。 - gknauth
有没有办法告诉客户端使用旧密码?我无法改变主机上正在发生的事情。我正在尝试开发现有应用程序。我不知道如何修改xampp以使用旧版本的php。 - JDPeckham
显示剩余2条评论

7

我一直在寻找一种简单的解决方法。可以尝试这个方法。在MySQL中输入:

SELECT Host, User, Password FROM mysql.user;

如果您的密码是16个字符,那么这是因为您在用户上使用了OLD_PASSWORD或运行了旧版本的MySQL。要更新,请输入:
UPDATE mysql.user SET Password=PASSWORD('newpass')
  WHERE User='root' AND Host='localhost';
FLUSH PRIVILEGES;

将用户、主机和密码分别替换为根、localhost和newpass。现在当您重新输入时

SELECT Host, User, Password FROM mysql.user;

您的密码应该已经更改了。这对我有用。


1
最简单的解决方法!将密码更新为相同的旧密码(Password=PASSWORD('oldpass'))也可以起到作用。 - kehers
2
如果服务器仍然默认创建16个字符的密码,您仍然可以解决此问题:在本地计算机上使用SELECT PASSWORD('yourpass');创建41个字符的哈希值,然后将打印的哈希值复制到类似以下命令的命令中,并在服务器计算机上执行它:UPDATE mysql.user SET Password='yourhash' WHERE User='root'; FLUSH PRIVILEGES; - tanius

4

您的数据库服务器默认使用旧密码。您看到的错误信息是mysqlnd看到了一个支持新(更安全)身份验证的数据库,但拒绝使用它。在这种情况下,mysqlnd会中止连接并拒绝工作。

请确保您的my.cnf文件没有以下设置:

old-passwords = 1 

在注释掉my.cnf文件中的该设置(或从其他设置位置删除它)并重新启动服务器后,确保使用VolkerK描述的命令重新设置密码,否则您将无法登录。


我在my.ini中没有ol-passwords = 1,那么我该如何更改数据库服务器以不使用旧密码? - Sid
1
@sid:MySQL可以加载多个配置文件,您需要确保它们中没有一个启用了旧密码。另一种可能性是全局变量old_passwords设置为1。要检查,请运行SELECT @@global.old_passwords; - Guss

3
更简单的解决方案是删除数据库用户并创建一个新的带有相同用户名和密码的用户。

这是我决定更新我的 ppa:ondrej/php 后发生的。我还必须更新我的 apache2 服务。长话短说,这个 mysql 问题也发生在我身上。我想说这个解决方案对我有效,我甚至不需要费事创建一个新用户。我只需要更新现有用户的密码即可。希望这能帮助其他人走出困境。感谢您提供简明有效的解决方案。 - Casper Wilkes

3
如果你正在使用MySQL 8或更高版本,则默认认证插件caching_sha2_password,因此如果存在与PHP不兼容的情况需要降级到mysql_native_password,可以在my.cfg中设置,例如:
[mysqld]
default-authentication-plugin=mysql_native_password

然后重新启动MySQL服务。

参考:升级到MySQL 8.0:默认身份验证插件注意事项本地可插拔认证

如果仍无法工作,请按照已接受的答案建议更改root密码,例如:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password by 'root';
FLUSH PRIVILEGES;

相关:


2

正如用户Evernoob所说:

“回退到PHP 5.2.*,即低于5.3.0的任何版本都可以完全解决问题。只要我不运行5.3.0,我就可以连接到两个数据库。对于这种奇怪现象的解释我不太确定。”

在连接共享主机(在我们的情况下是DreamHost)时,由于使用了oldpassword选项,我们无法修改用户表。这些建议的选项在其他情况下也适用,但在共享Web托管中不适用。

值得注意的是,我们正在运行WAMP。


1
经过多次搜索和尝试,我找到了一种方法,无需降级/升级MySQL,也不会影响正在运行的MySQL实例的其他用户。解决方案是通过以下方式重置密码:
对于MySQL版本新于5.7.5(> 5.7.5):
ALTER USER 'mysqlUsername'@'hostname' IDENTIFIED WITH mysql_native_password BY 'mysqlUsernamePassword';
对于旧版本的MySQL:(<= 5.7.5)
SET PASSWORD FOR 'mysqlUsername'@'hostname' = PASSWORD('mysqlUsernamePassword');
我在这里找到了关键点here!它使我的工作正常运行!

1
我刚刚遇到了一个问题,Wordpress的网站突然停止工作并显示了这个错误。
我在网站控制面板中找到了一个GUI,允许我更改数据库用户密码。我试图将其更改为当前密码,但不允许,因为当前密码不够强大。
我将数据库密码更改为新的、更强大的密码,并编辑了我的wp-config.php文件以包含新密码。
这起作用了!
所以我猜测,托管提供商升级了某些东西,可能是MySQL,需要更强大的密码。我解决问题的方法是使用cpanel GUI来更改数据库用户的密码,并更新wp-config.php以匹配。

1

回到 PHP 5.2.* 版本就解决了问题!谢谢!

如果你使用的是 WAMP... 左键单击 wamp > php > version> get more>

选择你想要的版本并下载。

安装/运行 exe 文件

左键单击 wamp > php > version> PHP 5.2.*

这样就解决了这个问题。我无法运行任何 SQL 命令,总是出现“命令被拒绝,用户 'XXX'@'localhost'”的错误。试图以 SU 'Root' 的身份登录是徒劳的。也许在个人服务器上可以,但在真正的主机上不可能发生。


1

我的网络主机配置了不同版本的PHP/MySQL,为了使用特定版本,我需要使用正确的.php扩展名,尤其是.php5。这可能只是一些简单的问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接