解决mysql锁表终极方法

本文提供了解决MySQL锁表问题的详细步骤,包括利用bash脚本批量杀死锁定进程,以及通过SQL语句和mysqladmin命令进行锁表管理。案例涵盖了从基本的单进程锁定处理到大规模锁定情况的解决方案,旨在提升数据库性能和稳定性。

很多时候!一不小心就锁表!这里讲解决锁表终极方法!

案例一

mysql>show processlist;

参看sql语句

一般少的话

mysql>kill thread_id;

就可以解决了

 

 

 

kill掉第一个锁表的进程, 依然没有改善. 既然不改善, 咱们就想办法将所有锁表的进程kill掉吧, 简单的脚本如下.

#!/bin/bash
mysql -u root -e "show processlist" | grep -i "Locked" >> locked_log.txt

for line in `cat locked_log.txt | awk '{print $1}'`
do
  
echo "kill $line;" >> kill_thread_id.sql
done

现在kill_thread_id.sql的内容像这个样子

kill 66402982;
kill 66402983;
kill 66402986;
kill 66402991;
.....

好了, 我们在mysql的shell中执行, 就可以把所有锁表的进程杀死了.

mysql>source kill_thread_id.sql

当然了, 也可以一行搞定
for id in `mysqladmin processlist | grep -i locked | awk '{print $1}'`
do
  
mysqladmin kill ${id}
done
 
案例二
 
如果大批量的操作能够通过一系列的select语句产生,那么理论上就能对这些结果批量处理。
但是mysql并没用提供eval这样的对结果集进行分析操作的功能。所以只能现将select结果保存到临时文件中,然后再执行临时文件中的指令。
具体过程如下:
mysql> SELECT concat('KILL ',id,';') FROM information_schema.processlist WHERE user='root';
+------------------------+
| concat('KILL ',id,';')
+------------------------+
| KILL 3101;            
| KILL 2946;            
+------------------------+
2 rows IN SET (0.00 sec)
mysql> SELECT concat('KILL ',id,';') FROM information_schema.processlist WHERE user='root' INTO OUTFILE '/tmp/a.txt';
Query OK, 2 rows affected (0.00 sec)
mysql> source /tmp/a.txt;
Query OK, 0 rows affected (0.00 sec)
 
 
案例三
 
MySQL + PHP的模式在大并发压力下经常会导致MySQL中存在大量僵死进程,导致服务挂死。为了自动干掉这些进程,弄了个脚本,放在服务器后台通过crontab自动执行。发现这样做了以后,的确很好的缓解了这个问题。把这个脚本发出来和大家Share.
根据自己的实际需要,做了一些修改:
SHELL脚本:mysqld_kill_sleep.sh
#!/bin/sh
mysql_pwd="root的密码"
mysqladmin_exec="/usr/local/bin/mysqladmin"
mysql_exec="/usr/local/bin/mysql"
mysql_timeout_dir="/tmp"
mysql_timeout_log="$mysql_timeout_dir/mysql_timeout.log"
mysql_kill_timeout_sh="$mysql_timeout_dir/mysql_kill_timeout.sh"
mysql_kill_timeout_log="$mysql_timeout_dir/mysql_kill_timeout.log"
$mysqladmin_exec -uroot -p"$mysql_pwd" processlist | awk '{ print $12 , $2 ,$4}' | grep -v Time | grep -v '|' | sort -rn > $mysql_timeout_log
awk '{if($1>30 && $3!="root") print "'""$mysql_exec""' -e " "/"" "kill",$2 "/"" " -uroot " "-p""/"""'""$mysql_pwd""'""/"" ";" }' $mysql_timeout_log > $mysql_kill_timeout_sh
echo "check start ...." >> $mysql_kill_timeout_log
echo `date` >> $mysql_kill_timeout_log
cat $mysql_kill_timeout_sh
把这个写到mysqld_kill_sleep.sh。然后chmod 0 mysqld_kill_sleep.sh,chmod u+rx mysqld_kill_sleep.sh,然后用root账户到cron里面运行即可,时间自己调整。
执行之后显示:
 
www# ./mysqld_kill_sleep.sh
/usr/local/bin/mysql -e "kill 27549" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27750" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27840" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27867" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27899" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27901" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27758" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27875" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27697" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27888" -uroot -p"mysql root的密码";
/usr/local/bin/mysql -e "kill 27861" -uroot -p"mysql root的密码";
如果确认没有问题了,把最后的cat修改为sh即可。

本人改写了下上面的脚本:
#!/bin/bash
mysql_pwd="密码"
mysql_exec="/usr/local/mysql/bin/mysql"
mysql_timeout_dir="/tmp"
mysql_kill_timeout_sh="$mysql_timeout_dir/mysql_kill_timeout.sh"
mysql_kill_timeout_log="$mysql_timeout_dir/mysql_kill_timeout.log"
$mysql_exec -uroot -p$mysql_pwd -e "show processlist" | grep -i "Locked" >> $mysql_kill_timeout_log
chmod 777 $mysql_kill_timeout_log
for line in `$mysql_kill_timeout_log  | awk '{print $1}'`
do
echo "$mysql_exec -uroot -p$mysql_pwd -e /"kill $line/"" >> $mysql_kill_timeout_sh
done
chmod 777 $mysql_kill_timeout_sh
cat $mysql_kill_timeout_sh
 
