写点什么

MySQL:一个奇怪的 hang 案例,java 基础程序代码

作者:MySQL神话
  • 2021 年 11 月 27 日
  • 本文字数:2582 字

    阅读完需:约 8 分钟

因此 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 状态的连接


然后做了 strace mysqld 的监听线程的操作,得到的结果如下:



正常的情况下这里应该是 poll 和 accept 然后开启新的(或者从缓存线程中拿一个)线程来处理交互信息了。但是这里我们可以清晰的看到出现了 SIGSTOP 信号。随即查看正 mysqld 线程的状态如下:



所有的线程都处于 T 状态下,这个状态正是由于信息 SIGSTOP 引起的。因此我们发一个 SIGCONT 信号给 mysqld 进程就好了如下:


kill -18 29676


推荐观看:Mysql精讲教程


三、关于信号


==========


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


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


  • 产生-->阻塞信号集


《一线大厂 Java 面试题解析+后端开发学习笔记+最新架构讲解视频+实战项目源码讲义》

【docs.qq.com/doc/DSmxTbFJ1cmN1R2dB】 完整内容开源分享


-->未决信号集-->信号递达-->信号处理方式


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


[root@mgr4 8277]# kill -l


  1. SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP

  2. SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1

  3. SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM

  4. SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP

  5. SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ

  6. SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR

  7. SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3

  8. SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8

  9. SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13

  10. SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12

  11. SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7

  12. SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2

  13. 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++)


{

最后

对于很多 Java 工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。


整理的这些资料希望对 Java 开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。


再分享一波我的 Java 面试真题+视频学习详解+技能进阶书籍



本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

用户头像

MySQL神话

关注

还未添加个人签名 2021.11.12 加入

还未添加个人简介

评论

发布
暂无评论
MySQL:一个奇怪的hang案例,java基础程序代码