凌晨三点,值班手机突然炸响。电话那头的运维同事声音都在抖:“数据库连不上了,所有业务系统全部瘫痪,客户已经开始骂娘了。”我一边穿裤子一边往公司赶,脑子里飞速转着各种可能性——网络断了?数据库挂了?连接池满了?还是最要命的那种,硬盘写满了?

这种场景,干过运维的人都不陌生。服务器连不上数据库,就像人突然断了氧气,业务系统瞬间变成一具空壳。页面转圈、接口超时、用户疯狂刷新——整个系统在几秒内从“正常运转”变成“一团乱麻”。更可怕的是,这种故障往往不是单一原因造成的,而是多重因素叠加的结果。
第一个要排查的,永远是网络。很多人一上来就查数据库进程、看日志,结果折腾半天发现是防火墙策略变更了,或者交换机端口down了。我见过最离谱的一次,是机房空调漏水,正好滴在网线上,导致信号衰减。所以,当你说“连不上数据库”的时候,先别急着怀疑数据库本身,ping一下数据库IP,telnet一下端口,确认网络层是不是通的。这一步花不了两分钟,但能帮你节省两个小时。
如果网络是通的,那问题大概率出在数据库自身。最典型的场景是连接数打满了。很多业务系统上线时,数据库连接池配置的是“够用就行”,但流量一涨,或者某个接口出现慢查询,连接就会被长期占用,新的请求根本进不去。这时候你去看数据库状态,会发现一堆“sleeping”状态的连接,它们既不工作也不释放,活像占着茅坑不拉屎。解决办法有两个:要么临时kill掉这些空闲连接,要么紧急扩容连接池上限。但别高兴太早,这只是治标。
更深层的问题,往往是慢查询导致的连锁反应。一条没加索引的SQL,在数据量小的时候跑得飞快,等数据量涨到几百万条,它就成了定时炸弹。这条SQL一执行,可能锁住整张表,其他所有请求都得排队等它完成。排队的人一多,连接池就满了,新请求进不来,于是整个系统瘫了。这种场景下,你光杀连接没用,得找到那条罪魁祸首的SQL,看看能不能加索引、改写法,或者干脆把它缓存起来。
还有一类故障特别气人——硬盘满了。数据库写不了binlog,写不了undo log,直接罢工。这时候你查数据库日志,会看到“No space left on device”之类的提示。解决办法听起来简单:删文件。但删什么文件很有讲究。有人一着急就删应用日志,结果腾出几G空间,数据库还是起不来——因为数据库需要的是数据目录的空间。正确的做法是先看哪个分区满了,然后重点清理数据库的归档日志或者过期备份。如果实在没东西可删,那就紧急挂载一块新硬盘。
说到备份,就不得不提一个血的教训。有个朋友的公司,数据库挂了之后,运维想从备份恢复,结果发现备份文件已经损坏三天了。三天啊,也就是说,即使恢复了,也要丢三天的数据。一问才知道,他们的备份脚本从来没验证过备份文件是否可读。所以,定期做备份恢复演练,比备份本身还重要。你备份了一百次,只有恢复成功的那一次才算数。
真正要命的,还不是技术问题,而是人的反应。故障发生后的前十分钟,是黄金抢救时间。但很多人会犯一个错误:慌了手脚,开始乱试。一会儿重启数据库,一会儿改配置,一会儿又去查网络。结果不仅没解决问题,还把现场搞乱了,连排查线索都丢了。正确的做法是:先止血,再查因。如果业务能降级,先降级;如果不能,那就切备用数据库或者重启集群。先让业务恢复,别管原因是什么。原因可以事后慢慢查,但业务每多宕一分钟,损失都是真金白银。
讲到你会发现,很多数据库连不上的问题,其实在架构层面就能避免。比如,数据库和业务服务不要放在同一个物理机或同一个交换机下;比如,连接池要设置合理的超时时间和熔断机制;再比如,重要业务要有读写分离或多副本架构。但架构再完美,也架不住运维人员的懈怠。定期巡检、监控告警、预案演练,这些看似繁琐的事情,才是真正能救你命的东西。
服务器连不上数据库怎么办?答案很简单:别慌,按顺序排查,先止血再查因。但更重要的答案是:别等到它断了才去想怎么办。平时多流汗,战时少流血——这句话放在运维身上,再合适不过。


