当mysql 遇到 ctrl+c
目的
为了理解MySQL在执行大SQL时,对执行CTRL+C产生的疑惑,本文通过实验测试和源码分析两个方面,对MySQL处理CTRL+C的详细过程进行分析和讲解,从而解除DBA及开发人员对CTRL+C的误解。
测试
首先,基于线上数据库版本,分别使用MySQL客户端版本5.5.20和5.0.77进行实验测试,一方面排除不同数据库客户端版本造成的差异,另一方面,深入了解不同版本执行CTRL+C产生的差异。
MySQL客户端5.5.20
使用MySQL客户端5.5.20在Session1中执行select sleep(100)语句,在Session2中执行show processlist语句;然后在Session1中执行CTRL+C,在Session中执行show processlist语句,查看当前连接的线程。执行的图如下所示:
Session1:
|
mysql> select sleep(100); Ctrl-C -- sending "KILL QUERY 153779" to server ... Ctrl-C -- query aborted. ERROR 2013 (HY000): Lost connection to MySQL server during query |
Session2:
|
mysql> show processlist; mysql> show processlist; |
从以上结果来看,Session1中执行select操作时,Session2中可以查看该连接正在执行,在Session1中执行CTRL+C时,客户端向服务器端发送KILL QUERY 命令,并且连接关闭。在Session2中可以看到执行select的连接已经关闭。
MySQL客户端5.0.77
使用客户端5.0.77执行同样的操作,执行CTRL+C后,观察执行的差异性。具体如下表中所示:
Session1:
|
mysql> select sleep(100); Query aborted by Ctrl+C +------------+ | sleep(100) | +------------+ | 1 | +------------+ |
Session2:
|
mysql> show processlist; mysql> show processlist; |
从以上结果可知,Session1上执行select时,Session2中建立查询连接;在Session1中执行CTRL+C时,显示Query被终止,并且返回执行的错误结果。在Session2中可知,连接的线程仍然存在,但是Query被终止,只是保持连接。
源码分析
为了更进一步对以上测试进行确认,查看MySQL源码进行进一步的求证,同样基于MySQL的5.5.20和5.0.77两个版本进行验证。具体如下:
MySQL 5.5.20源码
MySQL客户端主函数main中,信号函数在源码文件client/mysql.cc:1163,源码如下所示:
|
signal(SIGINT, handle_sigint); // Catch SIGINT to clean up |
信号处理函数handle_sigint在client/mysql.cc:1291,源码如下所示:
|
sig_handler handle_sigint(int sig) { char kill_buffer[40]; MYSQL *kill_mysql= NULL; /* terminate if no query being executed, or we already tried interrupting */ if (!executing_query || (interrupted_query == 2)) { tee_fprintf(stdout, "Ctrl-C -- exit!\n"); goto err; } kill_mysql= mysql_init(kill_mysql); if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password, "", opt_mysql_port, opt_mysql_unix_port,0)) { tee_fprintf(stdout, "Ctrl-C -- sorry, cannot connect to server to kill query, giving up ...\n"); goto err; } interrupted_query++; /* mysqld < 5 does not understand KILL QUERY, skip to KILL CONNECTION */ if ((interrupted_query == 1) && (mysql_get_server_version(&mysql) < 50000)) interrupted_query= 2; /* kill_buffer is always big enough because max length of %lu is 15 */ sprintf(kill_buffer, "KILL %s%lu", (interrupted_query == 1) ? "QUERY " : "", mysql_thread_id(&mysql)); tee_fprintf(stdout, "Ctrl-C -- sending \"%s\" to server ...\n", kill_buffer); mysql_real_query(kill_mysql, kill_buffer, (uint) strlen(kill_buffer)); mysql_close(kill_mysql); tee_fprintf(stdout, "Ctrl-C -- query aborted.\n"); return; err: #ifdef _WIN32 mysql_thread_end(); return; #else mysql_end(sig); #endif } |
从以上源码可知,MySQL客户端在捕获信号后,将KILL QUERY 命令发送到服务器端执行,从而将Query处理KILL。
MySQL 5.0.77源码
MySQL客户端主函数main中,信号函数在源码文件client/mysql.cc:1150。源码如下所示:
|
signal(SIGINT, mysql_sigint); // Catch SIGINT to clean up |
信号处理函数mysql_sigint在源码文件client/mysql.cc:1214,源码如下所示:
|
sig_handler mysql_sigint(int sig) { char kill_buffer[40]; MYSQL *kill_mysql= NULL; /* terminate if no query being executed, or we already tried interrupting */ if (!executing_query || interrupted_query++) goto err; kill_mysql= mysql_init(kill_mysql); if (!mysql_real_connect(kill_mysql,current_host, current_user, opt_password, "", opt_mysql_port, opt_mysql_unix_port,0)) goto err; /* kill_buffer is always big enough because max length of %lu is 15 */ sprintf(kill_buffer, "KILL /*!50000 QUERY */ %lu", mysql_thread_id(&mysql)); mysql_real_query(kill_mysql, kill_buffer, strlen(kill_buffer)); mysql_close(kill_mysql); tee_fprintf(stdout, "Query aborted by Ctrl+C\n"); return; err: #ifdef _WIN32 mysql_thread_end(); return; #else mysql_end(sig); #endif } |
通过以上源码可知,MySQL客户端捕获信号后,向服务器端发送KILL /*!50000 QUERY */ 命令并执行,从而将Query处理kill。
基于以上两个版本处理的源码可知,MySQL客户端一定会捕获CTRL+C信号,并对该信号进行处理。而对于不同版本的客户端,由于发送命令的不同,导致MySQL服务器端执行结果有所不同。
结论
通过以上测试和源码分析可知,MySQL客户端肯定会捕获CTRL+C信号,并对信号进行处理。不同的是,在MySQL 5.5.20版本的客户端中执行时,服务器端执行KILL QUERY 命令,将QUERY KILL掉,并将连接关闭。而对MySQL 5.0.77客户端中执行时,服务器端执行KILL /*!50000 QUERY */ 命令,KILL掉QUERY,但保持连接。
此外,对于update、delete数据更新操作[1],CTRL+C会将执行的操作标记为KILLED状态,然后执行回滚操作。因此,不会因为CTRL+C操作,导致数据变脏。
当mysql 遇到 ctrl+c的更多相关文章
- [转]Navicat for MySQL快捷键
Navicat for MySQL快捷键 ctrl+q 打开查询窗口 ctrl+/ 注释sql语句 ctrl+shift +/ 解除注释 ctrl+r 运行查询窗口的sql语句 ctrl+shift+ ...
- centos 7.0 编译 安装mysql 5.6.22 过程 已完成~ 成功~ 撒花~
mysql 下载目录/usr/local/srcmysql 解压目录 /usr/local/bin/mysql GitHub https://github.com/mysql/mysql-server ...
- docker上配置mysql主从复制
1.在docker上启动2台mysql容器:(这里3306为主,3307为从) docker run -d -e MYSQL_ROOT_PASSWORD=123456 -p 3306:3306 - ...
- 二进制安装mysql
1.1 MySQL安装介绍 mysql软件下载地址信息: www.mysql.com mirrors.sohu.com mysql软件下载完毕后,查看mysql解压后目录文件大小 1.下载解压my ...
- 【大数据应用技术】作业九|安装关系型数据库MySQL 安装大数据处理框架Hadoop
本次作业的要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/3161 1.安装MySql 按ctrl+alt+t打开终端窗口,安 ...
- docker部署项目: centos+python+redis+mysql+uwsgi+nginx
一.Centos7安装docker 1.1 环境配置 先测试是否下载了docker:查看镜像:docker images没有下载,就依次执行以下环境的安装 ①curl http://mirrors.a ...
- Centos5.8 安装 MySQL5.6.19
查看已经安装的mysql: sudo yum list installed |grep mysql 删除 sudo yum remove mysql 安装 sudo rpm -ivh MySQL-se ...
- 原创:LNMP架构部署个人博客网站 禁止转载复制
nginx编译安装步骤 ①. 检查软件安装的系统环境 cat /etc/redhat-release uname -r ②. 安装nginx的依赖包(pcre-devel openssl-devel) ...
- Docker 安装mysql8.0
1. 下载Mysql的Docker镜像: $ docker search mysql (搜索mysql镜像) $ docker pull mysql (下载mysql镜像,默认最新版本) 2. 运行镜 ...
随机推荐
- 【题解】Oulipo
题目描述 给出两个串S1,S2(只有大写字母),求S1在S2中出现了多少次. 例如:S1=“ABA”,S2=“ABABA”,答案为2. 输入T组数据,对每组数据输出结果. 输入输出格式 输入格式 第一 ...
- 2017-2018 ACM-ICPC, Asia Daejeon Regional Contest C(记忆化搜索)
C题 Problem C Game Map 思路: 之前暴力搜索写了好几发,一直超时,后面看其他人的题解发现要用记忆化搜索..直接暴力搜的话有太多重 复的计算. dist u 表示以u 为起点所能走的 ...
- (转)CS0016: 未能写入输出文件
转自:http://www.pageadmin.net/article/20130305/537.html 编译错误 说明: 在编译向该请求提供服务所需资源的过程中出现错误.请检查下列特定错误详细信息 ...
- caffe多任务、多标签
解决的目标问题:多分类问题,比如车辆的外形和颜色,苹果的大小和颜色:多任务:车牌角点的定位和车牌的颜色.定位在技术上属于回归,车牌颜色判断则属于分类. 技术点 caffe默认是单输入任务单标签的,也就 ...
- bzoj1098 办公楼
Description FGD开办了一家电话公司.他雇用了N个职员,给了每个职员一部手机.每个职员的手机里都存储有一些同事的电话号码.由于FGD的公司规模不断扩大,旧的办公楼已经显得十分狭窄,FGD决 ...
- codeforces906 D
题目链接:http://codeforces.com/contest/906/problem/D 题意: 给你n个数,再给你l~r,求%m 题解: 一开始不会 后来查到了欧拉降幂定理: 然后就会了 这 ...
- 【poj3415】 Common Substrings
http://poj.org/problem?id=3415 (题目链接) 题意 给定两个字符串 A 和 B,求长度不小于 k 的公共子串的个数(可以相同). Solution 后缀数组论文题... ...
- bzoj 3195 [Jxoi2012]奇怪的道路
3195: [Jxoi2012]奇怪的道路 Description 小宇从历史书上了解到一个古老的文明.这个文明在各个方面高度发达,交通方面也不例外.考古学家已经知道,这个文明在全盛时期有n座城市,编 ...
- LVS NAT/DR
LVS介绍:http://www.linuxvirtualserver.org/zh/lvs3.html DR 工作流: HOST发送服务请求报文(源IP为HOST IP,目的IP为VSIP) Gen ...
- T分布在医药领域应用-python建模
sklearn实战-乳腺癌细胞数据挖掘 https://study.163.com/course/introduction.htm?courseId=1005269003&utm_campai ...