MySQL中的死锁(deadlock)是指两个或多个事务在等待彼此释放资源,导致系统陷入僵局,无法继续执行。
自动死锁检测和回滚
MySQL的InnoDB存储引擎具有自动检测死锁并回滚某个事务的机制。InnoDB会选择回滚代价最小的事务,以解除死锁。这是默认行为。
捕获和处理死锁错误
在应用程序层面捕获死锁错误,并重试事务操作。可以通过捕获特定的错误代码(例如ER_LOCK_DEADLOCK
)来实现。
import mysql.connector
from mysql.connector import errorcode
def execute_transaction():
try:
conn = mysql.connector.connect(user='user', password='password', host='localhost', database='test')
cursor = conn.cursor()
for attempt in range(3): # 尝试重试3次
try:
cursor.execute("START TRANSACTION;")
# 执行SQL操作
cursor.execute("UPDATE table_name SET column1 = value1 WHERE condition;")
cursor.execute("UPDATE table_name SET column2 = value2 WHERE condition;")
conn.commit()
break # 如果成功则退出重试循环
except mysql.connector.Error as err:
if err.errno == errorcode.ER_LOCK_DEADLOCK:
print("Deadlock detected. Retrying...")
conn.rollback()
else:
raise
finally:
cursor.close()
conn.close()
execute_transaction()
手动解决步骤
查看表是否在使用
show open tables where in_use > 0 ;
若查询为空,表明没有表在使用。
不为空:
mysql> show open tables where in_use > 0 ;
+----------+-------+--------+-------------+
| Database | Table | In_use | Name_locked |
+----------+-------+--------+-------------+
| test | t | 1 | 0 |
+----------+-------+--------+-------------+
1 row in set (0.00 sec)
2. 查看InnoDB的状态,获取当前死锁的信息
SHOW ENGINE INNODB STATUS\G
这条命令会返回大量关于InnoDB的运行状态信息,其中包括最近发生的死锁的信息。在输出中查找“LATEST DETECTED DEADLOCK”字段,查看涉及死锁的事务及其持有的锁。
3.查看数据库当前的进程,看一下有无正在执行的慢SQL记录线程。
show processlist;
这条命令会显示当前所有连接的线程状态,包括每个线程正在执行的SQL语句、线程ID等信息。
4.终止
KILL <thread_id>;
终止指定的事务,释放其持有的锁。