连接管理

连接管理

客户端连接线程

连接管理器为每个客户端连接分配一个线程,该线程用于处理身份验证和请求。

连接结束时,如果高速缓存未满,这个线程不马上回收,而是被缓存。

每次有连接请求的时候,会先查看线程缓存中是否有可用的线程,如果没有,才会创建新线程。

这种连接线程管理方式的缺点是,每个连接都要分配一个线程,资源开销大,性能消耗大。

企业版中提供了一个线程池插件,用来减少开销并提高性能。

系统变量

  • thread_cache_size
    • 缓冲区保留的可重用线程数。0表示禁用缓存
  • thread_stack
    • 线程堆栈大小。
    • 当线程堆栈太小时,这将限制服务器可以处理的 SQL 语句的复杂性,存储过程的递归深度以及其他消耗内存的操作

状态变量

  • Threads_cached
    • 缓存中的线程数
  • Threads_created
    • 由于无法从缓存中获取线程而创建的线程数

连接数

系统变量

  • max_connections
    • 最大连接数,默认是151
    • 组复制的内部会话与客户端连接分开处理,因此它们不计入 max_connections 限制,并且如果服务器达到此限制,也不会被拒绝
  • open_files_limit
    • 操作系统的打开文件数量限制

状态变量

  • Connection_errors_max_connections
    • 如果达到最大连接数,此状态变量将增加
    • 这个状态变量的值还与其他变量有关,后续遇到再补充。

查看连接线程

mysql> show processlist;
+----+-----------------+-----------------+--------------------+---------+--------+------------------------+------------------+
| Id | User            | Host            | db                 | Command | Time   | State                  | Info             |
+----+-----------------+-----------------+--------------------+---------+--------+------------------------+------------------+
|  5 | event_scheduler | localhost       | NULL               | Daemon  | 173642 | Waiting on empty queue | NULL             |
| 60 | root            | localhost       | NULL               | Query   |      0 | init                   | show processlist |
| 61 | root            | 172.16.0.1:3189 | performance_schema | Sleep   |   3070 |                        | NULL             |
| 62 | root            | 172.16.0.1:3190 | performance_schema | Sleep   |   3055 |                        | NULL             |
| 63 | root            | 172.16.0.1:3486 | performance_schema | Sleep   |   3055 |                        | NULL             |
+----+-----------------+-----------------+--------------------+---------+--------+------------------------+------------------+

Note: MySQL 实际允许的连接数是 max_connections + 1 ,额外的那个连接是为管理员 (需要 CONNECTION_ADMIN 权限) 准备的。

受影响因素

如果 RAM 充足,且每个连接的负载低,响应时间不高,Linux 至少支持500-1000个并发连接,最高10000个。

  • 给定平台上线程库的质量
  • 每个连接使用的 RAM 的大小
  • 每个连接的负载
  • 所需的响应时间
  • 可用文件描述符的数量

连接管理

8.0 版本,服务器可以使用 TCP/IP 协议指定管理连接的接口。

管理连接的数量没有限制,但是需要 SERVICE_CONNECTION_ADMIN 权限。

管理连接接口有自己的配置选项,与主连接接口相对应。默认情况下,已启用加密连接,不需要特别指定。

系统变量

[mysqld]
admin_address=127.0.0.1
admin_port=33064
  • admin_addresss
    • 指定 IP 地址
  • admin_port
    • 指定端口,默认是 33062
  • create_admin_listener_thread
    • 启动时可以选择管理接口是否具有自己的单独线程。默认为 OFF。
  • 连接加密
    • admin_tls_xxx、admin_ssl_xxx
      • 与 tls_xxx、ssl_xxx 类似
    • admin_tls_version
      • TLS 规则,指定加密列表。空值,表示不使用加密连接
        [mysqld]
        admin_tls_version=''
        
      • 加密连接可以通过 –admin-ssl 选项指定

配置过程

  • 编辑配置文件 /etc/my.cnf

    [mysqld]
    # 连接管理
    thread-cache-size = 9
    thread-stack      = 300K  # default 287620
    max_connections   = 151
    admin_address     = 127.0.0.1
    admin_port        = 33062
    #create_admin_listener_thread = on
    
    # 连接加密
    admin_ssl_ca=ca.pem
    admin_ssl_cert =server-cert.pem
    admin_ssl_key  =server-key.pem
    admin_tls_version  =TLSv1,TLSv1.1,TLSv1.2,TLSv1.3
    
  • 验证连接
    mysql -uroot -p -h 127.0.0.1 -P33062
    

    Note: 虽然通过33062端口连接到服务器,但是服务器端的正常服务端口仍然是3306,33062只是用于管理连接的端口。

    mysql> select @@port;
    +--------+
    | @@port |
    +--------+
    |   3306 |
    +--------+
    

