滚动新闻 →
推拉窗为什么越来越难开 奥斯卡小金人与神有关?2700前的铜像告诉你 法国周末骚乱背后是哪些人? AI 系统为什么需要 MLOps,它与传统 DevOps 到底有哪些不同 Cloud SQL 数据库连接数过高怎么办,从应用连接池到实例配置逐项检查 汶川地震余震?绵阳发生5.0级地震 多地震感明显 马斯克宣布给全美儿童每人一股股票 普京提议美中俄峰会 泽连斯基被晾一边? 美国向中东12国发警报 以军进入高度戒备 超强台风蔷琵略过关岛 恐直扑台湾 PHP 定时任务处理大量 SaaS 数据时,应该怎样分批执行 笔记本电脑电池掉电速度突然加快,如何判断是电池老化还是硬件故障 亚股跳水!何时止跌?关键看利率 下季财报是重点! 1000步的缤纷台湾:坪林一日游 太好玩了! 美军前狙击手:曾在51区秘密作战 击毙外星人 Windows 11 文件属性怎么看?大小、位置、创建日期等信息全面了解 MySQL 表应该怎么设计?从一个简单新闻网站建立数据库结构 李清照前后期作品为什么变化如此明显 薏米在传统饮食文化中的地位 金鸡奖提名无辛芷蕾惹议 观众:不能办别办了! 中国第3季GDP4.5% 依赖出口加剧失衡 书法为什么不仅仅是把字写漂亮 让孩子理解集体利益不是个人利益的牺牲品 【概览】“国手山脉杯”国际围棋赛(个人赛) 全红婵现身上海参加活动 重返训练未来仍不确定 视频格式和视频编码有什么区别 唐朝为什么在安史之乱后逐渐衰落 大陆网红王扁重庆摆摊遇袭 遭人挥锤殴打入院 中国人疯抢“蟑螂粉”替代蛋白粉 专家示警 沈阳高架桥上惊现三匹马 车流中狂奔画面曝光 洗钱集团干部土地公庙求财 高雄警现场逮人 北京预计2035年进入“重度老龄化” 四大危机来临 旧房采光不好可以有哪些低成本改善方法 发酵食品为什么能够体现一个地区的生活智慧 张爱玲美国英文演讲 原声录音热传(录音) 湖北一男子酒后摔死 家属索赔33万余元引热议 川普:不想俄国退出谈判 我要战争结束! 澳洲“幽灵鲨潜舰”长獠牙 配备无人机与水雷强化战力 清晨推开窗,班夫之外的加拿大库特尼国家公园已经被群山包围 史上最大规模 美日“利剑27”军演今启动

Cloud SQL 数据库连接数过高怎么办,从应用连接池到实例配置逐项检查

发布时间: 2026-10-19 09:24:01    最后更新: 2026-10-19 10:53:46    阅读:8  约14 分钟阅读     

Cloud SQL 数据库连接数过高怎么办,从应用连接池到实例配置逐项检查
图片说明:示意图   图片来源:Public Domain(公有领域)
Cloud SQL 数据库连接数突然升高,是 SaaS、API 服务和后台管理系统中非常常见的一类性能问题。很多开发人员看到连接数接近上限后的第一反应,是直接把数据库允许的最大连接数调大。但数据库连接并不是越多越好。一个实例如果已经因为 CPU、内存、磁盘 I/O 或慢查询出现性能瓶颈,再增加几百甚至几千个连接,往往只是让更多请求同时排队,甚至把原本可以恢复的数据库拖入更严重的资源争用。

因此,Cloud SQL 出现连接数过高时,首先应该回答的不是“还能增加多少连接”,而是“为什么这些连接没有及时释放,以及每个连接为什么要占用这么长时间”。从应用连接池开始,一直检查到 SQL、事务、数据库实例和部署架构,通常才能找到真正原因。

