包拯断案 | create connections failed的深度剖析@还故障一个真相

31 篇文章 3 订阅
21 篇文章 1 订阅

作为DBA运维的你是否有过这些苦恼

1)什么?应用又连不上数据库了?刚刚不是还好好的吗,怎么又不行了?

对数据库一顿操作猛如虎,最后发现还是重启好使,拍着胸脯对leader说okay,没问题啦!结果悲剧如期上演,打脸的速度赶上了找地缝的速度,此时谁来help me呢?

2)有时候出去面试,明明感觉对面试官的问题答得挺好,但面试完又没后续,上百度一逛,答案没问题呀。

长此以往,心中天天万马奔腾,疑惑+郁闷+容嬷嬷附体的心中不停在问 why? Why? Why?

面试官:应用连接数据库无法创建新的连接,请给出你的排查思路。

应聘者:可以通过show processlist查看一下当前会话,然后检查一下max_connections的参数,看一下wait_timeout空闲会话的超时时间,如果当前会话已经达到max_connections的最大值,则连接会话满了;

面试官:如果当前空闲会话没有达到最大值,但是仍然无法创建连接,该从何处下手排查?

应聘者:啥?啥?啥?弄啥嘞,我回答得还不全面吗?面试官脑子xx了吗?

其实站在面试官的角度看,也合乎情理。

为啥嘞?细想一下:

如果面试官问了你一个故障现象,而不是一个具体的报错信息,那他其实是想看你的知识储备和是否有丰富的运维经验,是否能胜任复杂的运维工作。如果你回答的是百度上随处可见的答案,面试官听了也会觉得耽误他的时间,因此我们如何才能让面试官两眼放光呢?

答案显而易见:除了美貌之外剩下的就是才华了~

1、心中有章,遇事不慌

作为DBA的你,遇到问题无从下手,除了在问题面前徘徊,又能如何选择?如果你第一次(或多次)遇到该问题还是无法解决,又很懊恼,该如何排忧呢?

2023包拯断案系列之包拯秘籍

✨整套故障排错及应对策略送给你,让你像包拯一样断案如神:

#首先

遇到此类问题后 我们要做到心中有章(章程),遇事不慌。一定要冷静,仔细了解故障现象(和研发或用户反馈的问题仔细沟通故障现象、操作流程、数据库架构等信息)

#其次

我们要根据故障现象进行初步分析。心中要想什么情况会导致会话创建失败?例如:数据库本身限制了连接数的大小?操作系统资源限制了连接数的创建?网络限制给阻塞掉了?

#然后

针对上述的思考,我们需要进行逐步验证并排除,确定问题排查方向。

#接着

确定了问题方向,进行具体分析。通过现象得出部分结论,通过部分结论继续排查及论证。

#最后

针对问题有了具体分析,并进行线下复现,从而梳理故障报告。

2、真刀实战,我们能赢

说了这么多理论,想必实战更让你心动。那我们就拿一个真实案例进行分析——当应用连接数据库失败,导致业务受阻,该如何进行快速分析处理:

-2.1 故障处理场景

(加班不是福报,摸鱼才是王道。)

突然的信息打破了正在划水的你,什么!???

⚠️ 突然收到一条某客户的数据库实例DBA运维人员发来的信息:应用无法执行sql语句,业务卡顿!

瞬间警醒,慌得一匹,数据库down啦?内存满啦?无数个【可能】从脑海中闪过……

收到信息10s后:联系客户的DBA运维人员,沟通具体的故障信息场景,并指导后续操作

• 大脑回复:开发人员反馈,某个接口异常,查看日志发现连接数据库执行sql语句失败;

收到信息20s后:排查当前数据库运行状态

• 发送命令:

netstat -lntup|grep pidof greatdb || ps -aux|grep pidof greatdb

• 大脑回复:当前数据库运行状态正常;

收到信息30s后:使用客户端手动连接数据库进行本地连接测试

• 发送命令:

greatdb -uxxx -pxxx -h127.0.0.1 -P xxx -e “select 1”;

• 大脑回复:进程卡住,无法获取到1的返回值;

收到信息35s后:查看系统的资源限制

• 发送命令:

ulimit -a;

• 大脑回复: 文件句柄软硬连接限制都是1024;

