• MySQL的ERROR 1205错误分析


    一、错误发生及原因猜测

    1、错误发生

    在删除 t_user 表的一条数据时,Navicat 发生长时间的无响应,然后弹出一个对话框,提示:ERROR 1205: Lock wait timeout exceeded; try restarting transaction

    关闭对话框之后,数据并没有被删除。

    2、原因猜测

    根据错误信息可以知道,是因为锁等待超时导致的错误。那么具体到底是什么原因。

    我们知道,InnoDB 引擎是支持事务的。

    在使用 begin 或 start transaction 开启事务,进行更新、删除时,会对被操作的行加行级锁。

    如果这个事务没有提交,而其他的事务对同一行也进行了更新、删除操作,那么这个事务是不能成功的,至于会不会出现上面的错误,还不确定。

    二、错误重现

     1、演示环境

    操作系统

    Windows 7 x64

    MySQL版本

    MySQL Community Server (GPL) 5.5.56

    执行未提交事务的用户

    system

    查看会话、执行删除操作的用户

    root

    数据库

    test

    t_user

     

     

     

     

     

     

     

     1 mysql> select * from t_user;
     2 +----+----------+
     3 | id | username |
     4 +----+----------+
     5 |  1 | a1       |
     6 |  2 | a2       |
     7 |  3 | a3       |
     8 |  4 | a4       |
     9 |  5 | a5       |
    10 |  6 | a6       |
    11 +----+----------+

     

    2、错误重现

    使用 A窗口 更新 id = 2 的数据

    1 mysql> begin;
    2 Query OK, 0 rows affected (0.00 sec)
    3 
    4 mysql> update t_user set username = 'b1' where id = 2;
    5 Query OK, 1 row affected (0.00 sec)
    6 Rows matched: 1  Changed: 1  Warnings: 0

    在没有提交的情况下,使用 C窗口 查看当前事务,我们可以看到事务的 状态(trx_state)、行锁数(trx_rows_locked)、修改数据行数(trx_rows_modified) 等信息

     1 mysql> select * from innodb_trxG;
     2 *************************** 1. row ***************************
     3                     trx_id: A023
     4                  trx_state: RUNNING
     5                trx_started: 2018-03-11 15:30:19
     6      trx_requested_lock_id: NULL
     7           trx_wait_started: NULL
     8                 trx_weight: 3
     9        trx_mysql_thread_id: 5
    10                  trx_query: NULL
    11        trx_operation_state: NULL
    12          trx_tables_in_use: 0
    13          trx_tables_locked: 0
    14           trx_lock_structs: 2
    15      trx_lock_memory_bytes: 376
    16            trx_rows_locked: 1
    17          trx_rows_modified: 1
    18    trx_concurrency_tickets: 0
    19        trx_isolation_level: REPEATABLE READ
    20          trx_unique_checks: 1
    21     trx_foreign_key_checks: 1
    22 trx_last_foreign_key_error: NULL
    23  trx_adaptive_hash_latched: 0
    24  trx_adaptive_hash_timeout: 10000

    此时再使用 B窗口 删除t_user表的数据,在删除 id = 2 的数据时,发现事务被阻塞。我们在 C窗口 查看 processlist、事务以及锁等待 情况

    1 mysql> show full processlist;

    1 mysql> select * from innodb_trxG;

    1 mysql> select * from INNODB_LOCK_WAITSG;

    当事务超时后出现1205的错误

    此时,我们再查看一下 processlist、事务以及锁等待 情况,发现刚才处于 等待状态 的事务、process和锁等待已经没有了

    1 mysql> show full processlist;
    2 mysql> select * from INNODB_LOCK_WAITSG;
    3 mysql> select * from innodb_trxG;

    此时把 A窗口rollback 回来

    mysql> rollback;

    再查看一下processlist、事务以及锁等待情况

    由此可以确定:1205 的错误是因为未提交事务对数据加了行级锁,当前事务获取同一数据行级锁超时导致的

    三、解决方案

    我们可以使用 show full processlist 查看未提交事务的连接的 id

    可以看到这个连接的id是5

    如果可以确定不是很重要的事务,我们可以使用kill命令断开这个连接。

    mysql> kill 5;

     如果不确定的话,还是需要沟通一下如何安全处理。

  • 相关阅读:
    SQL一条语句统计记录总数及各状态数
    火狐登录国际账户
    HTML基础笔记
    增强for、lambda for、stream 遍历List 结束方法 or 跳过循环本次循环
    nginx
    前端问题总结
    Node.js
    Actuator
    ssh免密登录实现及Python实现
    【Mac渗透测试】之SQL注入Demo
  • 原文地址:https://www.cnblogs.com/xugf/p/8696508.html
Copyright © 2020-2023  润新知