【发布时间】:2015-04-14 02:31:17
【问题描述】:
我有一个 innoDB 表,其中多个连接可能会插入数据,并且每 10 秒运行一次的单个 MySql 事件会删除一些以前插入的记录。
但我遇到了死锁。我怎样才能避免它们?
这段代码负责将记录逐行插入到表中。
sql = "INSERT INTO ex_result (Result_ID, ParentResult_ID, StepNumber, Name, Type, DB_ID, Session_ID, Status, TotalTime, FunctionCall, FunctionResult, ToolTime, PluginName, Screenshot_FID, IsNegative, ContinueOnError, WantSnapshot, Message, ResultCode, Output, InputArguments) VALUES (@Result_ID, @ParentResult_ID, @StepNumber, @Name, @Type, @DB_ID, @Session_ID, @Status, @TotalTime, @FunctionCall, @FunctionResult, @ToolTime, @PluginName, @Screenshot_FID, @IsNegative, @ContinueOnError, @WantSnapshot, @Message, @ResultCode, @Output, @InputArguments)"
事件的代码是:
DELIMITER //
CREATE EVENT EVENT_RESULT_CLEANER
ON SCHEDULE
EVERY 10 second
COMMENT 'Clean all delted results'
DO
BEGIN
DROP TEMPORARY TABLE IF EXISTS `Temp_Result_Purge`;
CREATE TEMPORARY TABLE `Temp_Result_Purge` (
`Result_ID` VARCHAR(63) NOT NULL,
PRIMARY KEY (`Result_ID`))
ENGINE = MEMORY;
INSERT INTO Temp_Result_Purge(Result_ID)
(
SELECT t1.result_id
FROM ex_result AS t1
INNER JOIN ex_session as t2
ON t1.session_id=t2.session_id
WHERE NOT EXISTS(SELECT t3.result_id FROM ex_result as t3 WHERE t3.parentresult_id=t1.result_id)
AND t2.DeletedOn IS NOT NULL
LIMIT 2000
);
DELETE t1 FROM `ex_result` AS t1 INNER JOIN
`Temp_Result_Purge` AS t2 ON t1.Result_ID=t2.Result_ID;
DROP TEMPORARY TABLE `Temp_Result_Purge`;
END//
DELIMITER ;
【问题讨论】:
-
我不明白为什么你创建一个临时表 'Temp_Result_Purge' 而不是直接 DELETE t1 FROM ex_result AS t1 INNER JOIN ex_session as t2 ON t1.session_id=t2.session_id WHERE NOT EXISTS(SELECT t3 .result_id FROM ex_result as t3 WHERE t3.parentresult_id=t1.result_id) AND t2.DeletedOn IS NOT NULL
-
你确定有死锁吗?很奇怪,单个 INSERT 是如何导致死锁的。有没有办法同时多次运行删除程序?这可能是死锁的原因。
-
请提供 SHOW CREATE TABLE ex_result。
-
在遇到死锁后立即执行 SHOW ENGINE INNODB STATUS 并向我们提供陷入死锁的两条语句。
-
@RickJames:在问题link 中添加了相同的 CreateTable 和 InnoDBStatus
标签: mysql database database-deadlocks