mysql事务未提交导致锁等待如何解决

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:

1、实验环境

Myql版本5.7.17-log

实验表结构

1
2
3
4
5
6
7
8
9
10
11
(root@localhost)[apex]> show  create  table  test;
+ -------+-----------------------------------------------------------------------------------------------------------------------------------+
Table Create  Table                                                                                                                      |
+ -------+-----------------------------------------------------------------------------------------------------------------------------------+
|test  |  CREATE  TABLE  `test` (
   `x`  int (11)  NOT  NULL ,
   `y`  int (11)  DEFAULT  NULL ,
   PRIMARY  KEY  (`x`)
)ENGINE=InnoDB  DEFAULT  CHARSET=gbk |
+ -------+-----------------------------------------------------------------------------------------------------------------------------------+
1 row inset (0.01 sec)

插入数据

1
2
3
(root@localhost)[apex]>  insert  into  test  values (1,1);
(root@localhost)[apex]>  insert  into  test  values (2,2);
(root@localhost)[apex]>  insert  into  test  values (3,3);

2、锁产生步骤

会话一:开启事务,更新数据,不提交

1
2
3
4
5
(root@localhost)[apex]>  begin ;
QueryOK, 0  rows  affected (0.00 sec)
(root@localhost)[apex]>  update  test  set  y=y+1  where  x=1;
QueryOK, 1 row affected (0.00 sec)
Rowsmatched: 1  Changed: 1  Warnings: 0

查看当前连接id号(线程id号)

1
2
3
4
5
6
7
(root@localhost)[apex]>  select  connection_id();
+ -----------------+
|connection_id() |
+ -----------------+
|               4 |
+ -----------------+
1 row inset (0.00 sec)

会话二:开启另一个事务,更新同一行数据,

1
2
3
4
5
(root@localhost)[apex]>  begin ;
QueryOK, 0  rows  affected (0.00 sec)
  
(root@localhost)[apex]>  update  test  set  y=y+1  where  x=1;
ERROR1205 (HY000): Lock wait timeout exceeded; try restarting  transaction

执行update test set操作时,会卡在那边,不执行,经过50秒后,会报错;

(上面的卡住现象,是由于锁,可以通过查看表information_schema.innodb_lock,获取锁的状态)

1
2
3
4
5
6
7
8
(root@localhost)[information_schema]>  select  from  information_schema.innodb_locks;
+ -----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
|lock_id         | lock_trx_id | lock_mode| lock_type | lock_table    | lock_index| lock_space | lock_page | lock_rec | lock_data |
+ -----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
|757082:3279:3:2 | 757082      | X         | RECORD    | `apex`.`test` |  PRIMARY     |      3279 |         3 |       2 | 1         |
|757081:3279:3:2 | 757081      | X         | RECORD    | `apex`.`test` |  PRIMARY     |      3279 |         3 |        2 | 1         |
+ -----------------+-------------+-----------+-----------+---------------+------------+------------+-----------+----------+-----------+
2 rowsin  set , 1 warning (0.00 sec)

查看当前连接id号(线程id号)

1
2
3
4
5
6
7
  (root@localhost) [apex]> selectconnection_id();
+ -----------------+
|connection_id() |
+ -----------------+
|               5 |
+ -----------------+
1 row inset (0.00 sec)

以上说的50秒,是系统参数innodb_lock_wait_timeout决定的

1
2
3
4
5
6
7
(root@localhost)[apex]> show variables  like  'innodb_lock_wait_timeout' ;
+ --------------------------+-------+
|Variable_name            | Value |
+ --------------------------+-------+
| innodb_lock_wait_timeout|  50  |
+ --------------------------+-------+
1 row inset (0.00 sec)

3mysql 如何查看未提交的事务

方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
(root@localhost)[performance_schema]>   SELECT  * FROMinformation_schema.INNODB_TRX\G
***************************1. row ***************************
                     trx_id: 756996
                  trx_state: RUNNING
                trx_started: 2017-05-08 15:08:07
      trx_requested_lock_id:  NULL
           trx_wait_started:  NULL
                 trx_weight: 3
        trx_mysql_thread_id: 4
                  trx_query:  NULL
        trx_operation_state:  NULL
          trx_tables_in_use: 0
          trx_tables_locked: 1
           trx_lock_structs: 2
      trx_lock_memory_bytes: 1136
            trx_rows_locked: 1
          trx_rows_modified: 1
    trx_concurrency_tickets: 0
        trx_isolation_level:  REPEATABLE  READ
          trx_unique_checks: 1
     trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
  trx_adaptive_hash_latched: 0
  trx_adaptive_hash_timeout: 0
           trx_is_read_only: 0
trx_autocommit_non_locking:0
1 row inset (0.00 sec)

通过以上可看出线程id一直未提交,事务开始的时间为2017-05-08 15:08:07

方法二:通过 show engine innodb status\G

其中有一段关于事务的描述