收到信息40s后:查看文件句柄限制

• 发送命令:

cat /etc/security/limits.conf && cat/etc/security/limits.d/20-nproc.conf;

• 大脑回复:无任何配置;

收到信息45s后:查看当前进程的资源限制

• 发送命令:

cat /proc/pidof greatdb/limits|grep “Max open files”;

• 大脑回复:文件句柄软硬连接限制都是1024;

收到信息50s后:查看当前数据库使用了多少文件句柄,是否超限

• 发送命令:

lsof -p pidof greatdb|wc -l && lsof -p pidof greatdb|grep TCP|wc -l;

• 大脑回复:目前总共占用了1111个连接,TCP连接占用的文件句柄是988个;

收到信息55s后:查看当前操作系统允许的最大文件句柄数

• 发送命令:

cat /proc/sys/fs/file-max;

• 大脑回复:当前操作系统最大允许打开789968个文件句柄数;

收到信息60s后:确认一下该服务的tcp套接字

• 发送命令:

netstat -alntup|grep IP:Port|wc -l ;

• 大脑回复:当前的连接已经占用文件句柄达到了1000 ;

(故障已定位并反馈,进行相应的应急处理…)

处理手段:

关闭非业务应用的数据库访问,释放部分资源,让业务正常运行(主要保证正在执行的DML),修改limit限制,重启数据库。

经过上述一顿猛如虎的操作和排查,1-2分钟内快速定位了问题原因,且及时和客户业务方进行了沟通,最大化地减少并避免了业务受到的影响。

同时,在故障排查过程中保留了排查步骤及结果图,故障处理完成后进行故障报告编写,全流程专业、顺畅、有序的操作得到了客户的认可与肯定。

本 期 复 盘 总 结

1)本次故障主要是因为底层环境导致的数据库出现故障

2)指定数据库运行环境及运行状态的定期巡检

3)增加相关参数的定期监控

4)根据巡检项开发自动化运维脚本并与告警相结合

番外篇-展昭答疑解惑

1)在排查问题时,为什么没有先看数据库的错误日志?

答:其一:由于时间紧迫,业务受到影响。如果有些error日志因为历史原因没有做割接,那么加载>1G的文件也是比较耗时的;其二:影响连接创建的情况常见的就那几种,我们通过测试验证即可用排查法快速定位问题方向。

2)遇到此类问题,为什么监控没有提前告警?

答:其一:监控是有延迟性的,针对爆发性的问题无法处理;其二:监控项检测多少,对数据库本身也是一种负担。

3)为什么此情况就是文件句柄问题,而不是连接数打满?

答:在前面手动验证时通过问题表现就已知晓,当连接数打满时客户端会报too many connections错误。

4)创建连接的影响因素有很多,如何排除不是网络问题?

答:在手动验证时使用的是127.0.0.1的本地连接,此时连接都不正常,说明是数据库本机的问题,间接性排除了网络问题。

业务模拟代码:


```sql

```powershell

```powershell

```sql
package main
import (
        "database/sql"
        "fmt"
        _ "github.com/go-sql-driver/mysql"   //go连接greatdb的驱动
        "sync"
)
var wg sync.WaitGroup
func openDb(jdbc string) {
        db, err := sql.Open("mysql", jdbc)    //go连接greatdb的驱动类型,由于加载的驱动是MySQL,所以此处填写的是mysql,jdbc是数据库的连接串
        if err != nil {
                fmt.Println(err)
        }
        if err = db.Ping(); err != nil {
                fmt.Println("(0) database connection fail. Error Info: ", err)
        }
        db.SetMaxIdleConns(100)
        db.SetMaxOpenConns(100)
        db.SetConnMaxLifetime(-1)
        db.SetConnMaxIdleTime(-1)
        _, err = db.Exec("select sleep(100);")
        if err != nil {
                fmt.Println(err)
        }
        wg.Done()
}
func main() {
        jdbc := fmt.Sprintf("%s:%s@tcp(%s:%s)/information_schema?charset=utf8", "用户名", "密码", "数据库ip", "数据库端口")
        for i := 0; i < 1000; i++ {
                wg.Add(1)
                go openDb(jdbc)
        }
        wg.Wait()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值