这里简单记录下问题的原因,供参考。首先祝大家新年快乐,万事如意。
实际上这个问题是在nohup mysql < sql.sql &命令在nohup文件中记录了Terminal close -- query aborted。
重现
这个问题很容易重现如下,
nohup /newdata/mysql/mysql8023/install/bin/mysql -S'/newdata/mysql/mysql8023/tmp/mysql3329.sock' -e 'select sleep(10000) from dual' &
ps -ef|grep mysql 找到进程id
kill -1 25026(进程ID)
为什么报错
实际上这是mysql客户端收到了信号SIGHUP信号,然后mysql客户端程序捕获了这种信号做出的行为重定义。如下,
#ifndef _WIN32
signal(SIGINT, handle_ctrlc_signal); // Catch SIGINT to clean up
signal(SIGQUIT, mysql_end); // Catch SIGQUIT to clean up
signal(SIGHUP, handle_quit_signal); // Catch SIGHUP to clean up
#else
Terminal close的报错来自handle_quit_signal
void handle_quit_signal(int sig) {
const char *reason = "Terminal close";
而在测试的时候我们是kill 直接发的SIGHUP信号,用于模拟。
nohup失效?谁发出的SIGHUP?
这里不是用nohup屏蔽了SIGHUP信号吗,为什么在响应信号SIGHUP呢?实际上这信号和进程组有关,而mysql程序自己捕获了SIGHUP信号进行了重新处理,因此nohup屏蔽的目的失效了。而SIGHUP信号本生是比较复杂的,涉及到进程组很多概念,有兴趣的可以看看。那么这里谁发起了SIGHUP信号呢?一般有如下,
- 使用nohup启动,然后直接点击x号关闭SecureCRT
- 使用nohup启动,然后等SecureCRT终端超时
- 使用kill -1 发送了sighub信号
接下写一段简单的信号处理程序,只捕获SIGHUP,并且简单输出一下(叫GPT写就好了),
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
void handle_sighup(int signum) {
fprintf(stderr, "Received SIGHUP signal. Continuing execution...\n");
}
int main() {
// 注册自定义信号处理程序
signal(SIGHUP, handle_sighup);
// 无限循环,保持程序运行
while (1) {
fprintf(stderr, "Program is running...\n");
sleep(1);
}
return 0;
}
接下用用nohup ./a.out & 运行,我们分别测试kill -1 和 直接x号关闭SecureCRT,可以看到输出中都有如下,
image.png
连续2次收到了SIGHUP信号,一次是kill -1一次是x号关闭SecureCRT,说明nohup 失效了,如果我将程序改为收到信号exit退出则会终止程序。因此我们的mysql程序也是一样如果收到了SIGHUP信号,mysql程序是报Terminal close后退出。
如何观测
这个可以直接如下查看
/proc/25109/status
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000001000
SigIgn这一个位图,到底哪些信号呗忽略了。这里明显SIGHUP没有忽略,下面是忽略的,
SigIgn: 0000000000000001
网友评论