第一步应该检查应用连接池,而不是直接修改 Cloud SQL 的连接上限。以 Java 应用常见的 HikariCP 为例,maximumPoolSize 决定一个应用实例最多可以同时持有多少数据库连接。如果 Kubernetes 中部署了20个 Pod,而每个 Pod 都配置 maximumPoolSize=100,理论上的连接需求就已经可能达到2000个。Cloud SQL 看到的是所有应用实例连接的总和,而不是某一个 Pod 的连接数。

这也是生产环境中非常容易被忽略的问题。开发人员可能看到单个应用实例只使用几十个连接,于是认为数据库完全没有压力,却没有计算整个集群的连接池总容量。

例如:

应用实例数量 × 每实例 maximumPoolSize

得到的只是理论最大连接数,但这个数字已经非常适合用来做第一轮容量检查。如果还有后台 Worker、Cron、数据分析任务、管理后台、迁移脚本以及其他微服务访问同一个 Cloud SQL 实例,实际连接来源还会更多。

连接池也不能只看最大连接数。需要同时检查最小空闲连接、空闲连接回收时间、连接获取超时时间、最大生命周期以及应用实例数量。连接池过大,会让数据库长期维持大量连接;连接池过小,则可能让应用请求长时间等待可用连接。

这里尤其要注意一个概念:connectionTimeout 并不是“让数据库连接过一段时间自动关闭”。以 HikariCP 为例,connectionTimeout 主要控制应用从连接池获取连接时最多等待多久;它与连接本身的生命周期不是一回事。连接回收通常涉及 idleTimeout、maxLifetime 等参数。

因此,不应该把下面两个概念混在一起:

获取连接最多等待多久
连接最多存活多久
空闲连接多久回收

这几个参数解决的是不同问题。

如果怀疑连接泄漏,可以开启 HikariCP 的 leakDetectionThreshold 进行诊断。它适合帮助发现某段代码借用了连接却长时间没有归还。需要注意,这个参数更接近“异常持有连接的诊断工具”,而不是一个自动修复连接泄漏的开关。开启之后,如果阈值设置得过低,大量正常但耗时较长的 SQL 也可能产生告警,因此应该结合实际业务查询时间判断。

PHP、Python、Node.js 等技术栈也存在类似问题,只是连接池实现不同。尤其是 PHP-FPM 环境,需要同时考虑 PHP Worker 数量和数据库持久连接配置。如果每个 Worker 都可能建立数据库连接,那么 PHP-FPM 的并发规模本身就可能成为 Cloud SQL 连接数的重要来源。使用持久连接并不意味着可以无限复用连接,反而需要特别注意进程生命周期、连接状态和数据库端资源消耗。

第二步是检查数据库连接到底在“做什么”。

连接数高并不等于数据库正在高效工作。假设 Cloud SQL 有500个连接,其中450个连接都在等待某个慢查询、锁或者事务提交,那么增加到1000个连接并不会让系统快一倍。

因此应该同时观察:

当前连接数
活跃连接数
空闲连接数
等待中的连接
事务持续时间
锁等待
CPU 使用率
内存使用率
磁盘 I/O
查询延迟

对于 MySQL,可以检查当前连接和运行中的 SQL:

SHOW PROCESSLIST;

生产环境中则应该进一步使用 performance_schema 等诊断能力分析等待事件、事务和 SQL 执行情况。

例如,一个 SQL 平时只需要50毫秒,那么一个连接很快就能返回连接池。但是,如果因为缺少索引导致同一个 SQL 从50毫秒变成5秒,那么同样的并发量下,连接占用时间可能扩大100倍。此时看到的现象就是“数据库连接突然爆满”,但真正的根因其实是 SQL 执行时间突然变长。

因此,连接数问题和慢查询问题经常是同一个故障的两个表现。

Cloud SQL 的监控体系在这里非常重要。Google Cloud 的 Cloud Monitoring 可以观察数据库连接等指标,Cloud SQL Insights 则可以帮助从查询层面进一步分析数据库负载。实际排查时不要只截取某一分钟的连接数,而应该观察一段时间的趋势。

