Perl编辑:据我所知,这个问题的根本原因是安装了正确的模块,但是加载了错误的mysql.so
文件。
my $dsn = "DBI:mysql:"
. "database=$db;"
. "host=$dbhost;"
. "mysql_ssl=$dbssl;"
. "mysql_skip_secure_auth=1;";
我最近试图升级我们的DBD::mysql版本,但一直遇到DBI connect('database=mydb;host=myhost','myuser',...) failed: Connection using old (pre-4.1.1)
错误。
经过几个小时的调试,并确定不更新mysql表的密码散列方法的正确选项在整个系统中是不可能的,我发现使用DBD::Mysql 4.027可以将"mysql_skip_secure_auth“声明为dsn的一部分。
然而,这似乎不起作用。
如果我运行mysql -h $myhost -u $myuser -p --skip-secure-auth
,我可以毫无意外地进行连接,但是尝试使用DBI/DBD::mysql进行连接时,我总是会遇到上面的错误,就好像该指令被忽略一样。
我也尝试过在设置了相同选项的情况下使用mysql_read_default_file
,以及在DSN中简单地使用mysql_skip_secure_auth
。这些东西的任何一个组合都不起作用。
我是不是遗漏了什么?
编辑:
跟踪输出(编辑以删除敏感信息):
imp_dbh->mysql_dr_connect: host = |{host}|, port = 0, uid = {user}, pwd = {pwd}
imp_dbh->mysql_dr_connect: Skipping secure auth
imp_dbh->bind_type_guessing: 0
imp_dbh->use_server_side_prepare: 0
imp_dbh->mysql_dr_connect: client_flags = 2
imp_dbh->mysql_dr_connect: <- --> do_error
Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled) error 2049 recorded: Connection using old (pre-4.1.1) authentication protocol refused (client option 'secure_auth' enabled)
my $versions = DBI->installed_versions;
foreach (keys %$versions) {
print "\n$_: " . %$versions->{$_};
}
DBD::SQLite: 1.26
DBD::ExampleP: 12.014310
DBD::Sponge: 12.010002
DBD::Gofer: 0.015057
DBD::DBM: 0.06
DBD::mysql: 4.027
DBI: 1.618
发布于 2014-12-12 01:38:31
您说得对,这方面的事情有点棘手,但挑战似乎来自C mysql库,而不是DBD::mysql。
首先,将参数作为驱动程序选项传递,而不是作为主要DSN字符串的一部分传递:my @dsn = ("DBI:mysql:database=$db;host=$dbhost;mysql_ssl=$dbssl", $user, $pissword, { mysql_skip_secure_auth => 1 });
只要你不使用.cnf文件,它就应该可以工作。
要通过文件进行身份验证,有一些限制。my @dsn = ("DBI:mysql:"database=$db;host=$dbhost;mysql_ssl=$dbssl;" . "mysql_read_default_file=$absolute_path.cnf", undef, undef, { mysql_skip_secure_auth => 1 });
确保您的文件不包含secure_auth
条目,否则C库会错误地将其视为已启用,即使该条目已禁用。
任何与此类似、带有禁用(错误)值secure_auth = FALSE
的行都必须更改为skip_secure_auth
(并确认mysql和mysqldump等标准工具可以像以前一样工作)。
C库有一个错误,它将secure_auth = FALSE
视为secure_auth = TRUE
,在我看来,它还有第二个错误,它忽略了skip_secure_auth
,而不是尊重它。
根据http://dev.mysql.com/doc/refman/5.6/en/mysql-options.html的文档,通常不支持secure_auth选项,但奇怪的是,一个表单被(错误地)实现,而另一个表单被忽略。
如果你的代码知道它连接的是v4.0服务器,那么上面的方法是有效的,但是我不想把代码和特定于服务器的逻辑搞乱。我仍然希望有一种方法可以修补C库,这样就可以像标准工具一样,完全通过.cnf文件完成这项工作。
作为补充,如果你因为某些原因不能使用skip_secure_auth
,你需要省略[client]
部分中的所有secure_auth条目,而是将secure_auth = FALSE
添加到你的工具所需的每个部分,例如[mysql]
、[mysqldump]
等,这显然是可怕的。
https://stackoverflow.com/questions/22702546
复制相似问题