mysql:存储过程内部死锁

问题描述 投票:0回答:1

我有这样的存储过程:

DECLARE err_code CHAR(5) DEFAULT '00000';
DECLARE msg TEXT;
DECLARE CONTINUE HANDLER FOR SQLEXCEPTION
BEGIN
    GET DIAGNOSTICS CONDITION 1
    err_code = RETURNED_SQLSTATE, msg = MESSAGE_TEXT;
END;

START TRANSACTION;
INSERT INTO tableA .....;
INSERT INTO tableB .....;

SELECT updateJournal(id) INTO x;

IF err_code != '00000' THEN
   ROLLBACK;
   INSERT INTO log (msg) VALUES (msg);
ELSE
   COMMIT;
END IF;
CREATE FUNCTION updateJournal(orderId INT) return int BEGIN INSERT INTO tableC ....; UPDATE tabled ....;

RETURN 1; END

有时我收到消息错误“尝试获取锁定时发现死锁;尝试重新启动事务” 存储过程已回滚,但函数

updateJournal
仍然有效(tableC 已插入,tableD 已更新), 谁能解释为什么存储过程回滚并出现死锁错误,但存储过程内的函数仍然提交。

任何人都可以解释为什么我的存储过程出现死锁错误吗?

mysql database-deadlocks
1个回答
0
投票

仅根据您提供的信息很难判断是什么原因导致了僵局。您可以尝试的是,当问题发生时,收集一些信息。 Performance_schema 中有几个地方可能包含有用的信息:data_locks 表、 data_lock_waits 表metadata_locks 表

确保收集数据,默认情况下可能并不总是收集数据。除此之外,正如已经提到的,您应该捕获

的输出
SHOW ENGINE INNODB STATUS\G

这还将包含一些有关正在发生的锁定的有用信息。

您可以使用 pt-stalk 来获取全部数据,这是 Percona Toolkit 中的一个工具,旨在运行显示数据库状态的深入数据收集。您可以从以下位置下载:

wget https://percona.com/get/pt-stalk

您可以手动触发执行:

./pt-stalk --no-stalk --iterations=1 --user=root --ask-pass

您要查看的数据在文件中:

*-ps-locks-transactions
*-transactions
*-lock-waits
*-innodbstatus1
*-innodbstatus2

并不总是会创建所有文件,这取决于数据库中的情况。默认情况下 pt-stalk 在

/var/lib/pt-stalk
中创建其数据。

© www.soinside.com 2019 - 2024. All rights reserved.