Perl 如何使用 DBI 模块更改帐户主机?

Posted

技术标签:

【中文标题】Perl 如何使用 DBI 模块更改帐户主机?【英文标题】:Perl How to change account host using DBI module? 【发布时间】:2021-12-18 08:28:24 【问题描述】:

我的公司在 IP 的服务器中有一个 Perl 应用程序:10.10.3.39

并且由于实施了新规则,我必须将数据库迁移到具有 IP 的服务器中的 mysql 数据库:10.10.1.18

我公司的数据库管理员创建了一个帐户并授予用户名的应用程序访问权限:'user'@'10.10.3.39'。所以该账号只能在IP为10.10.3.39的服务器上使用

我使用命令mysql -h 10.10.1.18 -u user -p在服务器中尝试了连接

[hanief@dev39 project]$ mysql -h 10.10.1.18 -u user -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 19484169
Server version: 10.0.15-MariaDB mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

我在 Perl 中有一个数据库连接脚本 test_db.pm,如下所示:

use DBI;

$user = "user";
$pw = 'password';
$dbh = DBI->connect("DBI:mysql:database=mysql;host=10.10.1.18;mysql_enable_utf8=1",$user, $pw, %attr) or die "Cannot connect to MySQL server\n";

然后,我尝试使用命令perl test_db.pm 运行它,我得到了这个错误

[hanief@dev39 project]$ perl test_db.pm
DBI connect('database=mysql;host=10.10.1.18;port=3306;mysql_enable_utf8=1','user',...)
failed: Access denied for user 'user'@'%' to database 'mysql' at test_db.pm line 6.
Cannot connect to MySQL server

不知道为什么账号名后面突然多了@'%'

我已尝试将变量 $user 更改为:

$user = "user\@10.10.3.39";
failed: Access denied for user 'user@10.10.3.39'@'10.10.3.39' (using password: YES) at test_db.pm line 6.
$user = "user\@'10.10.3.39'";
failed: Access denied for user 'user@'10.10.3.39''@'10.10.3.39' (using password: YES) at test_db.pm line 6.
$user = "'user'\@'10.10.3.39'";
failed: Access denied for user 'user'@'10.10.3.39'@'10.10.3.39' (using password: YES) at test_db.pm line 6.

但还是不行。服务器仍然无法连接到数据库服务器。

我不知道为什么用户帐户后面有一个额外的@'10.10.3.39'。 而且不知道为什么之前%,突然换成了10.10.3.39

我的情况有什么解决方案吗?

【问题讨论】:

您是否尝试过设置调试级别,以便您可以看到 DBI 和 DBD::MySQL 的一些内容(我不确定模块名称中 MySQL 的大小写)表明它们的更多内容是做?您也许可以看到更改(对我来说很神秘)来自何处。你使用的 Perl 版本和以前一样吗?同一个版本的DBI? DBD?你还能连接到旧服务器吗? (我想它可能不再运行了,但如果他们在新系统稳定之前将它留在身边会更好。) DBI_TRACE 环境变量设置为非零值可能会有所帮助。使用DBI_TRACE=9 可以提供大约最多的可用信息。 @JonathanLeffler 是的,我仍然使用相同版本的 perl、DBI 和 DBD。当然,我仍然可以连接到与应用程序在同一台服务器上的旧 mysql 服务器。但是由于新规则,我必须尽快迁移它。现在它仍然有效(因为我们仍在使用旧数据库) 将尝试您对 DBI_TRACE 的建议。 如果您仍然可以访问旧服务器,则运行与 DBI_TRACE 设置的连接并捕获输出(它被写入标准错误,因此您可能需要 perl yourscript.pl >output.1 2>&1(假设Bourne/POSIX 风格的 shell)。然后使用 DBI_TRACE 设置运行与新服务器的连接并捕获该输出。现在比较两组输出,看看有什么不同。应该有不同的地方。但我不知道是什么.(免责声明:我不是 MySQL 用户——但我确实编写了大部分 DBD::Informix 驱动程序,并且我仍然维护它,尽管不是很积极)。 【参考方案1】:

我不完全确定这里发生了什么,但我想我可以阐明一点。

MySQL(也就是 MariaDB)有一个登录系统,它不仅仅依赖于用户名和密码。它还考虑了连接来自的主机。如果您查看mysql.user 表,您会看到前三列是HostUserPassword

Host 专栏很有趣。它可以包含 IP 地址或主机名,但也可以包含符号 '%',表示“任何主机”。

所以当 DBA 告诉你他们有:

创建一个帐户并使用用户名授予应用程序的访问权限:'user'@'10.10.3.39'

我打赌他们的意思是他们已经在mysql.user 表中插入了值user10.10.3.39

这意味着您的 $user 变量需要设置为 user,而不是 user@10.10.3.39 - 因为 MySQL 会从您的传入连接中计算出 IP 地址。

所以当你看到这样的错误时:

失败:用户'user@10.10.3.39'@'10.10.3.39'的访问被拒绝

第一对引号内的位 ("user@10.10.3.39") 是您尝试使用的用户名,第二对引号内的位 ("10.10.3.39") 是 IP 地址MySQL 认为您正在连接。显然,这是行不通的,因为 mysql.users 表中不存在该用户名。

所以,我们只看你的第一个例子:

$dbh = DBI->connect("DBI:mysql:database=mysql;host=10.10.1.18;mysql_enable_utf8=1",$user, $pw, %attr)
  or die "Cannot connect to MySQL server\n";

这给出了这个错误:

失败:用户 'user'@'%' 的访问被拒绝

现在,这个错误使用“%”作为您的主机名这一事实似乎意味着 MariaDB 服务器没有将您来自的 IP 地址识别为允许您使用的特定 IP 地址之一用户。

因此,在这种情况下,我会仔细检查两件事:

您确定要从 10.10.3.39 连接吗?这包括检查您和数据库服务器之间是否有任何代理可能会更改您的 IP 地址。 mysql.user表中的IP地址真的是10.10.3.39吗?或者该值是否包含拼写错误?

我知道这不是一篇“这是解决您的问题的方法”的帖子,但希望它能够更多地解释正在发生的事情,并为您提供一些调查途径。

【讨论】:

感谢@Dave Cross,我将首先尝试根据您的指示调查问题。并将与 DBA 沟通以检查他的实际设置。

以上是关于Perl 如何使用 DBI 模块更改帐户主机?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Perl 的 DBI 处理 unicode?

如何从 Perl 连接到 MySQL?

Perl DBI:如何使用绑定值查看失败的查询?

如何检查 Perl 中的 DBI 查询是不是返回了多个记录?

如何正确表示 Perl 的 DBI 中的空格

如何查询某些行的sqlite,即将它分成页面(perl DBI)