DNS 查找和主机缓存

MySQL 服务器在内存中维护了一个主机缓存信息,包含客户端信息,如 IP 地址、主机名、错误信息,会被缓存起来。

主机缓存只用于非本地登录的 TCP 连接。

如果缓存已满,则服务器将丢弃最近最少使用的缓存条目,以便为新条目腾出空间。如果内存不足,可能导致连接错误。

查看主机缓存

  • performance_schema.host_cache
    mysql> select * from performance_schema.host_cache\G
    *************************** 1. row ***************************
                                            IP: 172.16.0.30
                                          HOST: NULL
                                HOST_VALIDATED: YES
                            SUM_CONNECT_ERRORS: 0
                     COUNT_HOST_BLOCKED_ERRORS: 0
               COUNT_NAMEINFO_TRANSIENT_ERRORS: 0
               COUNT_NAMEINFO_PERMANENT_ERRORS: 1
                           COUNT_FORMAT_ERRORS: 0
               COUNT_ADDRINFO_TRANSIENT_ERRORS: 0
               COUNT_ADDRINFO_PERMANENT_ERRORS: 0
                           COUNT_FCRDNS_ERRORS: 0
                         COUNT_HOST_ACL_ERRORS: 0
                   COUNT_NO_AUTH_PLUGIN_ERRORS: 0
                      COUNT_AUTH_PLUGIN_ERRORS: 0
                        COUNT_HANDSHAKE_ERRORS: 0
                       COUNT_PROXY_USER_ERRORS: 0
                   COUNT_PROXY_USER_ACL_ERRORS: 0
                   COUNT_AUTHENTICATION_ERRORS: 0
                              COUNT_SSL_ERRORS: 0
             COUNT_MAX_USER_CONNECTIONS_ERRORS: 0
    COUNT_MAX_USER_CONNECTIONS_PER_HOUR_ERRORS: 0
                 COUNT_DEFAULT_DATABASE_ERRORS: 0
                     COUNT_INIT_CONNECT_ERRORS: 0
                            COUNT_LOCAL_ERRORS: 0
                          COUNT_UNKNOWN_ERRORS: 0
                                    FIRST_SEEN: 2021-03-04 14:22:45
                                     LAST_SEEN: 2021-03-04 14:22:45
                              FIRST_ERROR_SEEN: 2021-03-04 14:22:45
                               LAST_ERROR_SEEN: 2021-03-04 14:22:45
    

    Note: 因为没有为 172.16.0.30 配置本地 DNS 解析,所以最后两列有值。

作用

  • 通过缓存 IP 和主机名的映射,避免对每个客户端连接做 DNS 解析
  • 主机缓存中的错误信息可以用来判断是否阻塞,如果某主机连续多次连接失败,服务器端会阻止该主机的连接

配置主机缓存

  • 系统变量

    • max_connect_errors
      • 连续失败次数。
        [mysqld]
        max_connect_errors=10000
        
      • 如果存在网络问题,增加此变量的值是没有好处的,所以如果发生阻塞,应该首先确认 TCP/IP 连接是否正常

    • host_cache_size

      • 主机缓存大小,默认开启。
        [mysqld]
        host_cache_size=200
        
      • 动态修改这个变量会清除主机缓存

    • skip_name_resolve

      • 禁用 DNS 解析。
      • 如果 DNS 速度很慢且有很多主机,可以通过此变量禁用 DNS 解析,或者增加主机缓存 host_cache_size
  • 禁止 TCP/IP 连接,可以启动时指定 skip_networking

刷新主机缓存

  • 什么时候需要刷新

    • 当客户端主机 IP 地址变更时
    • 因为连续连接失败导致主机连接受阻时
  • 刷新主机缓存的影响
    • 会把性能表 host_cache 的内容删除,相当于清空主机缓存,并解除所有受阻主机

解锁主机的方法

  • 改变系统变量 host_cache_size
  • truncate 性能表 host_cache
  • 执行 FLUSH HOSTS 或 mysqladmin flush-hosts
  • 还有一个临时方法,就是增加系统变量 max_connect_errors

发表评论

您的电子邮箱地址不会被公开。 必填项已用*标注