1
2
3
4
5
6
7
8
9
10
11
12
13
TRANSACTIONS
------------
Trx idcounter 756998
Purgedone  for  trx's n:o < 0 undo n:o < 0 state: running but idle
Historylist length 0
LIST OFTRANSACTIONS  FOR  EACH SESSION:
---TRANSACTION421519065333360, not started
0 lockstruct(s), heap  size  1136, 0 row lock(s)
---TRANSACTION421519065332448, not started
0 lockstruct(s), heap  size  1136, 0 row lock(s)
---TRANSACTION756996, ACTIVE 914 sec
2 lockstruct(s), heap  size  1136, 1 row lock(s), undo log entries 1
MySQL thread id 4, OS thread handle 140041791522560, query id25 localhost root

从以上也可以看出线程id号为4的事务一直未提交。

4、如何解决未提交的事务

方法一:如果能知道哪个用户在执行这个操作,让他提交一下(这种可能性很小)

方法二:kill掉这个线程id号,让事务回滚,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
(root@localhost)[information_schema]> show processlist;
+ ----+-----------------+------------------+--------------------+---------+------+------------------------+------------------+
| Id | User             | Host             | db                 | Command |  Time  | State                  | Info             |
+ ----+-----------------+------------------+--------------------+---------+------+------------------------+------------------+
|  1 | event_scheduler | localhost        |  NULL                | Daemon  | 4469 | Waiting  on  empty queue |  NULL              |
|  4 | root            | localhost        | apex               | Sleep   |  871|                        |  NULL              |
|  5 | root            | localhost        | apex               | Sleep   |   82|                        |  NULL              |
|  6 | root            | localhost        | information_schema | Query   |    0| starting               | showprocesslist |
|  7 | root            | 192.168.1.1:3708 |  NULL                | Sleep   | 3221 |                        |  NULL              |
+ ----+-----------------+------------------+--------------------+---------+------+------------------------+------------------+
5 rowsin  set  (0.00 sec)
  
(root@localhost)[information_schema]> kill 4;
QueryOK, 0  rows  affected (0.01 sec)

 


本文转自 corasql 51CTO博客,原文链接:http://blog.51cto.com/corasql/1923427,如需转载请自行联系原作者

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
3天前
|
SQL 安全 关系型数据库
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
事务是MySQL中一组不可分割的操作集合,确保所有操作要么全部成功,要么全部失败。本文利用SQL演示并总结了事务操作、事务四大特性、并发事务问题、事务隔离级别。
【MySQL基础篇】事务(事务操作、事务四大特性、并发事务问题、事务隔离级别)
|
9天前
|
SQL 关系型数据库 MySQL
MySQL进阶突击系列(04)事务隔离级别、AICD、CAP、BASE原则一直搞不懂? | 看这篇就够了
本文详细介绍了数据库事务的四大特性(AICD原则),包括原子性、隔离性、一致性和持久性,并深入探讨了事务并发问题与隔离级别。同时,文章还讲解了分布式系统中的CAP理论及其不可能三角关系,以及BASE原则在分布式系统设计中的应用。通过具体案例和图解,帮助读者理解事务处理的核心概念和最佳实践,为应对相关技术面试提供了全面的知识准备。
|
2月前
|
存储 SQL 关系型数据库
MySQL的事务隔离级别
【10月更文挑战第17天】MySQL的事务隔离级别
130 43
|
1月前
|
关系型数据库 MySQL
mysql事务特性
原子性:一个事务内的操作统一成功或失败 一致性:事务前后的数据总量不变 隔离性:事务与事务之间相互不影响 持久性:事务一旦提交发生的改变不可逆
|
1月前
|
关系型数据库 MySQL 数据库
MySQL事务隔离级别及默认隔离级别的设置
在数据库系统中,事务隔离级别是一个关键的概念,它决定了事务在并发执行时如何相互隔离。MySQL提供了四种事务隔离级别,每种级别都解决了不同的并发问题。本文将详细介绍这些隔离级别以及MySQL的默认隔离级别。
|
2月前
|
存储 关系型数据库 MySQL
优化 MySQL 的锁机制以提高并发性能
【10月更文挑战第16天】优化 MySQL 锁机制需要综合考虑多个因素,根据具体的应用场景和需求进行针对性的调整。通过不断地优化和改进,可以提高数据库的并发性能,提升系统的整体效率。
142 1
|
2月前
|
存储 关系型数据库 MySQL
MySQL锁,锁的到底是什么?
【10月更文挑战第16天】MySQL 锁锁定的是与数据和资源相关的对象,其目的是为了保证数据的一致性、避免冲突,并在并发环境下合理协调事务或操作的执行。理解锁的对象和意义对于优化数据库性能、处理并发问题至关重要。
100 0
|
2月前
|
关系型数据库 MySQL 数据库
mysql锁详解
通过理解并合理运用MySQL中的锁机制,开发者可以有效管理数据库并发访问,平衡性能与数据一致性需求。更多关于MySQL锁的深入探讨和最佳实践,请参考专业的数据库管理资源[[深入MySQL锁机制详解
62 0
|
6天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
23 3
|
6天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
28 3