首页 > 解决方案 > mySQL innoDB 上无休止的死锁情况

问题描述

这是我最近在我的 Google Cloud Platform 帐户的虚拟机中托管的 MySQLdb 5.7(带有 innoDB 引擎)中遇到的一个问题。突然,我的数据库进入一个名为“用户”的特定表上的每个事务(例如登录)都失败(无限超时)的状态。我犯了这个错误:pymysql.err.OperationalError: (1213, 'Deadlock found when trying to get lock; try restarting transaction'

好吧,基本上我试图找出是否可以从这个圈出的情况中自动恢复。我在 MySQL 的网站上读到,默认情况下执行回滚到最后一个事务,但为什么在我的情况下没有发生这种情况?在这种情况下呆了很长时间后,我不得不重新启动 MySQL 服务器。

我需要一些关于如何调查它或采取行动不再面对它的指示,因为它是一个有客户的实时数据库。

标签: mysqlgoogle-cloud-platformgoogle-compute-enginedatabase-deadlocks

解决方案


下面是我们检测到无限死锁的登录过程的存储过程。

CREATE DEFINER=`root`@`%` PROCEDURE `login`(
    in email1 varchar(45), 
    in password1 varchar(256),
    in lastlogin datetime, 
    out s INT(1)
    )
    BEGIN
    DECLARE p INT(11);
    DECLARE counter TINYINT;

      IF EXISTS (select * from user where user.email = email1 AND user.password = password1 AND user.locked = 0 AND user.inactive = 0) THEN
          SELECT id INTO p FROM user WHERE user.email = email1;
          SELECT user.id, user.id_user_roles, user.id_user_settings, user.first_name, user.last_name, UserRoles.description
          FROM user
          LEFT JOIN UserRoles
          ON user.id_user_roles = UserRoles.id_user_roles WHERE user.id = p;
          UPDATE user SET last_login = lastlogin WHERE user.id = p;
          INSERT INTO login_info (id_user, timestamp)
          VALUES (p, lastlogin);
          SET s = 1; 
      ELSE
          SELECT login_error_times INTO counter FROM user WHERE email = email1;
          IF (counter < 3) THEN
             SET counter = counter + 1;
             UPDATE user
             SET login_error_times = counter
             WHERE user.email = email1;
             SET s = 0; 
          ELSE
             UPDATE user
             SET locked = 1
             WHERE user.email = email1;
             SET s = 2;
          END IF;   
      END IF;
    END

推荐阅读