美文网首页
MySQL-DNS解析和主机缓存

MySQL-DNS解析和主机缓存

作者: 月饮沙 | 来源:发表于2020-04-29 16:24 被阅读0次

本文问题

  1. 主机缓存的内容和作用是什么?
  2. 主机缓存是如何进行更新的?
  3. 如何设置主机缓存是否启用及主机缓存的大小?
  4. 主机缓存中的错误消息有什么作用?
  5. 如何清空主机缓存?
  6. 如何查看已缓存的主机信息?

主机缓存

MySQL服务器在内存中维护关于客户端的主机缓存,内容包括:IP地址、主机名和错误信息。

主机缓存作用

  • 通过缓存IP到主机名的对应关系,服务器可以避免对每个客户端连接进行DNS解析。对于给定的主机,只需要对第一个连接进行解析即可。
  • 缓存中包含了在连接过程中发生的错误信息。一些错误被认为是‘阻塞’。如果一个主机连续发生了太多‘阻塞',数据库会拒绝这个主机的连接

对于每个新的客户端连接,服务器使用IP地址来检查客户端的主机名是否在主机缓存中。如果在主机缓存中,数据库根据缓存中的内容来决定是否接受连接。如果不在主机缓存中,数据库会尝试解析主机名:首先,将IP地址解析为主机名并将主机名反向解析为IP地址。然后,服务器将解析后的IP地址和原始IP地址比较,确定两个IP地址相同。数据库将结果记录在主机缓存中。如果缓存已满,则丢弃最近最少使用的记录。

主机缓存的更新

  • 当一个客户端从指定的IP地址第一次连接到服务器时,创建一个新的缓存记录,记录包括客户端IP地址,主机名和客户端解析验证标记。最初,主机名设置为NULL,标识设置为false。这个记录用于同一IP地址之后的其他客户端连接
  • 如果条目的验证标识为false,服务器尝试进行IP到主机名 主机名到IP的DNS解析。如果解析程工。主机名更新为解析到的主机名并且验证标记更新为true。如果解析失败,则采取的措施取决于错误是暂时错误还是永久的错误。对于永久的错误,主机名保持NULL不变,验证标识更新为true。对于暂时的错误,主机名和验证标识都保持不变,当下一次相同IP的客户端连接时,还会再次尝试DNS解析。
  • 如果在处理客户端连接的时候发生了错误,服务器会更新对应IP地址的相关错误计数器。

数据库使用gethostbyaddr()gethostbyname()系统调用进行主机名解析

清空Host缓存

如果一个主机连续发生了太多‘阻塞’的错误,数据库会拒绝这个主机继续连接到数据库(锁定主机)。再进行连接时,会提示以下错误:

Host 'host_name' is blocked because of many connection errors.
Unblock with 'mysqladmin flush-hosts'

max_connect_errors决定了最大错误次数。默认值是100。

手动解锁主机的唯一方法是刷新主机缓存

mysql> FLUSH HOSTS
mysql>TRUNCATE TABLE performance_schema.host_cache
shell> mysqladmin flush-hosts

由于主机缓存具有最大大小,当其他主机连接数据库后,如果缓存超过了最大缓存大小,并且被锁定的主机恰好是最近最少使用的主机,也有可能会将这个主机从主机缓存中清楚,主机会自动解锁。

查看Host缓存信息

可以通过Performance_Schema.host_cache表来查看主机缓存信息

host_cache表结构