例如,如果每天上午9点以后连接数持续增长,到中午达到高峰,然后随着业务量下降而恢复,那么可能是正常的流量模式,也可能说明连接池配置过大。反过来,如果业务流量没有明显增加,连接数却从100逐渐涨到500、800、1000,而且一直不下降,则更应该怀疑连接泄漏、连接未释放、长事务或者后台任务异常。

第三步是检查事务。

数据库连接长期被占用的一个常见原因,就是事务没有及时结束。例如代码执行:

START TRANSACTION;

之后进行了多个业务操作,但因为异常路径没有执行 COMMIT 或 ROLLBACK,连接就可能长期保持在事务状态。

更危险的是,事务里面如果同时包含外部 HTTP 请求、文件操作或者复杂业务逻辑,那么数据库连接可能在等待第三方 API 的几十秒甚至几分钟时间里一直被占用。

因此,数据库事务应该尽可能短。

比较合理的结构通常是:

获取连接
开始事务
执行数据库操作
提交事务
释放连接

外部 API 调用
复杂计算
文件处理
尽量不要长时间占用数据库事务

如果一个订单处理流程需要调用支付平台、物流平台或第三方 SaaS API,更不能简单地把整个流程包在一个数据库事务里。

第四步才是考虑 Cloud SQL 实例本身的容量。

Cloud SQL 的最大连接数并不是一个可以对所有数据库实例统一写成“默认1000、最高5000”的固定数字。实际可用连接上限与数据库引擎、实例配置以及 Cloud SQL 对相应数据库版本和规格的限制有关。因此,生产环境不应该直接套用某个文章中的固定数字,而应该查看当前实例实际显示的连接限制和数据库参数。

即使数据库允许更多连接,也不意味着应该把连接上限调到很高。

每个连接都会消耗数据库资源。具体开销与数据库引擎、查询类型、会话状态以及实例配置有关,因此不能简单地套用“每增加1000连接就增加10%到15% CPU和内存”这样的固定公式。真正可靠的方法是通过监控和压力测试观察实际变化。

如果 Cloud SQL 当前只有100个连接,但 CPU 已经长期接近满载,那么把最大连接数从500提高到2000没有解决根本问题。

相反,如果数据库 CPU、内存和 I/O 都比较充足,只是应用连接池偶尔出现短暂排队,那么合理增加连接池容量可能有意义。

第五步是检查索引和查询计划。

例如:

SELECT *
FROM orders
WHERE tenant_id = ?
AND status = ?
ORDER BY created_at DESC
LIMIT 100;

如果 SaaS 系统每天执行几十万次,而数据库没有与实际查询模式匹配的索引,就可能导致大量扫描。

这时应该结合:

EXPLAIN

以及数据库实际运行指标判断执行计划,而不是看到 SQL 慢就机械地“加索引”。

SaaS 数据库尤其需要注意多租户查询。例如大量查询都带有 tenant_id,那么索引设计通常应该围绕真实的过滤、排序和分页方式建立。假设业务经常按照租户和状态查询,再按照创建时间排序,那么可能需要考虑类似:

(tenant_id, status, created_at, id)

这样的复合索引,但最终结构必须根据实际 SQL、数据分布和执行计划决定。

第六步是检查连接来源。

如果 Cloud SQL 连接数突然从200变成1200,不要只盯着数据库本身。应该把连接来源拆开。

例如:

Web API
PHP-FPM
Java 服务
Node.js 服务
后台 Worker
Cron
报表系统
BI 工具
数据库管理工具
临时脚本
迁移程序

很多线上事故最后发现,真正制造大量连接的并不是主业务服务,而是一个忘记关闭的后台 Worker,或者某个凌晨运行的报表程序。

如果使用 Kubernetes,还应该把 Pod 数量和每个 Pod 的连接池容量一起计算。自动扩容机制如果只根据 CPU 扩容,却没有同时考虑数据库连接预算,就可能出现一个非常典型的连锁反应:

流量增加
应用 Pod 自动扩容
每个 Pod 创建连接池
数据库连接数快速增长
数据库开始等待
查询变慢
连接占用时间进一步增加
连接池继续排队

最后应用和数据库可能同时进入拥塞状态。

