MySQL客户端连接登入hang住原因分析

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: MySQL客户端连接登入hang住原因分析

一、问题来源

问题来自一位朋友

mysql客户端无法登陆,查看服务器负载没有发现高负载信息。通过pstack查看线程栈信息,没有发现异常信息。


二、问题诊断和解决

一般来讲出现这种情况,我们会使用pstack看看新建立的线程为在什么函数上卡住了,然后很容易就能找到原因。但是出现这个问题过后,当mysql发起连接后卡住后,使用pstack查看mysqld服务端的进程,发现根本就没有线程与之进行交互,因此mysqld怀疑监听线程是不是出了什么问题,因此对mysql客户端连接进程进行了pstack发现如下:

#0  0x00007f262e7889c0 in __connect_nocancel () from /lib64/libpthread.so.0
#1  0x0000000000435123 in inline_mysql_socket_connect (src_file=0x504490 "../../mysql-8.0.20/vio/viosocket.cc", src_line=1054, len=110, addr=0x7fffb38daa20, mysql_socket=...) at ../../mysql-8.0.20/include/mysql/psi/mysql_socket.h:647
#2  vio_socket_connect (vio=0x110d2c0, addr=addr@entry=0x7fffb38daa20, len=len@entry=110, nonblocking=<optimized out>, timeout=-1, connect_done=connect_done@entry=0x7fffb38da9ef) at ../../mysql-8.0.20/vio/viosocket.cc:1054
#3  0x0000000000422ad6 in csm_begin_connect (ctx=0x7fffb38daad0) at ../../mysql-8.0.20/sql-common/client.cc:250
#4  0x000000000041fe99 in mysql_real_connect (mysql=mysql@entry=0xaf16a0 <mysql>, host=host@entry=0x0, user=user@entry=0x10defc0 "root", passwd=passwd@entry=0x10deff0 "xsh0923", db=db@entry=0x0, port=<optimized out>, unix_socket=0x10e0860 "/data/mysql3306/tmp/mysql.sock", client_flag=66560) at ../../mysql-8.0.20/sql-common/client.cc:5600
#5  0x000000000040ddb6 in sql_real_connect (silent=0, password=0x10deff0 "xsh0923", user=0x10defc0 "root", database=0x0, host=0x0) at ../../mysql-8.0.20/client/mysql.cc:4515
#6  sql_connect (host=0x0, database=0x0, user=0x10defc0 "root", password=0x10deff0 "xsh0923", silent=<optimized out>) at ../../mysql-8.0.20/client/mysql.cc:4670
#7  0x000000000040968b in main () at ../../mysql-8.0.20/client/mysql.cc:1326
#8  0x00007f262ce3e495 in __libc_start_main () from /lib64/libc.so.6
#9  0x000000000040a4e1 in _start () at ../../mysql-8.0.20/include/my_alloc.h:86


实际上mysql卡住connect函数上面如下,

因此mysql客户端和mysqld服务端都还没有建立好连接,netstat查看如下:

unix  2      [ ACC ]     STREAM     LISTENING     8584712  29676/mysqld         /tmp/mysqlx.sock

unix 7 [ ACC ] STREAM LISTENING 8584713 29676/mysqld /data/mysql3306/tmp/mysql.sock
unix 2 [ ] STREAM CONNECTING 0 - /data/mysql3306/tmp/mysql.sock
unix 2 [ ] STREAM CONNECTING 0 - /data/mysql3306/tmp/mysql.sock
unix 2 [ ] STREAM CONNECTING 0 - /data/mysql3306/tmp/mysql.sock
大量connectint状态的连接

正常的情况下这里应该是poll和accept然后开启新的(或者从缓存线程中拿一个)线程来处理交互信息了。但是这里我们可以清晰的看到出现了SIGSTOP信号。随即查看正mysqld线程的状态,所有的线程都处于T状态下,这个状态正是由于信息SIGSTOP引起的。因此我们发一个SIGCONT信号给mysqld进程就好了如下:

kill -18 29676


三、关于信号

下面是我学习信号的时候一些笔记。

在Linux中信号是一种由内核处理的一种软中断机制,他满足简单、不能携带大量信息、并且要满足一定条件才会发送等特征。信号会经历如下过程:

  • 产生-->阻塞信号集-->未决信号集-->信号递达-->信号处理方式

首先信号的产生可以有多种方式比如我们经常用的kill命令就是发起信号的一种手段如下:

[root@mgr4 8277]# kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX



我们经常的按键也可以产生

  • Ctrl+c 2)SIGINT
  • Ctrl+\ 3)SIGQUIT
  • Ctrl+z 4)SIGTSTP

当然还有很多其他触发方式比如硬件异常,raise函数,abort函数,alarm函数等等。其次是阻塞信号集,阻塞信号集能够对想除(9/19号信号以外)的信号进行屏蔽,如果屏蔽后信号自然不会到达 递达 状态,也就谈不上处理了。通过sigprocmask函数进行阻塞信号集的设置,但之前必须要设置sigset_t 集合,通过sigaddset、sigdelset、sigemptyset、sigfillset等函数设置。

未决信号集是不能被操作的,只能被获取通过sigpending函数获取,但是他和阻塞信号集一起可以控制信号的递达。

信号递达后就需要处理信号,默认的行为上面都列举了,但是信号(9/19号信号以外)是可以被捕获改变其处理方式的,我们可以自定义函数作为某个信号的处理方式,这可以通过signal函数和sigaction函数进行捕获和处理,sigaction函数相对复杂需要有一个struct sigaction的结构体变量,其中包含了sa_handler\sa_mask\sa_flags\sa_siaction 成员,这里不做解释可以自行查看Linux man page。

