8

我正在尝试从位于 slicehost (两个不同的托管公司)服务器中的 php 脚本连接到 dreamhost 的 mysql 服务器。我需要这样做,以便可以将 slicehost 的新数据传输到 dreamhost。使用转储不是一个选项,因为表结构不同,我只需要传输一小部分数据(每天 100-200 条记录)问题是我在 slicehost 和 dreamhost 使用新的 MySQL 密码散列方法使用旧的,所以我得到

$link = mysql_connect($mysqlHost, $mysqlUser, $mysqlPass, FALSE); 

Warning: mysql_connect() [function.mysql-connect]: OK packet 6 bytes shorter than expected
Warning: mysql_connect() [function.mysql-connect]: mysqlnd cannot connect to MySQL 4.1+ using old authentication
Warning: mysql_query() [function.mysql-query]: Access denied for user 'nodari'@'localhost' (using password: NO) 

事实:

  • 我需要继续在 slicehost 上使用新方法,我不能使用旧的 php 版本/库
  • 数据库太大,每天都用dump转储
  • 即使我这样做了,表格也有不同的结构
  • 我每天只需要复制其中的一小部分(仅当天的更改,100-200 条记录)
  • 由于表格如此不同,我需要使用 php 作为桥梁来规范化数据
  • 已经google了
  • 已经和两位支持人员谈过了

对我来说更明显的选择是在 Dreamhost 开始使用新的 MySQL 密码哈希方法,但他们不会更改它,而且我不是 root,所以我自己不能这样做。

有什么疯狂的想法吗?

VolkerK 建议:

mysql> SET SESSION old_passwords=0;
Query OK, 0 rows affected (0.01 sec)

mysql> SELECT @@global.old_passwords,@@session.old_passwords, Length(PASSWORD('abc'));
+------------------------+-------------------------+-------------------------+
| @@global.old_passwords | @@session.old_passwords | Length(PASSWORD('abc')) |
+------------------------+-------------------------+-------------------------+
|                      1 |                       0 |                      41 |
+------------------------+-------------------------+-------------------------+
1 row in set (0.00 sec)

现在显而易见的是运行 mysql> SET GLOBAL old_passwords=0; 但我需要超级特权才能做到这一点,他们不会给我

如果我运行查询

SET PASSWORD FOR 'nodari'@'HOSTNAME' = PASSWORD('new password');

我得到错误

ERROR 1044 (42000): Access denied for user 'nodari'@'67.205.0.0/255.255.192.0' to database 'mysql'

我不是根...

Dreamhost 支持的那个人坚持说问题出在我头上。但他说他会运行我告诉他的任何查询,因为它是私人服务器。所以,我需要确切地告诉这个人要运行什么。所以,告诉他跑

SET SESSION old_passwords=0;
SET GLOBAL old_passwords=0;
SET PASSWORD FOR 'nodari'@'HOSTNAME' = PASSWORD('new password');
grant all privileges on *.* to nodari@HOSTNAME identified by 'new password';

会是一个好的开始吗?

4

6 回答 6

8

在某些情况下,您仍然可以设置和使用“新哈希算法密码”。
MySQL 4.1+ 服务器能够处理这两种登录算法。使用哪一个与 old-passwords 变量无关。如果 MySQL 找到以 * 开头的 41 个字符长的散列,它将使用新系统。并且 PASSWORD() 函数也能够使用这两种算法。如果字段 mysql.user.Password 足够宽以存储 41 个字符并且 old-passwords 变量为 0,它将创建一个“新”密码。old_passwords的文档说Variable Scope Both,因此您可以为您的会话更改它。
连接到 MySQL 服务器(尽管全局 old_passwords=1,客户端仍能这样做),例如HeidiSQL并尝试以下操作:

SET SESSION old_passwords=0;
SELECT @@global.old_passwords,@@session.old_passwords, Length(PASSWORD('abc'));

如果它打印1, 0, 41(意味着全局 old_passwords 已打开,但对于会话它已关闭并且 PASSWORD() 返回“新”密码),您应该能够在同一会话中使用新算法为您的帐户 设置新密码。

但如果dreamhost 真的想禁用新密码算法,mysql.user.Password 字段的长度将少于41 个字符,并且无能为力(除了唠叨他们)。

于 2009-12-12T10:39:18.220 回答
4

我刚刚遇到了这个问题,并且能够解决它。

首先,使用不介意 old_passwords 的旧客户端连接到 MySQL 数据库。使用您的脚本将使用的用户进行连接。

运行这些查询:

SET SESSION old_passwords=FALSE;
SET PASSWORD = PASSWORD('[your password]');

在您的 PHP 脚本中,更改您的 mysql_connect 函数以包含客户端标志 1:

define('CLIENT_LONG_PASSWORD', 1);
mysql_connect('[your server]', '[your username]', '[your password]', false, CLIENT_LONG_PASSWORD);

这使我能够成功连接。

于 2010-05-25T03:07:17.557 回答
2

我会通过在 Slicehost 转储数据来解决这个问题,使用SELECT ... INTO OUTFILE.

这使您可以设计查询以确保输出的格式与目标站点的表结构相匹配。

然后将转储文件传输到 Dreamhost 并使用LOAD DATA INFILE.

顺便说一句,Dreamhost 真的还在使用 MySQL 4.0 吗?它们已经非常过时了——甚至 MySQL 4.1 的扩展支持也将于本月到期(2009 年 12 月)。

于 2009-12-12T07:58:22.660 回答
2

是的,这看起来像一个顽固的人。如果没有主机的合作或更改密码格式或客户端库的能力,您将没有很多选择。

老实说,我的第一选择是放弃 Dreamhost。这可能需要做很多工作,但如果他们将被困在使用旧的不兼容的东西,那将继续存在问题。

如果这不是一个选项,那么联合自动化流程呢?您可以将 Slicehost 端的数据导出为 CSV 文件,并将其转换为 Dreamhost 所需的任何格式,然后将其上传到 Dreamhost 服务器。您可以让 Dreamhost 服务器上的 cron 脚本定期检查上传的文件并进行处理(确保在成功处理后移动或删除它)。

于 2009-12-12T07:17:56.310 回答
1

我认为你应该从 slicehost 制作 WebServices/RPC 并在其上编写相应的服务来处理它。

于 2009-12-12T08:03:16.363 回答
0

我遇到过同样的问题。为了解决它,我做了以下事情:

SET PASSWORD = PASSWORD('[your password]');
于 2016-02-04T19:56:20.513 回答