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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 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 :)

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
17天前
|
SQL 关系型数据库 MySQL
MySQL事务日志-Undo Log工作原理分析
事务的持久性是交由Redo Log来保证,原子性则是交由Undo Log来保证。如果事务中的SQL执行到一半出现错误,需要把前面已经执行过的SQL撤销以达到原子性的目的,这个过程也叫做"回滚",所以Undo Log也叫回滚日志。
MySQL事务日志-Undo Log工作原理分析
|
11天前
|
安全 关系型数据库 MySQL
CentOS7仅安装部署MySQL80客户端
通过上述步骤,你可以在CentOS 7上成功安装并配置MySQL 8.0客户端。这个过程确保你能够使用MySQL客户端工具连接和管理远程的MySQL数据库,而不需要在本地安装MySQL服务器。定期更新MySQL客户端可以确保你使用的是最新的功能和安全修复。
83 16
|
1月前
|
SQL 关系型数据库 MySQL
MySQL 窗口函数详解:分析性查询的强大工具
MySQL 窗口函数从 8.0 版本开始支持,提供了一种灵活的方式处理 SQL 查询中的数据。无需分组即可对行集进行分析,常用于计算排名、累计和、移动平均值等。基本语法包括 `function_name([arguments]) OVER ([PARTITION BY columns] [ORDER BY columns] [frame_clause])`,常见函数有 `ROW_NUMBER()`, `RANK()`, `DENSE_RANK()`, `SUM()`, `AVG()` 等。窗口框架定义了计算聚合值时应包含的行。适用于复杂数据操作和分析报告。
75 11
|
28天前
|
SQL 关系型数据库 MySQL
MySQL操作利器大公开!这几款客户端让你事半功倍
本文介绍了多种MySQL数据库管理工具,包括命令行工具、图形化用户界面(GUI)工具和Web界面工具。主要工具有: 1. **Navicat for MySQL**:功能强大,支持多种数据库管理任务,但需付费。 2. **DBeaver**:开源免费,支持多种数据库,安装包较大。 3. **MySQL Workbench**:官方提供的图形化工具,适合MySQL全家桶用户。 4. **HeidiSQL**:轻量级Windows客户端,简单易用。 5. **phpMyAdmin**:基于Web的管理工具,易于部署和使用。 6. **SQLyog**:适用于Windows,功能丰富,有免费
71 3
|
2月前
|
关系型数据库 MySQL 网络安全
DBeaver连接MySQL提示Access denied for user ‘‘@‘ip‘ (using password: YES)
“Access denied for user ''@'ip' (using password: YES)”错误通常与MySQL用户权限配置或网络设置有关。通过检查并正确配置用户名和密码、用户权限、MySQL配置文件及防火墙设置,可以有效解决此问题。希望本文能帮助您成功连接MySQL数据库。
215 4
|
2月前
|
安全 关系型数据库 MySQL
【赵渝强老师】MySQL的连接方式
本文介绍了MySQL数据库服务器启动后的三种连接方式:本地连接、远程连接和安全连接。详细步骤包括使用root用户登录、修改密码、创建新用户、授权及配置SSL等。并附有视频讲解,帮助读者更好地理解和操作。
353 1
|
3月前
|
SQL Java 关系型数据库
java连接mysql查询数据(基础版,无框架)
【10月更文挑战第12天】该示例展示了如何使用Java通过JDBC连接MySQL数据库并查询数据。首先在项目中引入`mysql-connector-java`依赖,然后通过`JdbcUtil`类中的`main`方法实现数据库连接、执行SQL查询及结果处理,最后关闭相关资源。
317 6
|
3月前
|
存储 关系型数据库 MySQL
基于案例分析 MySQL 权限认证中的具体优先原则
【10月更文挑战第26天】本文通过具体案例分析了MySQL权限认证中的优先原则,包括全局权限、数据库级别权限和表级别权限的设置与优先级。全局权限优先于数据库级别权限,后者又优先于表级别权限。在权限冲突时,更严格的权限将被优先执行,确保数据库的安全性与资源合理分配。
|
3月前
|
SQL JavaScript 关系型数据库
node博客小项目:接口开发、连接mysql数据库
【10月更文挑战第14天】node博客小项目:接口开发、连接mysql数据库
|
3月前
|
Java 关系型数据库 MySQL
【编程基础知识】Eclipse连接MySQL 8.0时的JDK版本和驱动问题全解析
本文详细解析了在使用Eclipse连接MySQL 8.0时常见的JDK版本不兼容、驱动类错误和时区设置问题,并提供了清晰的解决方案。通过正确配置JDK版本、选择合适的驱动类和设置时区,确保Java应用能够顺利连接MySQL 8.0。
336 1