我的生产 mysql 服务器遇到了一个不寻常的问题。目前,我只有两台生产服务器,因此我将所有服务器主机名条目都保存在/etc/hosts
每台服务器上的文件中。几天前,我设置了一个 DNS 区域,希望可以删除文件中的手动条目 /etc/hosts
。
由于我只有两台生产服务器,因此我设置了 DNS,以便每台服务器都有一个真实的主机名,也可以使用别名,这样我就可以通过简单地更新 DNS 记录来控制连接。例如,server1 托管 httpd 和 mysql,因此在我的 DNS 区域中,server1 的 A 记录为 4.4.4.2,store-ro 的别名为 server1。显然 4.4.4.2 不是我的真实 IP,仅供参考。
经过一些配置后,我能够通过命令行连接到本地 mysql 实例,但我的应用程序不断抛出Unknown MySQL server host 'store-ro'
错误。解决此问题的唯一方法是将以下内容添加回 hosts 文件:
127.0.0.1 store-ro
# or
4.4.4.2 store-ro
(不确定是否重要,但我的应用程序正在使用 Zend_Db 连接到数据库。)
因此,如果我输入环回 IP 或实际 IP,应用程序就可以连接到服务器,但如果从 hosts 文件中删除,它将无法工作,所以我认为这可能是 DNS 问题,但看起来服务器可以正常解析主机名:
$ -> nslookup store-ro
Server: 72.14.179.5
Address: 72.14.179.5#53
Non-authoritative answer:
store-ro.example.com canonical name = server1.example.com.
Name: server1.example.com
Address: 4.2.2.2
我确实启用了 SELinux,并且粗略浏览一下相关的 httpd 连接设置似乎是正确的:
$ -> getsebool -a | ack httpd
httpd_can_network_connect_db --> on
httpd_can_network_connect --> on
另外,没有任何条目出现在/var/log/audit/audit.log
。
我的主机名设置正确:
$ -> hostname
server1
MySQL 用户权限:
mysql> select host, user from user;
+-----------+-------------+
| host | user |
+-----------+-------------+
| % | ro_user_1 |
| % | ro_user_2 |
和/etc/resolve.conf
:
search example.com
nameserver 72.14.179.5
nameserver 72.14.188.5
和/etc/hosts
:
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
4.4.4.2 server1 server1.example.com # This shouldn't be necessary with DNS setup?
我唯一能想到的可能是 cname 的别名导致了这个问题,但我对此表示怀疑。任何帮助都值得感激。
- 更新 -
忘记添加实际错误:SQLSTATE[HY000] [2005] Unknown MySQL server host 'store-ro'
根据请求,以下是来自 mysql 表的完整行:
mysql> select * from user where user like '%core%'\G
*************************** 1. row ***************************
Host: %
User: ro_ml_core
Password: *2B5FEA45B69826783FD6F8601A9AFB1CFE916D52
Select_priv: N
Insert_priv: N
Update_priv: N
Delete_priv: N
Create_priv: N
Drop_priv: N
Reload_priv: N
Shutdown_priv: N
Process_priv: N
File_priv: N
Grant_priv: N
References_priv: N
Index_priv: N
Alter_priv: N
Show_db_priv: N
Super_priv: N
Create_tmp_table_priv: N
Lock_tables_priv: N
Execute_priv: N
Repl_slave_priv: N
Repl_client_priv: N
Create_view_priv: N
Show_view_priv: N
Create_routine_priv: N
Alter_routine_priv: N
Create_user_priv: N
Event_priv: N
Trigger_priv: N
Create_tablespace_priv: N
ssl_type:
ssl_cipher:
x509_issuer:
x509_subject:
max_questions: 0
max_updates: 0
max_connections: 0
max_user_connections: 0
plugin:
authentication_string: NULL
答案1
mysql> select User,Host from user where user like '%core%';
+------------+-----------+
| User | Host |
+------------+-----------+
| ro_ml_core | % |
| ro_ml_core | localhost |
+------------+-----------+
2 rows in set (0.00 sec)
必须同时拥有 (
%
和localhost
) 帐户才能以 的身份ro_ml_core
从任何地方进行连接ro_ml_core
。如果没有 localhost 帐户,则从 localhost 连接mysql_install_db
时,由 创建的 localhost 匿名用户帐户将优先。因此,将被视为匿名用户。原因是匿名用户帐户比帐户具有更具体的 Host 列值,因此在用户表排序顺序中排在更前面。ro_ml_core
ro_ml_core
'ro_ml_core'@'%'
关于排序顺序:
服务器使用排序规则,将具有最具体 Host 值的行排在最前面。文字主机名和 IP 地址是最具体的。(文字 IP 地址的具体性不受其是否具有网络掩码的影响,因此
192.168.1.13
和192.168.1.0/255.255.255.0
被视为同样具体。)模式'%'
表示"any host"
和最不具体。空字符串''
也表示"any host"
但排在后面'%'
。具有相同 Host 值的行首先按最具体的 User 值排序(空白 User 值表示"any user"
和最不具体)。
答案2
发生这种情况是因为您的 resolv.conf 中没有
search foo.com
当 mysql 查找 时store-ro
,foo.com
不会将 附加到其后。另一种方法是使用 fqdn。使用store-ro.foo.com
进行连接。
手册页片段。resolv.conf(5)
搜索 用于主机名查找的搜索列表。搜索列表通常根据本地域名确定;默认情况下,它仅包含本地域名。这可以通过在搜索关键字后列出所需的域搜索路径来更改,名称之间用空格或制表符分隔。解析器查询中包含的点数少于 ndots 个(默认值为 1),将依次尝试使用搜索路径的每个组件,直到找到匹配项。对于具有多个子域的环境,请阅读下面的选项 ndots:n,以避免中间人攻击和根 DNS 服务器不必要的流量。请注意,如果列出的域的服务器不是本地的,此过程可能会很慢,并且会产生大量网络流量,并且如果其中一个域没有可用的服务器,查询将超时。搜索列表目前限制为六个域,总共 256 个字符。
答案3
所以我终于能够通过应用程序连接到 mysql 服务器了。在实施了 Suku 的建议后,我重新启动了 mysql 服务,但仍然不起作用。所以我想我会重新启动 httpd 服务,然后应用程序就可以再次连接了。似乎如果我删除 /etc/hosts 中的条目而不重新启动 httpd 服务,它就会出现连接问题,但如果我删除该条目并重新启动它就可以正常工作。即使将条目重新添加到 /etc/hosts 也不起作用,直到我重新启动 httpd。