华为云 RDS 数据库服务:MySQL/PostgreSQL 高可用配置指南
托管数据库把运维动作变成了控制台按钮,但没有把判断一并托管。主备切换的那几十秒里应用在干什么,才是"高可用"真正要回答的问题。
托管数据库最舒服的一点,是把"装、备份、升版本、做主从"这些动作变成了控制台里的按钮和开关。最危险的一点,是这些按钮让人误以为判断也被一并托管了。
主备切换是个典型:控制台上它显示为"切换已完成,耗时 32 秒"。但用户那边发生了什么,这 32 秒里应用在做什么、连接池变成了什么状态、有没有请求被静默地算错——这些都不在那个提示里。
#一、RTO 是应用的属性,不是数据库的属性
先说清楚一个经常被混淆的概念:数据库给出的"切换时间"只是它那一段的耗时。用户感知的恢复时间,是从"应用开始报错"到"应用恢复正常"的全过程。
数据库侧 RTO:故障检测 + 选主 + 切换
应用侧 RTO: 数据库侧 RTO
+ 连接池发现旧连接已死
+ 重试与退避
+ 缓存/队列积压的消化
+ 可能的会话状态丢失这个公式解释了为什么很多组织的真实恢复时间远长于数据库给出的数字:瓶颈往往在第二行和第四行。
- 第二行(连接池):连接池里握着的都是指向旧主库的连接。切换后它们会集中失效,于是所有线程同时开始重连——重连风暴。它的特征很鲜明:数据库切换本身很快,但随后数据库连接数瞬间飙升。
- 第四行(积压):如果应用在切换期间把请求堆在队列里而不是快速失败,恢复之后会有一波集中冲击,把刚起来的新主库再压一轮。
所以"高可用"的测试不能只测数据库切换,要测从应用视角看的端到端恢复时间。
#二、连接池该设成什么样
连接池的配置与故障恢复直接相关,值得单独说三条:
| 参数 | 在故障中的作用 | 常见错误 |
|---|---|---|
maxLifetime / 最大存活时间 | 让连接定期更换,故障时不会有大量"老连接"同时失效 | 设为无限(继承数据库的 wait_timeout),故障时集中失效 |
| 连接校验(test-on-borrow) | 拿连接前先验活,避免把死连接交给业务 | 关闭以求性能,结果错误以"随机的 SQL 异常"形式出现 |
connectionTimeout | 决定"等不到连接"多快失败 | 设得过长,把线程全部堵在等待上 |
第一行是最便宜的一招:让连接的最大存活时间短于数据库侧的空闲超时,这样连接会自然轮换,故障时不会有整批连接同时过期。这一条几乎不花成本,但能显著削弱重连风暴。
#三、只读副本:把"最终一致"变成可感知的现象
读写分离的架构里,只读副本的复制延迟会以非常具体的方式暴露出来:
- 用户提交表单 → 主库写入成功 → 页面跳转 → 从只读副本读 → 读不到刚才那条记录。
- 监控上复制延迟是"200ms",但用户的观感是"我明明提交了"。
这不是配置问题,是一致性语义的问题。可行的处理方式(按代价从低到高):
- 写后读主:刚写入的会话在一段时间内强制走主库。实现简单,但要小心会话粘滞带来的主库压力。
- 业务上容忍:把"必须立刻看到"的路径识别出来,让其余路径走副本。需要业务配合。
- 强一致读:牺牲扩展性换语义简单。多数互联网业务不需要走到这一步。
关键是别把复制延迟当成性能指标。它是正确性指标——它决定了用户能不能看到自己刚写下的东西。
#四、备份:价值不在"有没有",在"能不能恢复"
托管服务的自动备份解决了"有没有备份"的问题,但没解决"恢复得对不对"的问题。可验证的点有三条:
- 恢复演练:至少恢复一次到临时实例,确认数据可用、账号权限正确、连接串能通。
- 时间点恢复(PITR)窗口:这是"能回到多久之前"的上限。窗口是 7 天还是 30 天,直接决定你能容忍"多久之后才发现数据被改坏"。
- 逻辑备份的独立性:快照类备份与实例同源,删除实例可能连带影响。真正需要长期留存的,要另存一份到对象存储。
第二条常被忽略:一个常见的事故形态是"三天前的一次错误发布污染了数据",而备份窗口只有 24 小时——这时候快照再多也救不回来。
#五、参数:托管服务只把一部分旋钮给了你
托管数据库的参数通常分为"可改"和"不可改"两部分,且很多关键参数被平台按规格预设。这带来一个组合机会:不同业务用同一个实例模板,但参数需求完全不同。
| 负载类型 | 关注点 | 说明 |
|---|---|---|
| OLTP(短事务、高并发) | 连接数上限、事务隔离、锁等待 | 连接数上限比 CPU 更常成为瓶颈 |
| 分析查询(大表扫描) | 内存与临时空间 | 一个慢查询就能拖垮同实例的其它业务 |
| 混合负载 | 隔离 | 最危险:分析查询的 IO 会挤占在线事务 |
第三行是托管数据库最常见的性能事故来源。如果一定要混,至少放在只读副本上跑分析——这也解释了为什么只读副本在运维上经常不是"读扩展"而是"负载隔离"的手段。
#六、这篇没写什么
- 没写具体产品的控制台步骤与参数名。 各版本界面差异大,请以官方文档为准。
- 没写 SQL 调优与索引设计。 那是应用侧的功夫,和托管与否无关,值得单独写。
- 没写分布式数据库(分库分表、NewSQL)。 那是在单实例高可用之后的另一个阶段,混在一起会模糊掉边界。
- 没给"该选哪个版本/规格"的建议。 这取决于负载画像与兼容性要求,没有脱离场景的答案。
一句话收束:托管服务把动作托管了,没有把判断托管。所以在上线前值得问一句:切换发生的那几十秒里,我的应用会做什么?如果答不上来,那这套高可用还只是纸面上的。
写于 2026 年 5 月 11 日
- 栏目
- 技术文章
- 约
- 4.9 分钟
- 字数
- 2.2K
- 阅读
- 2
本文为原创记录,转载请注明出处。如果这篇替你省了时间,欢迎留言说说你踩到的坑。
同题 · related
留言 · remarks
00 条还没有留言,来说点什么吧。