因此,连接池实际上应该被视为整个系统容量规划的一部分,而不是单个应用的内部参数。

对于 Cloud SQL 这样的托管数据库,还需要合理使用数据库代理或连接池代理机制。在 Google Cloud 环境中,可以根据应用架构考虑 Cloud SQL Auth Proxy / Cloud SQL Connector,以及适合具体数据库引擎和架构的连接池方案。它们主要解决连接建立、安全认证、网络路径或连接复用等问题,但不能替代应用本身的连接池容量规划。

读写分离也不能简单理解为“有了只读副本,连接数问题就解决了”。读取副本可以把部分读取流量分散出去,但如果应用本身建立了大量连接,副本同样会面临连接资源压力。同时还要考虑复制延迟。对要求强一致读取的业务,不能为了降低主库连接压力就无条件把所有读取请求转移到副本。

网络方面,Private IP 对安全性、网络路径和延迟控制可能具有实际价值,但它本身不会神奇地减少数据库连接数量。一个应用即使通过内网连接 Cloud SQL,依然可能建立数百甚至数千个数据库会话。因此,不能把网络优化与连接池优化混为一谈。

对于大型 SaaS,还应该考虑异步化。

例如用户创建订单后,并不一定需要让 HTTP 请求同步完成所有后续任务。如果订单创建、邮件通知、统计更新、日志写入、第三方同步都在一个 HTTP 请求中完成,那么一个用户请求可能长期占用数据库连接。

更合理的架构可以是:

HTTP 请求
↓
完成必要的核心数据库操作
↓
提交事务
↓
发布任务
↓
后台 Worker 异步处理

这样不仅能够缩短数据库连接占用时间,也可以让高峰流量通过队列进行削峰。

至于分库分表,更不能简单规定“超过10亿行就必须分库分表”。数据库性能取决于硬件、索引、数据访问模式、查询复杂度、冷热数据比例、事务特征以及增长速度。一张10亿行的表,如果查询高度可控、索引设计合理、冷热数据分离得当,可能仍然能够稳定运行;一张只有几千万行但查询模式混乱、全表扫描频繁的表,也可能已经成为严重瓶颈。

所以,分库分表应该是容量和访问模式共同推动的架构决策,而不是由某一个行数数字自动触发。

最后,Cloud SQL 连接数过高时,最有效的排查顺序通常可以概括为:

先确认连接数是否真的异常
↓
统计所有应用实例和 Worker 的连接池容量
↓
检查活跃连接、空闲连接和等待连接
↓
检查长事务和锁等待
↓
检查慢查询和执行计划
↓
检查连接是否正常归还连接池
↓
检查应用扩容是否导致连接池叠加
↓
评估 Cloud SQL CPU、内存和 I/O
↓
最后才考虑增加数据库连接上限

如果只是把 Cloud SQL 的最大连接数从1000调到3000,而应用仍然存在连接泄漏、慢查询和长事务,那么问题很可能只是从“1000个连接时报错”变成“3000个连接时数据库整体变慢”。

真正稳定的 SaaS 数据库架构,不是让数据库承受尽可能多的连接,而是在应用并发、连接池容量、SQL执行时间、事务长度和数据库实例资源之间建立一个可计算的预算。每一个 Web Worker、每一个 Pod、每一个后台任务都应该知道自己最多可以占用多少数据库连接,而数据库本身也应该保留足够资源处理正常查询、事务和故障恢复。这样,当业务流量增长时,系统扩容才不会变成数据库连接数的突然失控。

喜欢这篇报道?

使用下面的功能,方便以后继续阅读和分享 MNewsTV

设为 Google 新闻首选来源 让 Google 新闻优先显示 MNewsTV 的最新报道 ›
★ 我的收藏 查看已经收藏的文章
关于文章收藏 收藏不需要注册帐号,收藏信息仅保存在当前浏览器中。 删除收藏请进入「我的收藏」进行管理。
分享这篇报道

捐助(Paypal): https://www.paypal.me/observeccp
订阅中国观察电报 Telegram : https://t.me/s/ObserveCCP