上面是单进程下的信号处理方式,在多线程下,线程之间公用处理方式,但是可以有不同的信号屏蔽集,在多线程下一般采用设置统一的信号屏蔽字和信号处理方式使用pthread_mask函数继承到各个线程,同时使用sigwait/sigwaitinfo等函数设置一个单独的信号处理线程来进行统一处理,MySQL就是这样处理的。MySQL实际上有一个信号处理线程,

|     36 |         1927 | sql/signal_handler              |    NULL | BACKGROUND | NULL   | NULL         |

如果需要了解可以参考如下文章: MySQL中对信号的处理(SIGTERM,SIGQUIT,SIGHUP等), http://blog.itpub.net/7728585/viewspace-2142060/

四、pstack和SIGSTOP

这里简单提一下pstack抓取线程栈的时候会触发一个SIGSTOP信号,因为pstack实际上调用的就是gdb的如下命令:

/usr/bin/gdb --quiet -nx /proc/8277/exe 8277
thread apply all bt
输出所有线程信息

gdb通常会发起SIGSTOP信号来停止进程的运行,因此我们在线上执行pstack命令的时候一定要小心,pstack可能导致你的MySQL停止运行一小会,特别是高压力线程很多负载很高的情况下,可能需要很长的时候,pstack应该作为线上重要数据库最后不得已而为之的诊断方式

如下我们使用pstack 来获取mysqld的栈,运行一开始就关闭窗口,此时我们的mysqld已经处于停止状态.

因此使用pstack一定要格外小心。一般来讲从库线程不多压力不大重要性不高可以使用pstack进行信息采集。当然也可以手动发起SIGSTOP信号来达到测试效果。


五、捕获所有的信号

下面一个小代码可以捕获所有的信号供测试:

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "unistd.h"

void handler(int sig)
{
printf("get signal %d\n",sig);
}

void test()
{
;
}

int main(void)
{
struct sigaction s;
int* a=NULL;
int i=0;

a=(int*)calloc(32,sizeof(int));

for(i=0;i<32;i++)
{
*(a+i) = (i+1);
}

s.sa_handler=handler;

for(i=0;i<32;i++)
{
sigaction(*(a+i),&s,NULL);
}

while(1)
{
test();
sleep(1);
}

return 0;
}

全文完。

Enjoy MySQL :)

            </div>
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
存储 算法 Nacos
Nacos支持哪些协议
Nacos支持哪些协议
|
存储 Linux C语言
【C++初阶】第五站:C/C++内存管理 (匹配使用,干货到位)-1
【C++初阶】第五站:C/C++内存管理 (匹配使用,干货到位)-1
134 0
|
机器学习/深度学习 算法 前端开发
《零基础实践深度学习》波士顿房价预测任务1.3.3.5 总结
使用Numpy实现梯度下降算法来构建和训练线性模型进行波士顿房价预测的过程,并提供了模型保存的方法,同时提出了几个关于梯度计算、参数更新和神经网络训练的作业题目。
 《零基础实践深度学习》波士顿房价预测任务1.3.3.5 总结
|
自然语言处理 Python
【Python自然语言处理】文本向量化的六种常见模型讲解(独热编码、词袋模型、词频-逆文档频率模型、N元模型、单词-向量模型、文档-向量模型)
【Python自然语言处理】文本向量化的六种常见模型讲解(独热编码、词袋模型、词频-逆文档频率模型、N元模型、单词-向量模型、文档-向量模型)
4185 0
|
算法 安全 NoSQL
2024重生之回溯数据结构与算法系列学习之栈和队列精题汇总(10)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第3章之IKUN和I原达人之数据结构与算法系列学习栈与队列精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
存储 人工智能 自然语言处理
AGI时代的奠基石:Agent+算力+大模型是构建AI未来的三驾马车吗?
AI Agent的训练离不开算力,服务器作为一个强大的计算中心,为AI Agent提供算力基础,支持其进行复杂计算和处理大规模数据的任务,包括模型训练、推理和处理大规模数据集。
1665 2
|
应用服务中间件 Apache
Mac环境下安装启动Tomcat
一、 下载 登录Apache Tomcat官网,地址 http://tomcat.apache.org ,瞅瞅左边的Download,点击选择需要下载的版本 Tomcat9 二、设置本地放置路径 下载下来包解压 三、启动Tomcat 打开终端,切换到我们Tomcat的bin目录 再输入:.
3027 0
|
关系型数据库 MySQL 应用服务中间件
公司内部搭建DokuWiki百科网站,并公网远程访问
在网上各种教程和介绍中,搭建网页都会借助各种软件的帮助,比如网页运行的Apache和Nginx、数据库软件MySQL和MSSQL之类,为方便用户使用,还出现了XAMPP、PHPStudy、宝塔面板等等一系列集成服务,都是为了方便我们能快速建立网站。是不是不适用这些软件就无法建立网站了呢?答案当然是否定的,在Windows系统中实际上集成了建立网站所必须的软件环境。今天就让我们来看看,如何使用Windows自带的网站程序建立网站吧。
680 0
公司内部搭建DokuWiki百科网站,并公网远程访问
|
安全 PHP
CTF-PHP常见考点实例小结
CTF-PHP常见考点实例小结
CTF-PHP常见考点实例小结
|
SQL 存储 监控
NineData|如何快速完成MySQL数据的差异对比?
NineData 是一款功能强大的数据库对比工具,能够帮助企业追踪数据库的变化、发现问题并快速修复。相比其他工具,NineData 具有以下优势:即开即用、全面的数据源支持、完善的对比功能、快速高效、可视化界面、一键差异修复、免费使用、安全可靠。使用 NineData,您可以快速配置对比任务、查看对比结果、修复不一致内容、验证修复结果,并查看任务日志和监控指标。让数据库对比变得更简单、高效、安全。
3400 0