生产环境出现过多次mysql hang住,写操作的sql堵住的情况,这个时候使用kill来kill所有的连接,但是大部分时候连接kill 后处于freeing item状态,kill在这种场景下基本无效。
查看官方文档(以下大致翻译):(http://dev.mysql.com/doc/refman/5.5/en/kill.html)
kill执行后,一个线程特定的kill flag会被设置(THD::killed)。大多数情况下,线程消亡可能是需要花一点时间的,因为kill flag是以特定的间隔被检查的:
1、对于select,group by,order by语句,每读取完一块后检查kill flag。如果有kill flag,这个语句就会终止。
2、对于alter table,每次读取一块之前检查kill flag。如果有kill flag,这个语句就会终止,临时表也会被删除。
3、对于update,delete操作,每次读取完一块或每次更新/删除一行后 检查kill flag。
4、insert delayed操作,立即flush内存中已经插入的行,然后终止。
5、如果一个连接处于locked状态,table lock立即终止。
从文档上看,在mysql hang住的时候,使用kill似乎并不是最佳选择,因为mysql并不会立即kill掉这些session。下面试图从代码上理一下mysql kill的处理逻辑。(5.1.58,其它版本会有差异,不过大致的逻辑没啥变化,最起码5.1和5.5的官方文档对于kill的解释没怎么变化:))
... /* kills a thread and sends response SYNOPSIS sql_kill() thd Thread class id Thread id only_kill_query Should it kill the query or the connection */ void sql_kill(THD *thd, ulong id, bool only_kill_query) { uint error; if (!(error= kill_one_thread(thd, id, only_kill_query))) my_ok(thd); else my_error(error, MYF(0), id); } ... /** kill on thread. @param thd Thread class @param id Thread id @param only_kill_query Should it kill the query or the connection @note This is written such that we have a short lock on LOCK_thread_count */ uint kill_one_thread(THD *thd, ulong id, bool only_kill_query) { THD *tmp; ... if (tmp) { /* If we're SUPER, we can KILL anything, including system-threads. No further checks. KILLer: thd->security_ctx->user could in theory be NULL while we're still in "unauthenticated" state. This is a theoretical case (the code suggests this could happen, so we play it safe). KILLee: tmp->security_ctx->user will be NULL for system threads. We need to check so Jane Random User doesn't crash the server when trying to kill a) system threads or b) unauthenticated users' threads (Bug#43748). If user of both killer and killee are non-NULL, proceed with slayage if both are string-equal. */ if ((thd->security_ctx->master_access & SUPER_ACL) || thd->security_ctx->user_matches(tmp->security_ctx)) { tmp->awake(only_kill_query ? THD::KILL_QUERY : THD::KILL_CONNECTION); error=0; } ... void THD::awake(THD::killed_state state_to_set) { ... killed= state_to_set; ... close_active_vio(); ...
sql_parse.cc中sql_kill()调用kill_one_thread(), kill_one_thread()找到对应的threadid,调用awake(),awake()做了2件事:设置标签killed;关闭连接。至此,kill操作就返回了。
kill flag被检查的点:
update--- while (!(error=info.read_record(&info)) && !thd->killed) { delete--- while (!(error=info.read_record(&info)) && !thd->killed && ! thd->is_error())
每种操作都会在不同的策略确保kill操作的线程消亡掉。
从mysql kill处理的机制看,在mysql hang住的情况下,大量写操作被阻塞,使用kill并不能立即解决问题,如果想尽快让mysql恢复服务,最快的是主备切换,或直接重启mysql。
ps:一些链接
http://www.dbasquare.com/2012/05/15/why-do-threads-sometimes-stay-in-killed-state-in-mysql/
http://www.dbasquare.com/2012/04/04/how-to-selectively-kill-queries-in-mysql/
相关推荐
总结来说,MySQL的`kill`命令并不保证立即将线程或查询中断,而是提供了一个通知机制,使线程在合适的时机开始停止执行。在资源受限或线程处于不可中断状态时,`kill`命令可能不会立即见效,需要等待线程完成当前...
线程的终止并不总是立即生效。在某些情况下,线程可能会花费一些时间来完成当前操作并释放资源,因此在使用`KILL`命令后,你可能需要再次运行`SHOW PROCESSLIST`来确认线程是否已经真正终止。这是因为MySQL的线程...
但是,如果线程处于特定状态,例如等待锁或者执行长时间的事务或大查询,`KILL`命令可能不会立即生效。以下是一些导致`KILL`命令无法成功结束语句的常见原因: 1. **锁等待**:如果线程在等待行锁,即使`KILL QUERY...
6.7 存取控制,阶段1:连接证实 6.8 存取控制,阶段2:请求证实 6.9 权限更改何时生效 6.10 建立初始的 MySQL权限 6.11 向MySQL增加新用户权限 6.12 怎样设置口令 6.13 存取拒绝(Access ...
6.6 权限系统工作原理 6.7 存取控制,阶段1:连接证实 6.8 存取控制,阶段2:请求证实 6.9 权限更改何时生效 6.10 建立初始的 MySQL权限 6.11 向MySQL增加新用户权限 6.12 怎样设置...
# 5.4.5.1 不使用外键的理由 + 5.4.6 视图(Views) + 5.4.7 '--'作为一个 注解的开始 o 5.5 MySQL 遵循什么标准? o 5.6 怎样处理没有提交/回卷(COMMIT / ROLLBACK) * 6 MySQL 存取权限系统 o 6.1 权限系统做...
`KILL`命令并不是即时生效的,它会给目标线程设置一个终止标记,然后在线程在执行某些操作时才会检查这个标记并终止。例如,在SELECT、ORDER BY或GROUP BY操作中,在处理完一组行后检查;在ALTER TABLE过程中,每...
4. **使服务生效**: 更新`systemd`的服务列表,使其包含刚创建的`mysql.service`,通过运行`systemctl daemon-reload`命令。 5. **管理MySQL服务**: 一旦`mysql.service`被`systemd`识别,你就可以使用以下命令...
这里需要注意的是,不要使用 `kill -9 pid` 或 `pkill mysql` 等命令来关闭 MySQL,因为这些命令会强制关闭数据库,导致数据库碎片增加,容易使数据 crash。相反,我们可以使用 `service mysql stop` 命令来安全地...
当MySQL服务器不检查权限时,可以使用`skip-grant-tables`选项来启动它。这个选项使得你可以跳过权限表的验证,直接登录到MySQL服务器。在命令行中,输入以下命令启动MySQL: - 在Linux或Unix系统中: ``` sudo ...
找到对应的进程号后,可以使用`kill`命令结束进程。 #### 三、安装后测试与启动 在完成MySQL的安装后,需要进行一系列的测试来确保服务已经正确安装并启动。 ##### 3.1 检查MySQL服务 - **检查MySQL服务是否启动...
atlas + MySQL 读写分离没有生效** - 确认 Atlas 配置正确无误。 - 确保从服务器状态正常。 - 检查 Atlas 是否正确识别了读写分离策略。 **3. MySQL 主从同步常见异常及恢复方法** - **延迟问题:** 检查网络连接...
`mysql_kill()` - **功能**:终止指定的线程。 - **使用场景**:系统管理和异常处理,强制结束挂起或问题线程。 #### 31. `mysql_list_dbs()` - **功能**:列出匹配简单正则表达式的数据库名称。 - **使用场景**:...
1. 使用`SHOW PROCESSLIST`找出锁定的进程ID,然后执行`KILL id;`来终止该进程。 2. 直接使用`UNLOCK TABLES;`命令解锁当前用户锁定的所有表。 锁表操作如`LOCK TABLES tbl_name READ/WRITE;`可以在备份或维护时...
彻底卸载Linux下的MySQL需要进行多个步骤的操作,包括但不限于停止服务、卸载相关软件包、删除数据文件和配置文件、处理文件权限问题以及解决SELinux带来的问题。遵循上述步骤可以帮助您确保MySQL被完全卸载,并为...
如果遇到无法关闭MySQL服务器的问题,可以使用`ps aux | grep mysqld`找出MySQL进程的PID,然后用`sudo kill PID`命令结束该进程。 以上就是MAC系统上MySQL的安装、环境配置以及常见异常处理的详细步骤。记住,每个...
- 使用`kill`命令终止进程:`kill `cat /mysql-data-directory/hostname.pid``。 3. **重启MySQL服务,并跳过权限表**: - 通过添加`--skip-grant-tables`选项重启MySQL服务,以便能够无密码登录。 - 示例命令:...
- 保存并重启MySQL服务,以使更改生效。 2. **MySQL 8的持久化设置**: - MySQL 8引入了`PERSIST`关键字,可以直接在MySQL命令行中设置参数,并使其在重启后仍然有效: ``` SET PERSIST wait_timeout=120; SET...