资讯动态

数据库拒绝新连接:上限、连接池与占着名额的人

发布时间:2026/10/21 18:57:17 来源:尧图企业网站定制
授权与合规声明本文全部操作对象均为自建隔离靶场本机容器或隔离虚拟机涉及安全测试的环节必须以取得合法授权为前提。未经授权的渗透测试违反《中华人民共和国网络安全法》与《刑法》相关条款须承担相应法律责任。本文只讲环境配置、版本对照与靶场隔离不含任何攻击步骤、利用载荷与绕过手法请勿将文中环境指向任何非自有系统。一、“连不上”要先分成两类1.1 同一个现象两条不同的因果链靶场里最常见的一幕某个页面突然连不上库。你去重启服务好了过一会儿又不行。或者把数据库重启一遍好了半小时后又是老样子。“连不上”这三个字其实盖住了两类完全不同的事。第一类是路不通。客户端发出去的这次连接压根没走到数据库跟前——地址不对、端口上没人监听、中间有东西挡着、认证没通过。这一类的特征是谁连都一样你的网页连不上命令行大概也连不上。第二类是名额满。路是通的数据库也确实在跑但这次连接被挡回来了因为它手里没有空位置。这一类的特征正好相反有人连得上有人连不上——而且往往是少数账号连得上应用连不上。区分这两类不用翻日志先问一句同一时刻换一个客户端、换一个账号能不能连上能就往第二类走不能先查第一类。1.2 本篇只处理第二类第二类的完整链条有三段上限是多少 → 谁在占 → 占的那些该不该占。三段里最容易搞错的是第一段。多数人记住的是“上限是一个配置项默认 151”然后把它当成唯一答案。手册不是这么说的。这个上限会被另一层资源压住实际生效的可能是另一个数——第二章展开。第二段是“谁在占”。这里有一个反直觉的点占名额的往往不是“正在查询的请求”而是已经查完、但连接没还回去的那些。一句话占着名额的人不一定在干活。第三段是判断这些占着的连接是设计如此还是漏了。1.3 本篇不写什么先把边界划清楚免得带着错误期待往下看。不写“把上限调大”这件事。手册给了这个变量的取值范围本文只讲它怎么生效、被什么压住不给任何建议值。理由很实在上限该多大取决于这台机器上还跑着什么这个数不是抄来的。不写客户端那一侧怎么选路径、怎么发起连接。那属于另一篇的范围本篇从“这次连接已经到了数据库跟前、被挡下来”这一刻开始讲。也不写数据搬迁这类操作层面的话题。它与连接名额没有因果关系混进来只会让排查线变乱。读法建议第二章看上限由什么决定第三章看那个多出来的名额第四章看一个连接占什么第五章看应用侧怎么把名额用掉第六章看怎么数第七章是自查顺序。急着排障可以直接跳第七章。二、上限是一个数但不是唯一的数2.1 手册给的那个默认值MySQL 8.0 手册在系统变量那一节截至 2026-10-20 的 8.0 版页面给max_connections列了四行属性属性手册取值ScopeGlobalDynamicYesTypeIntegerDefault Value151说明原文第一句是The maximum permitted number of simultaneous client connections.simultaneous这个词要圈出来。它管的不是“一共来过多少个连接”是“同一时刻能同时存在多少个”。这两个数在观感上差得很远一个页面一天被开很多次只要每次开完就关同时存在的可能一直很少反过来一个页面只被打开过几次但每次都留着不关同时存在的就会一直堆着。Dynamic: Yes这一行也值得看一眼。它的意思是这个值不需要重启就能改。这一条本身不是建议但它解释了一个常见困惑为什么有人“改完没重启也生效了”也有人“改了没生效”——前者动的是运行时的值后者动的是配置文件里的字两者不是同一层。2.2 实际生效值两个数取小的那个紧接着的一句是本文最该背下来的The maximum effective value is the lesser of the effective value of open_files_limit - 810, and the value actually set for max_connections.拆开看它说了三件事。第一存在“effective value”生效值这个概念。你设的那个数不一定是最后生效的那个数。手册在这里把“设了什么”和“生效了什么”分成了两句话这个区分是整篇的地基。第二生效值由两项比较得出一项是open_files_limit的有效值减去 810另一项是max_connections的设定值。取较小的那个。第三注意open_files_limit前面也带着“effective value”——它自己也可能不是配置文件里写的那个数。所以这是一条两级的链文件句柄那一层先算出自己的有效值减掉 810再去和连接数的设定值比。由这段原文可以直接推出一个结论这是推导不是原句只把max_connections往上调可能一点用都没有。如果文件句柄那一层给不出那么多取较小者会把你的调整整个吃掉。表现就是“我明明改了怎么还是那个数”。2.3 为什么中间要减掉一个常数手册没有解释 810 这个数是怎么来的本文也不猜。能说的只有一句数据库自己也要用文件句柄——它要打开数据文件、日志、临时文件还有别的运行时资源。所以“能拿出多少给客户端连接”不是open_files_limit的全额而是扣掉内部开销之后的余量。这解释了一个容易忽略的事实连接数上限不是一个可以在真空里调的数。它挂在一个更底层的资源账上。这也是同一份配置搬到另一台机器上表现可能不一样的原因——那台机器文件句柄这一层给的额度不同。要看这一层得分别读两个值设定的连接数和文件句柄那一层的实际额度。下面两条都是只读查询⚠️代码待验证mysql-eSHOW VARIABLES LIKE max_connections;mysql-eSHOW VARIABLES LIKE open_files_limit;读法第一个数出来的是当前生效值不是配置文件里的字第二个也是有效值。两个都拿到才能按 2.2 那句原文比一次。如果两个数都对不上你记忆里的配置先别怀疑自己记错——配置文件可能根本就没被读到。同一台机器上可能躺着不止一份配置文件而服务实际读的是哪一份由启动时的方式决定。要确认这一点可以看服务自己报出来的默认值来源⚠️代码待验证my_print_defaults mysqld这条命令打印的是“按当前环境会被采用的配置项”比直接翻文件更接近真相。至于它在你机器上输出什么以输出为准本文只给写法。三、那个多出来的名额3.1 原文实际上允许 1手册的故障排查附录 B.3.2.5 节截至 2026-10-20 的 8.0 版页面在讲这个问题时第一句先给判断If clients encounter [此处为手册所述连接耗尽的报错名按要求不引] when attempting to connect to the mysqld server, all available connections are in use by other clients.方括号里的部分手册原本写的是一个具体的报错名称本文按规定不写报错文本用方括号代替。意思不变所有可用连接都被其他客户端占着。紧接着的一段才是本节的核心逐字为mysqld actually permits max_connections 1 client connections. The extra connection is reserved for use by accounts that have the CONNECTION_ADMIN privilege (or the deprecated SUPER privilege).三处细节值得停下来看。actually permits——手册用“实际上允许”这个词是在纠正一个想当然你以为上限就是max_connections实际允许的是它加一。reserved for use by accounts that have the CONNECTION_ADMIN privilege——这一个名额不是留给“先到的人”而是绑在权限上的。没有这个权限的账号即使抢在最前面也用不上它。or the deprecated SUPER privilege——SUPER是旧写法手册明确标了 deprecated已弃用但仍然认。所以在判断“我这个账号有没有这个名额”时不能只看CONNECTION_ADMIN还要看有没有那个旧的。3.2 这个设计解决的是什么问题同一段后面还给了一句用途说明逐字为By granting the privilege to administrators and not to normal users (who should not need it), an administrator can connect to the server and use SHOW PROCESSLIST to diagnose problems even if the maximum number of unprivileged clients are connected.这句话把设计意图讲得很清楚名额满的时候得有人能进去看。如果满了就谁都进不去这个系统就没法诊断了——你连“谁在占”都看不到。所以这个 1 不是“预留的缓冲”而是一条诊断通道。它默认只对管理员开放普通账号拿不到这是刻意的。由这段可以推出一条判读推导你能连上不代表没满。如果你是管理员账号满的时候你照样进得去进去以后一切正常于是很容易得出“数据库没问题”的结论——而外面那些应用正在一个个被挡回来。这是本篇最想纠正的误判。3.3 反过来应用连不上你连得上把 3.1 和 3.2 合起来得到一个很实用的判据现象可能的位置管理员账号能连、应用账号连不上且管理员进去能看到一堆连接名额被占满应用账号没有那个额外名额管理员账号也连不上不是名额问题回到第一章的第一类两个账号都能连但应用偶发失败连接在“够用”和“不够用”之间来回看第五章第一行是本文的主战场。它同时说明了一件事“我能登进去”这个证据分量比想象中低——因为你登的可能正是那道专门给你留的门。四、每个连接都要占一份资源4.1 连接不是免费的一个连接建立之后数据库要为它准备一份运行时上下文这个连接是谁、当前在哪个库、上一次执行到哪儿、会话级的变量是什么以及一块用来放这次查询中间结果的地方。这些东西跟着连接走不跟着查询走。查询结束了上下文还在因为下一个查询可能马上就来还要接着用。max_user_connections的默认值、thread_cache_size的具体影响、单个连接的内存开销究竟是多少本次未逐字核到手册对应条目一律标「待验证」本文不给任何数值。这里只保留一个定性结论每个连接都占一份资源这份资源在连接关掉之前不会还回去。由此得到本章最重要的一句“空闲”不等于“不占资源”。一个连接即使一条语句都不执行它那份上下文也还在。4.2 长连接把“瞬时占用”变成“常驻占用”短连接的做法是要用就连用完就断。这样同时存在的连接数大致等于“同一时刻正在处理的数量”。长连接的做法是连一次一直留着。这样同时存在的连接数大致等于“被打开过、还没断的那些”。这两个数在业务低峰期差别不大高峰期差别很大——但真正的麻烦不在高峰期在高峰期过去之后。短连接会随着请求结束自然回落长连接不会它会一直停在那里把名额占着直到超时或被回收。这就解释了第一章那个“重启就好、过一会儿又不行”的现象重启把名额清空了但只要那些连接还会被重新建立、重新留住一段时间后又是同一个局面。重启是清账不是改账。4.3 一个连接从生到死账是怎么走的按顺序看一个连接会走过四段阶段占着什么谁决定它结束建立一个名额加一份运行时上下文——空闲同上一样不少连接自己什么时候断执行上面那些再加执行期的临时资源语句什么时候执行完关闭逐步释放客户端主动断或服务端回收表里最该看的是第二行。“空闲”这一行占的东西和“建立”那一行完全一样——手册没有给“空闲连接占用更少”这样的说法。所以“它没在跑查询应该不占什么”这个直觉是错的。第三行也值得注意执行期的临时资源是叠加在连接那份之上的不是替换。所以“连接数够”和“这台机器扛得住”是两个问题不能互相代替。五、应用侧连接是复用还是新建5.1 连接池做的事是把“新建”换成“借还”到这里问题已经从“库的上限是多少”转到了“应用这一侧到底开了多少个连接”。如果应用每次请求都新建一个连接、用完就关那么它同时持有的连接数大致跟着“同时处理的请求数”走。如果应用用连接池那么它在启动或首次用到时先建一批之后请求来了借一个、用完还回去。MySQL 客户端这一侧的连接复用机制、PHP 的mysqli/PDO持久连接行为、连接串里p:前缀的确切语义本次未逐字核到手册条目标「待验证」。本章只讲“复用会改变谁在占名额”这一层判断不给具体写法。复用带来的第一个变化是连接数不再跟着请求数走而是跟着池子的配置走。请求再多池子最多也就那么多请求再少池子里的连接也还挂在那儿。听起来是好事——它把“上限”从“看运气”变成了“看配置”。但它同时带来一个新问题池子的上限是应用自己定的跟数据库那个上限没有任何联动。5.2 两个上限之间没有自动对齐这是本章要讲清的核心。数据库那边有一个上限第二章那个取较小者的数应用这边有一个池子的大小。这两个数之间不存在任何自动协商。于是有三种局面局面表现池子总量小于数据库上限名额用不满也永远撞不到墙同时没什么弹性池子总量大致等于数据库上限谁先到谁占剩下的被挡表现是“有时好有时坏”池子总量大于数据库上限池子里的一部分连接注定建不起来第三种最容易被忽略因为它看起来配得很充裕。实际上多出来的那部分只会在真正需要的时候失败——平时看不出来一忙就露。算这笔账的方法不是看某一个应用的池子多大是看所有连这个库的东西加起来。同一台库上可能挂着好几种角色Web 应用、定时任务、后台脚本、监控采集还有你自己开着的那个命令行窗口。每一个都有自己的连接每一个都在同一个池子里取名额。这一步经常是排查的转折点你以为只有应用在连实际上还有别人。5.3 “占着名额的人”可能是三种不同的东西把第五章收一下。占名额的粗分三类处理方式完全不同。第一类正在干活的。这类占着是应该的问题不在它在总量。第二类干完活没走的。长连接、池子里的空闲连接、忘了关的脚本。这类是“占着但不产出”也是最常见的浪费。第三类卡住的。连接还在但它的语句一直没结束——可能在等锁可能在跑一个很久的查询。这类最麻烦因为它既占名额又在消耗执行资源而且不会自己好。三类的区分方法在第六章看状态、看时长、看它在等什么。配套资料第五章这张“三种占名额的人”的分类连同 2.2 那句原文的逐项拆解、第七章的五步自查顺序我整理成了一页纸的排查卡每个判断都标了本文的章节号方便回头对依据。放在资料包里扫码即可获取六、怎么数“现在有多少个”6.1 三条只读的观察路径数连接不需要任何写操作。三条路径从粗到细。第一条数个数。看当前同时存在多少个连接再和第二章那个生效上限比。第二条看明细。手册在 3.1 引用的那段里明确提到了SHOW PROCESSLIST——它是被写进“名额满时管理员该怎么办”这句话里的说明这是官方指定的诊断入口。这一条比第一条多给了两个维度每个连接来自谁、处在什么状态。第三条看配置。确认“我以为的上限”和“实际生效的上限”是不是同一个数。⚠️代码待验证mysql-eSHOW PROCESSLIST;mysql-eSHOW VARIABLES LIKE max_connections;mysql-eSHOW VARIABLES LIKE open_files_limit;三条都是只读。第一条给一张表行数就是当前连接数第二条给一个生效上限第三条给文件句柄那一层的额度。这三个结果要一起看只有个数、没有上限判断不了“满没满”只有上限、没有个数判断不了“离满还有多远”。不想连进去的话也可以在系统层面数这一侧的网络连接。这条只是旁证不是权威值⚠️代码待验证ss-tnstate established( sport :3306 )为什么说它是旁证系统层面数到的是“这台机器上和这个端口有关的连接”它可能把别的进程算进来也可能漏掉一些状态。以数据库自己报的数为准系统层面这个只用来交叉验证。6.2 一个数说明不了什么三个维度才行拿到“当前连接数”之后别急着下结论。同一个数可能是完全不同的三件事维度要看什么说明了什么来源这些连接分别来自哪些客户端是应用在占还是别的角色在占状态是在执行、空闲还是在等是“该占的”还是“占着不干活的”时长每个连接存在了多久是短连接的自然堆积还是长连接的常驻这三个维度合起来才对得上第五章那三类。只看来源你会得出“是应用占的”可应用占着也许是正常的。只看时长你会得出“这些连接存在很久了”可久不代表错——池子里的连接本来就该一直在。判断“该不该占”要的是三个维度的组合不是其中任何一个单独的数。6.3 从这里开始问题才变得可回答数清楚之后原来那个“数据库为什么拒绝连接”就拆成了几个具体问题生效上限是多少是被max_connections卡的还是被文件句柄那一层卡的当前占了多少离上限还差多少占着的里面有多少是空闲的空闲了多久这些连接来自哪几个客户端每一个客户端的池子多大四个问题都答得出来“该动哪里”就不用猜了。反过来说这四个问题答不出来就去改配置是在赌。而且赌输的概率不低——第二章那句原文已经说明你改的那个数可能压根不是生效的那个数。七、自查顺序7.1 五步按顺序走把全篇收成一条线第一步 同一时刻换个账号能不能连上 ├─ 不能 ── 路不通本篇到此为止1.1 └─ 能 ──── 继续 第二步 你用来试的那个账号有没有那个额外名额 ├─ 有 ──── 你走的是诊断通道能连上不能证明没满3.1 / 3.2 └─ 没有 ── 继续 第三步 生效上限是多少被哪一层卡的 ├─ 是 max_connections 卡的 ── 继续 └─ 是文件句柄那一层卡的 ──── 先看那一层2.2 / 2.3 第四步 当前占了多少来源、状态、时长分别是什么 6.1 / 6.2 第五步 占着的属于哪一类干活的 / 没走的 / 卡住的 5.3这张图的顺序不能调。第一步没做就往下走很可能在查一个根本不存在的名额问题第二步没做就下结论很可能把“我能进”当成“没满”。7.2 三件可以带走的事第一上限不是“一个数”是“两个数取小的那个”。手册原句写得很直白生效值取open_files_limit有效值减 810 与设定值中较小的那个。记住这半句能省掉很多“我明明改了”的困惑。第二“能连上”不是“没满”的证据。max_connections 1那一个名额是留给带CONNECTION_ADMIN或旧的SUPER权限的账号的用途就是让管理员在满的时候还能进去看。你走的可能正是那条通道。第三占名额的不一定在干活。空闲连接占的东西和刚建立时一样多“没在跑查询”不等于“不占资源”而长连接把这个占用从瞬时变成了常驻。7.3 最后一句边界本篇不给“该设成多少”的答案这不是藏私——这个数取决于这台机器上还跑着什么以及所有连它的应用各自开了多大的池子。第二章那句原文决定了你调的那一格可能根本不是生效的那一格。能确定的是在数清楚“谁在占”之前任何关于上限的调整都是在猜。本章可以带走的一句先分清是路不通还是名额满再去看是谁把名额用掉了。配套资料第七章这五步自查顺序加上第二章的原文拆解和第五章的三类占位者我做成了一张可以打印的排查卡每一步都标了章节号照着走不会跳步。放在资料包里扫码即可获取附表 A本文引用事实与官方出处对照表#事实逐字或紧贴原文的转述出处核验日期本文位置1max_connectionsScope Global、Dynamic Yes、Type Integer、Default Value 151docs.oracle.comMySQL 8.0 Reference Manual系统变量页DB12026-10-202.12“The maximum permitted number of simultaneous client connections.”同上DB1逐字docs.oracle.com 系统变量页2026-10-202.13“The maximum effective value is the lesser of the effective value of open_files_limit - 810, and the value actually set for max_connections.”同上DB1逐字docs.oracle.com 系统变量页2026-10-202.2 / 2.3 / 7.24“只调 max_connections 可能无效因为生效值取较小者”由 DB1 原句推出本文推导非原句2026-10-202.25810 这个常数的来源手册未作解释手册未给说明本文明确不作推测2026-10-202.36连接耗尽时手册的判断句所有可用连接都被其他客户端占着原文含报错名按要求以方括号代替、不引报错文本docs.oracle.comMySQL 8.0 Reference Manual 故障排查附录 B.3.2.5DB22026-10-203.17“mysqld actually permits max_connections 1 client connections. The extra connection is reserved for use by accounts that have the CONNECTION_ADMIN privilege (or the deprecated SUPER privilege).”同上DB2逐字docs.oracle.com 附录 B.3.2.52026-10-203.1 / 7.28“By granting the privilege to administrators and not to normal users … use SHOW PROCESSLIST to diagnose problems …”同上DB2逐字docs.oracle.com 附录 B.3.2.52026-10-203.2 / 6.19每个连接都占一份运行时资源空闲连接不释放这份资源定性DB4具体数值待验证本次未逐字核到手册条目2026-10-204.1 / 4.310应用侧连接复用会改变“谁在占名额”的判断DB5待验证mysqli/PDO持久连接细节本次未逐字核到2026-10-205.111连接池大小与数据库上限之间无自动对齐需按全部客户端合计由 DB1 的“同时存在”口径推出本文推导2026-10-205.212SHOW PROCESSLIST是手册指定的诊断入口同第 8 条DB22026-10-206.113本文全部命令均未在本机运行本机无 mysql / mysqld一律标「代码待验证」本机环境说明2026-10-202.3 / 6.1附表 B术语速查表术语一句话解释max_connections允许同时存在的客户端连接数全局、动态、整数手册默认值 151生效值effective value手册用来区分“设了什么”和“实际按什么算”的措辞不等于配置里的字open_files_limit文件句柄那一层的额度连接数生效值要拿它的有效值减 810 去比810手册原句里出现的扣减常数来源手册未解释CONNECTION_ADMIN拥有它才能用上max_connections 1里多出来的那一个名额SUPER旧权限名手册标为已弃用但仍被认作那个名额的凭据诊断通道那个 1 名额的实际用途满的时候让管理员还能进去看SHOW PROCESSLIST手册在“名额满怎么办”里点名的诊断入口行数即当前连接数连接池应用侧预先建好一批连接、用时借、用完还使连接数跟着配置而不是请求数长连接建一次一直留着把名额占用从瞬时变成常驻空闲连接不执行语句但上下文仍在占用与刚建立时相同排除法第一步同一时刻换个账号能不能连——用来分开“路不通”与“名额满”写在最后这篇用到的资料写这篇文章时把 MySQL 8.0 手册的max_connections条目和故障排查附录 B.3.2.5 对着读才发现“默认 151”这句话后面还跟着半句“取较小的那个”——多数人只记住了前半句于是改完发现没变化。顺手也整理了几份配套的东西数据库连接上限排查卡两个数取较小者的算法、1 名额的判据、五步自查顺序Web 安全学习路线图从基础打牢到安全管理四个阶段各学什么常用靶场清单每个靶场练什么、适合哪个阶段资料是我自己整理的放在下面这个码上扫码即可获取添加时备注「靶场」优先通过。拿到之后建议先看数据库连接上限排查卡那一份下次再碰上“连不上”先花十秒分清是路不通还是名额满比反复重启服务有用得多。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