优化网络使用
MySQL如何处理客户端连接
本节介绍MySQL服务器如何管理客户端连接的各个方面。
- 网络接口和连接管理器线程
- 客户端连接线程管理
- 连接卷管理
- 管理连接管理
网络接口和连接管理器线程
该服务器能够侦听多个网络接口上的客户端连接。连接管理器线程在服务器侦听的网络接口上处理客户端连接请求:
- 在所有平台上,一个管理器线程可处理TCP / IP连接请求。
- 在Unix上,同一管理器线程也处理Unix套接字文件连接请求。
- 在Windows上,管理器线程处理共享内存连接请求,另一个管理器处理命名管道连接请求。
- 在所有平台上,可以启用其他网络接口以接受管理TCP / IP连接请求。该接口可以使用管理“普通” TCP / IP请求的管理器线程,也可以使用单独的线程。
服务器不会创建线程来处理它不监听的接口。例如,不支持命名管道连接的Windows服务器不会创建处理它们的线程。
客户端连接线程管理
连接管理器线程将每个客户端连接与专用于该客户端连接的线程相关联,该线程处理身份验证并请求对该连接的处理。管理器线程在必要时创建一个新线程,但请尝试先咨询线程高速缓存以参见其是否包含可用于连接的线程,从而避免这样做。连接结束时,如果高速缓存未满,则其线程将返回到线程高速缓存。
在此连接线程模型中,线程数量与当前连接的客户端数量一样多,这在服务器工作负载必须扩展以处理大量连接时具有一些缺点。例如,线程的创建和处理变得昂贵。另外,每个线程都需要服务器和内核资源,例如堆栈空间。为了容纳大量的同时连接,必须使每个线程的堆栈大小保持较小,从而导致其大小过小或服务器占用大量内存的情况。也可能会耗尽其他资源,并且调度开销可能会变得很大。
MySQL Enterprise Edition包含一个线程池插件,该插件提供了另一种线程处理模型,旨在减少开销并提高性能。它实现了一个线程池,该线程池通过有效地管理大量客户端连接的语句执行线程来提高服务器性能。请参见“ MySQL企业线程池”。
为了控制和监视服务器如何管理处理客户端连接的线程,几个系统变量和状态变量是相关的。(请参见“服务器系统变量”和“服务器状态变量”。)
所述thread_cache_size
系统变量确定线程缓存大小。默认情况下,服务器会在启动时自动调整该值的大小,但可以显式设置它以覆盖此默认值。值为0将禁用缓存,这将导致为每个新连接建立一个线程,并在连接终止时将其丢弃。要启用N
非活动连接线程的缓存,thread_cache_size
请N
在服务器启动时或运行时将其设置为。与之关联的客户端连接终止时,连接线程将变为非活动状态。
要监视高速缓存中的线程数以及由于无法从高速缓存中获取线程而创建了多少线程,请检查Threads_cached
和Threads_created
状态变量。
当线程堆栈太小时,这将限制服务器可以处理的SQL语句的复杂性,存储过程的递归深度以及其他消耗内存的操作。要N
为每个线程设置字节的堆栈大小,请使用启动服务器thread_stack
。设置为N
服务器启动时。
连接卷管理
要控制服务器允许同时连接的最大客户端数,请max_connections
在服务器启动或运行时设置系统变量。max_connections
如果更多的客户端尝试同时连接,然后将服务器配置为可以处理,则可能有必要增加(请参见第B.4.2.6节“连接过多”)。如果服务器由于max_connections
达到限制而拒绝连接,则它将增加Connection_errors_max_connections
状态变量。
mysqld实际上允许max_connections
+ 1个客户端连接。保留额外的连接供具有CONNECTION_ADMIN
或SUPER
特权的帐户使用。通过将特权授予管理员而不是普通用户(该用户不需要),管理员可以连接到服务器并用于SHOW PROCESSLIST
诊断问题,即使连接了最大数量的非特权客户端也是如此。请参见“ SHOW PROCESSLIST语句”。
从MySQL 8.0.14开始,服务器还允许在管理网络接口上进行管理连接,您可以使用专用IP地址和端口进行设置。请参阅管理连接管理。
组复制插件使用内部会话与MySQL Server交互以执行SQL API操作。在MySQL 8.0.18发行版中,这些会话计入max_connections
服务器系统变量指定的客户端连接限制。在这些发行版中,如果在max_connections
启动组复制或尝试执行操作时服务器已达到限制,则该操作将失败,并且组复制或服务器本身可能会停止。从MySQL 8.0.19起,组复制的内部会话与客户端连接分开处理,因此它们不计入max_connections
限制,如果服务器已达到此限制,则不会被拒绝。
MySQL支持的最大客户端连接数(即max_connections
可以设置的最大值)取决于几个因素:
- 给定平台上线程库的质量。
- 可用的RAM量。
- RAM量用于每个连接。
- 每个连接的工作负载。
- 所需的响应时间。
- 可用文件描述符的数量。
如果您有大量GB的可用RAM,并且每个工作负载都很低或者响应时间目标不高,那么Linux或Solaris应该能够至少日常支持500至1000个同时连接,最多支持10,000个连接。
增大该max_connections
值会增加mysqld所需的文件描述符的数量。如果所需数目的描述符不可用,则服务器将减少的值max_connections
。有关文件描述符限制的注释,请参见“ MySQL如何打开和关闭表”。
open_files_limit
可能需要增加系统变量,这可能还需要提高操作系统对MySQL可以使用多少个文件描述符的限制。请查阅您的操作系统文档,以确定是否可以增加限制以及如何增加限制。另请参见第B.4.2.17节“找不到文件和类似错误”。
管理连接管理
从MySQL 8.0.14开始,服务器允许专门为管理连接配置TCP / IP端口。这提供了一种用于普通管理连接的网络接口上允许的单一管理连接的替代方法,即使max_connections
已建立连接(请参阅连接卷管理)。
管理网络接口具有以下特征:
- 仅当
dmin_address
在启动时将系统变量设置为指示管理接口的IP地址时,该接口才可用。如果未dmin_address
指定任何值,则服务器不维护任何管理界面。 - 所述
dmin_port
系统变量指定的接口的TCP / IP端口号(默认33062)。 - 管理连接的数量没有限制。
- 只有具有
SERVICE_CONNECTION_ADMIN
特权的用户才能连接。
使用create_admin_listener_thread
系统变量,DBA可以在启动时选择是使用用于普通连接的侦听器线程来实现管理接口,还是具有自己的单独线程。默认设置是使用用于普通连接的侦听器线程来实现管理接口。
DNS查找优化和主机缓存
MySQL服务器在内存中维护主机缓存,该缓存包含有关客户端的信息:IP地址,主机名和错误信息。性能架构host_cache
表公开了主机缓存的内容,以便可以使用SELECT
语句对其进行检查。这可以帮助您诊断连接问题的原因。请参见“ host_cache表”。
注意服务器仅将主机缓存用于非本地TCP连接。对于使用回送接口地址(例如
127.0.0.1
或::1
)建立的TCP连接,或使用Unix套接字文件,命名管道或共享内存建立的连接,它不使用缓存。
- 主机缓存操作
- 主机缓存配置
主机缓存操作
服务器将主机缓存用于以下目的:
- 通过缓存IP到主机名查找的结果,服务器避免了对每个客户端连接进行域名系统(DNS)查找。相反,对于给定的主机,它仅需要针对该主机的第一个连接执行查找。
- 缓存包含有关在连接过程中发生的错误的信息。一些错误被认为是“阻塞”。”如果太多的这些给定主机连续发生没有连接成功,服务器阻止来自主机的进一步连接。的
max_connect_errors
系统变量决定发生阻塞(参见之前连续误差的允许次数节B.4.2.5,“主机‘的host_name’被阻塞”)。
对于每个新的客户端连接,服务器使用客户端IP地址检查客户端主机名是否在主机缓存中。如果是这样,则服务器会根据主机是否被阻止来拒绝或继续处理连接请求。如果主机不在缓存中,则服务器尝试解析主机名。首先,它将IP地址解析为主机名,然后将该主机名解析为IP地址。然后,它将结果与原始IP地址进行比较,以确保它们相同。服务器将有关此操作结果的信息存储在主机缓存中。如果缓存已满,则丢弃最近最少使用的条目。
服务器按如下方式处理主机缓存中的条目:
- 当第一个TCP客户端连接从给定IP地址到达服务器时,将创建一个新的缓存条目来记录客户端IP,主机名和客户端查找验证标志。最初,主机名设置为
NULL
,并且标志为false。该条目还用于来自同一原始IP的后续客户端TCP连接。 - 如果客户端IP条目的验证标志为false,则服务器将尝试IP到主机名到IP DNS解析。如果成功,则使用解析后的主机名更新主机名,并将验证标志设置为true。如果解决不成功,则采取的措施取决于错误是永久的还是暂时的。对于永久性故障,将保留主机名,
NULL
并且将验证标志设置为true。对于短暂故障,主机名和验证标志保持不变。(在这种情况下,下一次客户端从该IP连接时,会进行另一次DNS解析尝试。) - 如果处理来自给定IP地址的传入客户端连接时发生错误,则服务器将更新该IP条目中的相应错误计数器。有关记录的错误的描述,请参见“ host_cache表”。
服务器使用gethostbyaddr()
和gethostbyname()
系统调用执行主机名解析。
要解除阻塞主机,请通过执行一条FLUSH HOSTS
语句,一条TRUNCATE TABLE
截断“性能模式”host_cache
表的语句或mysqladmin flush-hosts命令来刷新主机缓存。FLUSH HOSTS
和mysqladmin flush-hosts需要RELOAD
特权。TRUNCATE TABLE
需要DROP
该host_cache
表的特权。
如果自从上次尝试从被阻止的主机进行连接以来发生了来自其他主机的活动,则即使不刷新主机缓存,被阻止的主机也可能变得不受阻止。之所以会发生这种情况,是因为当连接从不在缓存中的客户端IP到达时,如果缓存已满,则服务器会丢弃最近最少使用的缓存条目,以便为新条目腾出空间。如果丢弃的条目用于阻止的主机,则该主机将变为未阻止。
某些连接错误与TCP连接无关,不是在连接过程的早期(甚至在IP地址已知之前)发生的,或者不是特定于任何特定IP地址的(例如内存不足的情况)。有关这些错误的信息,请检查状态变量(请参见“服务器状态变量”)。Connection_errors_xxx
主机缓存配置
默认情况下,主机缓存已启用。该host_cache_size
系统变量控制它的大小,以及绩效模式的大小host_cache
暴露缓存目录。缓存大小可以在服务器启动时设置,也可以在运行时更改。例如,要将启动时的大小设置为100,请将以下各行放入服务器my.cnf
文件中:
[mysqld] host_cache_size=200
要将大小在运行时更改为300,请执行以下操作:
SET GLOBAL host_cache_size=300;
host_cache_size
在服务器启动或运行时设置为0会禁用主机缓存。在禁用缓存的情况下,每次客户端连接时,服务器都会执行DNS查找。
在运行时更改缓存大小会导致隐式FLUSH HOSTS
操作,该操作将清除主机缓存,截断host_cache
表并取消阻止所有被阻止的主机。
使用该--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授权表中的行进行匹配。只能使用这些表中使用IP地址指定的帐户。(如果不存在指定客户端IP地址的帐户,则客户端可能无法连接。)
如果您的DNS速度很慢且有许多主机,则可以通过禁用DNS查找 +启用skip_name_resolve
或增加host_cache_size
使主机缓存更大的值来提高性能。
要完全禁止TCP / IP连接,请在skip_networking
启用系统变量的情况下启动服务器。