MySQL max_connections变量讲解

MySQL的max_connections参数用来设置最大链接(用户)数。超过这个值,系统就会拒绝接下来的链接请求,报错提示:“too many connections”。对于被拒绝链接的请求来讲,从业务角度就是数据库不可用。mysql

每一个链接MySQL的用户均算做一个链接,MySQL8.0.13的max_connections的默认值为151.sql

MySQL不管如何都会保留一个用于管理员(SUPER)登录的链接,用于管理员链接数据库进行维护操做,即便当前链接数已经达到了max_connections。所以MySQL的实际最大可链接数为max_connections+1;数据库

MySQL创建链接的过程,成本是很高的,除了正常的网络链接三次握手外,还须要作登陆权限判断和得到这个链接的数据读写权限。安全

该参数在服务器资源够用的状况下应该尽可能设置大,以知足多个客户端同时链接的需求。不然将会出现相似”Too many connections”的错误。服务器

碰到这种状况,一个比较天然的想法,就是调高max_conncetions的值。网络

set GLOBAL max_connections=1000;线程

可是这样作是有风险的。由于设计max_connections这个参数的目的是想保护MySQL,若是咱们把它改的太大,让更多的链接均可以进来,那么系统的负载可能会进一步加大,大量的资源消耗在权限验证等逻辑上,结果可能拔苗助长,已经链接的线程拿不到CPU资源去执行业务的SQL请求。设计

处理这种状况,有另外两个有损的方法。code

第一种方法:先处理掉那些占着链接可是不工做的线程。orm

对于那些不须要保持的链接,咱们能够经过show processlist命令,查看状态为sleep的线程,经过kill connection 主动踢掉。

这个行为跟事先设置wait_timeout的效果是同样的。设置wait_timeout参数表示的是,一个线程空闲wait_timeout这么多秒以后,就会被MySQL直接断开链接。顺便提一下,wait_timeout默认值是28800秒,即8个小时。

另外须要注意,show processlist出现的结果有多个状态为sleep的线程,应该优先断开事务外空闲的链接.

如何判断哪些是事务外空闲的呢?

要看具体的事务状态,能够查看information_schema库的innodb_trx表。

select * from information_schema.innodb_trx \G

查询结果里,trx_mysql_thread_id=32,表示id=32的线程还处在事务中。

所以,若是是链接数过多,你能够优先断开事务外空闲过久的链接;若是这样还不够,再考虑断开事务内空闲过久的链接。

从服务端断开链接使用的命令是kill connection + id的命令,一个客户端处于sleep状态时,它的链接被服务端主动断开后,这个客户端并不会立刻知道。直到客户端再发起下一个请求的时候,才会收到这样的报错“ERROR 2013(HY000):Lost connection to MySQL server during query"。

从数据库端主动断开链接多是有损的,尤为是有的应用端收到这个错误后,不从新链接,而是直接用这个已经不能用的句柄重试链接。这会致使从应用端看上去,”MySQL一直没恢复“。

第二种方法:让数据库跳过权限验证阶段。

若是如今数据库确认是被链接行为打挂了,那么一种可能的作法是:让数据库跳过权限验证阶段,减小链接过程的消耗。

跳过权限验证的方法:

重启数据库,并使用--skip-grant-tables参数启动。

这样,整个MySQL会跳过全部的权限验证阶段,包括链接过程和语句执行过程在内。

在MySQL8.0版本里,若是你启用--skip-grant-tables参数,MySQL默认会把--skip-networking参数打开,表示这时候数据库只能被本地的客户端链接。可见MySQL官方对skip-grant-tables这个参数的安全问题也很重视。

相关文章
相关标签/搜索