5.1.11.2 DNS 查找和主机缓存

MySQL 服务器在内存中维护主机缓存,该缓存包含有关 Client 端的信息:IP 地址,主机名和错误信息。 Performance Schema host_cachetable 公开了主机缓存的内容,以便可以使用SELECT语句对其进行检查。这可以帮助您诊断连接问题的原因。参见第 25.12.16.1 节“ host_cachetable”

Note

服务器仅将主机缓存用于 nonlocalTCP 连接。对于使用回送接口地址(例如127.0.0.1::1)构建的 TCP 连接,或者使用 Unix 套接字文件,命名管道或共享内存构建的连接,它不使用缓存。

主机缓存操作

服务器将主机缓存用于以下目的:

  • 通过缓存 IP 到主机名查找的结果,服务器避免了对每个 Client 端连接进行域名系统(DNS)查找。相反,对于给定的主机,它仅需要针对来自该主机的第一个连接执行查找。

  • 缓存包含有关在连接过程中发生的错误的信息。一些错误被认为是“阻塞”。如果在没有成功连接的情况下从给定主机连续发生了太多此类连接,则服务器将阻止来自该主机的其他连接。 max_connect_errors系统变量确定在发生阻塞之前允许的连续错误数(请参见B.4.2.5 节,“主机'host_name'被阻止”)。

对于每个新的 Client 端连接,服务器使用 Client 端 IP 地址检查 Client 端主机名是否在主机缓存中。如果是这样,则服务器会根据主机是否被阻止来拒绝或 continue 处理连接请求。如果主机不在缓存中,则服务器尝试解析主机名。首先,它将 IP 地址解析为主机名,然后将该主机名解析为 IP 地址。然后,它将结果与原始 IP 地址进行比较以确保它们相同。服务器将有关此操作结果的信息存储在主机缓存中。如果缓存已满,则丢弃最近最少使用的条目。

服务器按以下方式处理主机缓存中的条目:

  • 当第一个 TCPClient 端连接从给定 IP 地址到达服务器时,将创建一个新的缓存条目,以记录 Client 端 IP,主机名和 Client 端查找验证标志。最初,主机名设置为NULL且标志为 false。该条目还用于来自同一原始 IP 的后续 Client 端 TCP 连接。

  • 如果 Client 端 IP 条目的验证标志为 false,则服务器将尝试从 IP 到主机名到 IP DNS 解析。如果成功,则使用解析后的主机名更新主机名,并将验证标志设置为 true。如果解决不成功,则采取的措施取决于错误是永久性的还是暂时性的。对于永久性故障,主机名仍为NULL,并且验证标志设置为 true。对于短暂故障,主机名和验证标志保持不变。 (在这种情况下,下一次 Client 端从该 IP 连接时,将进行另一次 DNS 解析尝试.)

  • 如果处理来自给定 IP 地址的传入 Client 端连接时发生错误,则服务器会更新该 IP 条目中的相应错误计数器。有关记录的错误的说明,请参见第 25.12.16.1 节“ host_cachetable”

服务器使用gethostbyaddr()gethostbyname()系统调用执行主机名解析。

要取消阻止主机,请通过执行FLUSH HOSTS语句,截断 Performance Schema host_cachetable 的TRUNCATE TABLE语句或mysqladmin flush-hosts命令刷新主机缓存。 FLUSH HOSTSmysqladmin flush-hosts需要RELOAD特权。 TRUNCATE TABLE需要host_cachetable 的DROP特权。

如果自从上次尝试从被阻止的主机进行连接以来,发生了来自其他主机的活动,则即使不刷新主机缓存,被阻止的主机也可能变得不受阻止。发生这种情况的原因是,当连接从不在缓存中的 Client 端 IP 到达时,如果缓存已满,则服务器会丢弃最近最少使用的缓存条目,以便为新条目腾出空间。如果丢弃的条目用于阻止的主机,则该主机将变为未阻止。

一些连接错误与 TCP 连接无关,不是在连接过程的早期(甚至在知道 IP 地址之前)发生的,或者不是特定于任何特定 IP 地址的(例如内存不足的情况)。有关这些错误的信息,请检查Connection_errors_xxx状态变量(请参阅第 5.1.9 节“服务器状态变量”)。

主机缓存配置

默认情况下,主机缓存已启用。 host_cache_size系统变量控制其大小以及公开高速缓存内容的 Performance Schema host_cachetable 的大小。缓存大小可以在服务器启动时设置,也可以在运行时更改。例如,要将启动时的大小设置为 100,请将这些行放在服务器my.cnf文件中:

[mysqld]
host_cache_size=200

要将大小在运行时更改为 300,请执行以下操作:

SET GLOBAL host_cache_size=300;

在服务器启动或运行时将host_cache_size设置为 0 会禁用主机缓存。在禁用缓存的情况下,每次 Client 端连接时,服务器都会执行 DNS 查找。

在运行时更改缓存大小会导致隐式的FLUSH HOSTS操作,该操作将清除主机缓存,截断host_cachetable 并取消阻止所有被阻止的主机。

使用--skip-host-cache选项类似于将host_cache_size系统变量设置为 0,但是host_cache_size更灵活,因为它还可以用于在运行时调整大小,启用和禁用主机缓存,而不仅仅是在服务器启动时。使用--skip-host-cache启动服务器不会阻止更改host_cache_size的值,但是即使host_cache_size在运行时设置为大于 0,这样的更改也不会生效,并且不会重新启用缓存。

要禁用 DNS 主机名查找,请在启用skip_name_resolve系统变量的情况下启动服务器。在这种情况下,服务器仅使用 IP 地址而不使用主机名来将连接的主机与 MySQL 授权 table 中的行进行匹配。只能使用这些 table 中使用 IP 地址指定的帐户。 (如果不存在指定 Client 端 IP 地址的帐户,则 Client 端可能无法连接.)

如果您的 DNS 速度很慢且有许多主机,则可以通过启用skip_name_resolve来禁用 DNS 查找,或者通过增大host_cache_size的值来增大主机缓存来提高性能。

要完全禁止 TCP/IP 连接,请在启用skip_networking系统变量的情况下启动服务器。