mysql> desc performance_schema.host_cache;
+--------------------------------------------+------------------+------+-----+---------------------+-------+
| Field                                      | Type             | Null | Key | Default             | Extra |
+--------------------------------------------+------------------+------+-----+---------------------+-------+
| IP                                         | varchar(64)      | NO   |     | NULL                |       |
| HOST                                       | varchar(255)     | YES  |     | NULL                |       |
| HOST_VALIDATED                             | enum('YES','NO') | NO   |     | NULL                |       |
| SUM_CONNECT_ERRORS                         | bigint(20)       | NO   |     | NULL                |       |
| COUNT_HOST_BLOCKED_ERRORS                  | bigint(20)       | NO   |     | NULL                |       |
| COUNT_NAMEINFO_TRANSIENT_ERRORS            | bigint(20)       | NO   |     | NULL                |       |
| COUNT_NAMEINFO_PERMANENT_ERRORS            | bigint(20)       | NO   |     | NULL                |       |
| COUNT_FORMAT_ERRORS                        | bigint(20)       | NO   |     | NULL                |       |
| COUNT_ADDRINFO_TRANSIENT_ERRORS            | bigint(20)       | NO   |     | NULL                |       |
| COUNT_ADDRINFO_PERMANENT_ERRORS            | bigint(20)       | NO   |     | NULL                |       |
| COUNT_FCRDNS_ERRORS                        | bigint(20)       | NO   |     | NULL                |       |
| COUNT_HOST_ACL_ERRORS                      | bigint(20)       | NO   |     | NULL                |       |
| COUNT_NO_AUTH_PLUGIN_ERRORS                | bigint(20)       | NO   |     | NULL                |       |
| COUNT_AUTH_PLUGIN_ERRORS                   | bigint(20)       | NO   |     | NULL                |       |
| COUNT_HANDSHAKE_ERRORS                     | bigint(20)       | NO   |     | NULL                |       |
| COUNT_PROXY_USER_ERRORS                    | bigint(20)       | NO   |     | NULL                |       |
| COUNT_PROXY_USER_ACL_ERRORS                | bigint(20)       | NO   |     | NULL                |       |
| COUNT_AUTHENTICATION_ERRORS                | bigint(20)       | NO   |     | NULL                |       |
| COUNT_SSL_ERRORS                           | bigint(20)       | NO   |     | NULL                |       |
| COUNT_MAX_USER_CONNECTIONS_ERRORS          | bigint(20)       | NO   |     | NULL                |       |
| COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS | bigint(20)       | NO   |     | NULL                |       |
| COUNT_DEFAULT_DATABASE_ERRORS              | bigint(20)       | NO   |     | NULL                |       |
| COUNT_INIT_CONNECT_ERRORS                  | bigint(20)       | NO   |     | NULL                |       |
| COUNT_LOCAL_ERRORS                         | bigint(20)       | NO   |     | NULL                |       |
| COUNT_UNKNOWN_ERRORS                       | bigint(20)       | NO   |     | NULL                |       |
| FIRST_SEEN                                 | timestamp        | NO   |     | 0000-00-00 00:00:00 |       |
| LAST_SEEN                                  | timestamp        | NO   |     | 0000-00-00 00:00:00 |       |
| FIRST_ERROR_SEEN                           | timestamp        | YES  |     | 0000-00-00 00:00:00 |       |
| LAST_ERROR_SEEN                            | timestamp        | YES  |     | 0000-00-00 00:00:00 |       |
+--------------------------------------------+------------------+------+-----+---------------------+-------+

配置Host缓存

默认情况下,启用主机缓存。

设置缓存大小

缓存大小可以动态修改,修改缓存大小会清除缓存。

[mysqld]
host_cache_size=200

SET GLOBAL host_cache_size=300;

禁用主机缓存

在禁用主机缓存的情况下,每次客户端连接的时候都要进行DNS解析
--skip-host-cache 只能在数据库启动时设置,优先级更高。
host_cache_size=0 可以在数据库运行时修改。

禁用DNS解析

启用skip_name_resolve可以禁止DNS解析,在这种情况下,数据库只检查IP地址是否与权限表中的记录匹配。

问题答案

  1. 主机缓存的内容和作用是什么?
  • 内容
    主机缓存中包括IP地址、主机名和一些错误信息
  • 作用:
    1. 通过缓存主机,同一主机可以只在第一次连接时进行DNS解析,避免对每个连接都进行DNS解析。
    2. 主机缓存中会记录连接错误,同一主机连续多次出现阻塞性错误(超过max_connect_errors)可以拒绝该主机继续连接
  1. 主机缓存是如何进行更新的?
  • 添加
    • 当一个主机第一次连接时,创建一个新的缓存条目来记录主机信息(IP地址,主机名=NULL,验证标识=false)。
    • 如果验证标识=false,尝试用IP地址解析主机名。
      • 解析成功
        主机名=hostname,验证标识=true
      • 解析失败
        • 暂时性错误
          主机名=NULL,验证标识=false。相同主机下次连接时还会进行DNS解析
        • 永久性错误
          主机名=NULL,验证标识=true
  • 更新
    在处理客户端连接时发生错误,会更新主机缓存中对应IP地址相关的错误计数器。
  • 删除
    当缓存已满时,按照最近最少使用(LRU)算法驱逐缓存中的记录
  1. 如何设置主机缓存是否启用及主机缓存的大小?
    主机缓存默认启用,可以通过--skip-host-cache禁用。
    可以通过host_cache_size来修改主机缓存的大小,大小为0时禁用主机缓存。每次修改主机缓存的大小都会清空主机缓存。
    在使用--skip-host-cache禁用主机缓存后,修改host_cache_size的大小不会启用主机缓存。
  2. 主机缓存中的错误消息有什么作用?
    一些错误是阻塞性的,当一个主机连续发生的阻塞性错误数量超过max_connect_errors的值时,数据库会拒绝这个主机继续连接。可以通过清空主机缓存来允许主机继续连接
  3. 如何清空主机缓存?
    shell> mysqladmin flush-hosts
    flush hosts
    truncate table performance_schema.host_cache
    set global host_cache_size=n
  4. 如何查看已缓存的主机信息?
    查询performance_schema.host_cache

相关文章

网友评论

      本文标题:MySQL-DNS解析和主机缓存

      本文链接:https://www.haomeiwen.com/subject/srraihtx.html