存储过程挂起

时间:2016-11-22 18:05:34

标签: mysql stored-procedures hang

存储过程会不时挂起。有什么建议吗?

BEGIN
DECLARE bookId int;

SELECT IFNULL(id,0) INTO bookId FROM products
    WHERE 
        isbn=p_isbn
    and stoc>0 
    and status='vizibil' 
    and pret_ron=(SELECT MAX(pret_ron) FROM products
    WHERE isbn=p_isbn
                  and stoc>0 
                  and status='vizibil')
    ORDER BY stoc DESC

LIMIT 0,1;

IF bookId>0 THEN
UPDATE products SET afisat='nu' WHERE isbn=p_isbn;
UPDATE products SET afisat='da' WHERE id=bookId;
SELECT bookId INTO obookId;
ELSE

SELECT id INTO bookId FROM products
    WHERE 
        isbn=p_isbn 
    and stoc=0 
    and status='vizibil' 
    and pret_ron=(SELECT MAX(pret_ron) FROM products
                    WHERE isbn=p_isbn 
                      and stoc=0 
                      and status='vizibil')
LIMIT 0,1;
UPDATE products SET afisat='nu' WHERE isbn=p_isbn;
UPDATE products SET afisat='da' WHERE id=bookId;
SELECT bookId INTO obookId;
END IF;

END

当它挂起时,它会在: | 23970842 |用户名| sqlhost:54264 |数据库|查询| 65 |发送数据| SELECT IFNULL(id,0)INTO bookId FROM products         哪里                 isbn = NAME_CONST(' p_isbn',_ utf8' 973-679-50 | 0.000 |

| 1133136 |用户名| sqlhost:52466 |数据库_emindb |查询| 18694 |发送数据| SELECT IFNULL(id,0)INTO bookId FROM products         哪里                 isbn = NAME_CONST(' p_isbn',_ utf8' 606-92266- | 0.000 |

1 个答案:

答案 0 :(得分:1)

首先,我想提一下Percona toolkit,它非常适合调试死锁和挂起事务。其次,我猜想在挂起时,有多个线程执行相同的过程。我们需要知道的是,在挂起时获取了哪些锁。 MySQL命令SHOW INNODB STATUS为您提供详细信息。在下一个'挂起',运行此命令。

我几乎忘记提及innotop工具,它类似但更好:https://github.com/innotop/innotop

接下来,我假设你是InnoDB引擎。在这种情况下,REPEATABLE READ的默认事务隔离级别可能因为范围锁定而过高,您可以考虑尝试对程序主体执行READ COMMITTED(SET在开头提交READ COMMITTED并在结束时返回REPEATABLE READ)。

最后,也许最重要的是,请注意您的过程使用相同的p_isbn值在同一个表上执行SELECT和UPDATE(以混合顺序)。想象一下,如果此过程同时运行 - 这是一个完美的死锁设置。