解决mysql死锁错误 SQLSTATE【HY000】 G

SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction

在PHP调试时 提交事务触发异常后没有执行回滚导致mysql死锁,以致后续请求更新不了数据

问题原因

在mysql中事务a执行修改数据,比如: update table set a=1 where id=1;此时事务并未进行提交也没有回滚,然后事务B开始运行,修改同一条数据: update table set a=2 where id=1;

此时b一直等待a释放锁直到超时,超过设置的超时时间后会产生报错

问题出现环境:

1、在同一事务内先后对同一条数据进行插入和更新操作;

2、多台服务器操作同一数据库;

3、瞬时出现高并发现象;

4、语句中没有执行commit,也没有rollback就return退出了

比如参数检查不通过,直接return错误信息,导致回滚不能执行

如以下代码先执行了更新操作,后面出错又直接返回,导致没有执行rollback,对于这种操作return前一点要回滚,或者抛出异常统一扑捉后返回错误信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
php复制代码$this->startTrans();
try {


$user = new User();
$user->where('id',$userId)->update(['realname'=>$parentName]);

$existId = $this->where('class_id',$classId)->where('student_number',$number)->find();
if ($existId)
return ['data' => '', 'code' => 300, 'msg' => '学号重复'];
$this->commit();

} catch (Throwable $e) {
$this->rollback();
return ['data' => '', 'code' => 20102, 'msg' => $e->getMessage()];
}

异常信息

SQLSTATE[HY000]: General error: 1205 Lock wait timeout exceeded; try restarting transaction

)

解决

1、通过下面语句查找到为提交事务的数据,kill此线程即可。

1
csharp复制代码select * from information_schema.innodb_trx

)

trx_mysql_thread_id 即为该进程

1
bash复制代码kill 1544

相关排查语句

show full processlist ## 当前连接的线程

select * from information_schema.innodb_trx ## 当前运行的所有事务

select * from information_schema.innodb_locks ## 当前出现的锁

select * from information_schema.innodb_lock_waits ## 锁等待的对应关系

字段详细信息

desc information_schema.innodb_locks;

Field Type Null Key Default Remark

lock_id varchar(81) NO 锁ID

lock_trx_id varchar(18) NO 拥有锁的事务ID

lock_mode varchar(32) NO 锁模式

lock_type varchar(32) NO 锁类型

lock_table varchar(1024) NO 被锁的表

lock_index varchar(1024) YES NULL 被锁的索引

lock_space bigint(21) unsigned YES NULL 被锁的表空间号

lock_page bigint(21) unsigned YES NULL 被锁的页号

lock_rec bigint(21) unsigned YES NULL 被锁的记录号

lock_data varchar(8192) YES NULL 被锁的数据

desc information_schema.innodb_lock_waits

Field Type Null Key Default Remark

requesting_trx_id varchar(18) NO 请求锁的事务ID

requested_lock_id varchar(81) NO 请求锁的锁ID

blocking_trx_id varchar(18) NO 当前拥有锁的事务ID

blocking_lock_id varchar(81) NO 当前拥有锁的锁ID

desc information_schema.innodb_trx ;

Field Type Null Key Default Extra Remark

trx_id varchar(18) NO 事务ID

trx_state varchar(13) NO 事务状态:

trx_started datetime NO 0000-00-00 00:00:00 事务开始时间;

trx_requested_lock_id varchar(81) YES NULL innodb_locks.lock_id

trx_wait_started datetime YES NULL 事务开始等待的时间

trx_weight bigint(21) unsigned NO 0 #

trx_mysql_thread_id bigint(21) unsigned NO 0 事务线程ID

trx_query varchar(1024) YES NULL 具体SQL语句

trx_operation_state varchar(64) YES NULL 事务当前操作状态

trx_tables_in_use bigint(21) unsigned NO 0 事务中有多少个表被使用

trx_tables_locked bigint(21) unsigned NO 0 事务拥有多少个锁

trx_lock_structs bigint(21) unsigned NO 0 #

trx_lock_memory_bytes bigint(21) unsigned NO 0 事务锁住的内存大小(B)

trx_rows_locked bigint(21) unsigned NO 0 事务锁住的行数

trx_rows_modified bigint(21) unsigned NO 0 事务更改的行数

trx_concurrency_tickets bigint(21) unsigned NO 0 事务并发票数

trx_isolation_level varchar(16) NO 事务隔离级别

trx_unique_checks int(1) NO 0 是否唯一性检查

trx_foreign_key_checks int(1) NO 0 是否外键检查

trx_last_foreign_key_error varchar(256) YES NULL 最后的外键错误

trx_adaptive_hash_latched int(1) NO 0 #

trx_adaptive_hash_timeout bigint(21) unsigned NO 0 #3

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%