是不是很方便呢!
<think>嗯,用户想了解MySQL中删除记录的方法,这个问题很基础但也很重要。从引用内容看,用户提供的资料已经涵盖了DELETE命令、TRUNCATE命令以及关联删除等场景,我需要把这些信息整合成清晰的指导。 用户可能是个刚接触数据库的开发人员,或者需要处理数据清理任务的分析师。ta特意强调"方法",说明需要具体操作指导而非理论。值得注意的是引用[2]提到删除重复记录的场景,引用[3]涉及多关联删除,这些都属于实际工作中容易踩坑的点,需要重点说明。 安全方面要特别强调:1) WHERE子句的重要性 2) 备份的必要性 3) TRUNCATE的不可逆性。用户提供的引用[2][4]都提到了这些风险点,必须突出显示。 技术层面需要分层说明:先从最简单的单DELETE开始,再逐步展开到带条件的删除、多关联删除、清空的不同方案。特别要区分DELETE和TRUNCATE的本质差异,引用[4]说得很清楚——自增值重置和事务回滚特性是关键区别点。 对于关联删除这种复杂操作,用户提供的引用[3]示例有点抽象,我会改写一个更通用的案例。另外所有SQL示例都必须测试验证语法,避免误导用户。 最后考虑补充两个实用场景:重复数据处理和批量删除策略。虽然用户没直接问,但引用[2]提到了去重方法,这其实属于WHERE子句的高级应用,值得展开。 </think>以下是MySQL中删除记录的完整方法总结,结合关键操作场景和注意事项: ### 一、基础删除操作 1. **删除特定记录** ```sql DELETE FROM 名 WHERE 条件; ``` - 📌 示例:删除`users`中id为100的记录 ```sql DELETE FROM users WHERE id = 100; ``` - ⚠️ **必须包含WHERE子句**,否则全数据将被删除[^1][^3] 2. **清空整个** ```sql -- 方法1:DELETE (可回滚) DELETE FROM 名; -- 方法2:TRUNCATE (不可回滚) TRUNCATE TABLE 名; ``` - 🔥 核心区别: | 特性 | DELETE | TRUNCATE | |--------------|--------------------------|-------------------------| | 事务回滚 | 支持 (`ROLLBACK`) | **不支持** | | 自增ID | 保持原值 | **重置为初始值** | | 触发器 | 激活触发器 | 不激活触发器 | | 性能 | 逐行删除,较慢 | 销毁重建,极快 | | 日志 | 写日志 | **不写服务器log** | [^4] ### 二、高级删除技巧 1. **多关联删除** ```sql DELETE 别名1, 别名2 FROM 1 别名1 JOIN 2 别名2 ON 连接条件 WHERE 筛选条件; ``` - 📍 示例:删除学生"任波涛"的年龄记录 ```sql DELETE a FROM students s INNER JOIN ages a ON s.age_id = a.id WHERE s.name = '任波涛'; ``` [^3] 2. **删除重复记录**(保留一条) ```sql -- 步骤1:查询重复数据 SELECT email, COUNT(*) FROM users GROUP BY email HAVING COUNT(*) > 1; -- 步骤2:删除重复记录(保留最小ID) DELETE u1 FROM users u1 INNER JOIN users u2 WHERE u1.id > u2.id AND u1.email = u2.email; ``` 操作前**务必备份数据**[^2] ### 三、关键注意事项 1. **数据安全** - ✳️ 执行`DELETE`前先用`SELECT`验证条件: ```sql SELECT * FROM 名 WHERE 条件; -- 验证结果集 ``` - 💾 重大操作前备份数据: ```sql CREATE TABLE 名_backup SELECT * FROM 原; ``` 2. **性能优化** - 大删除使用分批操作: ```sql DELETE FROM 大 WHERE 条件 LIMIT 1000; -- 循环执行 ``` - 清空大时`TRUNCATE`比`DELETE`快10倍以上[^4] 3. **事务控制** ```sql START TRANSACTION; DELETE FROM ... WHERE ...; -- 测试删除 ROLLBACK; -- 回滚确认 -- COMMIT; -- 最终提交 ``` > 📌 **终极建议**:生产环境操作前**必须备份数据**并使用事务测试,尤其涉及关联删除或批量操作时[^2][^4]。 --- ### 相关问题 1. 如何恢复误删的MySQL数据? 2. `DELETE`和`DROP TABLE`的本质区别是什么? 3. 大数据删除导致有哪些解决方案? 4. 如何监控MySQL中的删除操作日志?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值