douya1061 2017-07-12 16:07
浏览 704
已采纳

MariaDB避免死锁

My original error was

Error No: 1213 - Deadlock found when trying to get lock; try restarting transaction

Okay, so I wrote a loop with max retries and a wait in between to try and get through the deadlocks.

$Try = 0;
while (!$Result = $dbs->query($MySQL)) {
    $Try++;
    if ($Try === MYSQL_MAX_RETRIES)
        HandleMySQLError($dbs->error, $MySQL, false, $Test, $Trace);
    else 
        sleep(MYSQL_RETRY_WAIT);
}

But now I'm constantly getting some of the original error still, and a new error

Got error 35 "Resource deadlock avoided" during COMMIT

But I can't really seem to find out what this means or how to fix it?


EDIT

I left out a ton of information when I first wrote this, but the server is a RedHat 7 AWS EC2 (well, 3 of them) in a Galera & MariaDB cluster.

The query I am running is a call to a stored procedure

call`getchatmessages`('<ChatID>','<UserID>',from_unixtime('<Some Timestamp>'));

And the stored procedure is as follows

CREATE DEFINER=`root`@`%` PROCEDURE `getchatmessages`(IN `__ChatID` CHAR(36), IN `__UserID` CHAR(36), IN `__Timestamp` TIMESTAMP(6))
BEGIN

DECLARE `__NewChatMessages` TINYINT(1) DEFAULT 0;
DECLARE `__i` INT(11) DEFAULT 0;

DECLARE `__Interval` INT(11) DEFAULT 100; -- ms
DECLARE `__Timeout` INT(11) DEFAULT 15000; -- ms

while `__NewChatMessages`=0 and `__i`<`__Timeout`/`__Interval` do
    select 1 into `__NewChatMessages` from `chatmessages` where `ChatID`=`__ChatID` and `DateTimeAdded`>ifnull(`__Timestamp`,0) limit 1;
    update `chatusers` set `DateTimeRead`=now(6) where `ChatID`=`__ChatID` and `UserID`=`__UserID`;
    do sleep(`__Interval`/1000);
    set `__i`=`__i`+1;
end while;

select `chatmessages`.`Body`, `chatmessages`.`ChatID`, `chatmessages`.`UserID`, 
`chatmessages`.`ChatMessageID`, `chatmessages`.`DateTimeAdded`, UNIX_TIMESTAMP(`chatmessages`.`DateTimeAdded`) `Timestamp`, `users`.`FirstName`,
`users`.`LastName`
from `chatmessages` 
join `users` using (`UserID`) 
where `chatmessages`.`ChatID`=`__ChatID` 
and `chatmessages`.`DateTimeAdded`>ifnull(`__Timestamp`,0) 
order by `chatmessages`.`DateTimeAdded` desc
limit 100;

END
  • 写回答

2条回答 默认 最新

  • douba05167 2017-07-12 18:18
    关注

    Deadlock in Galera Cluster (MariaDB Galera Cluster, 3 nodes) is not a typical deadlock, but a way of communicating the multi-master conflicts:

    http://galeracluster.com/documentation-webpages/dealingwithmultimasterconflicts.html

    The easiest way to avoid deadlocks is to write to 1 node at a time, i.e. configure HA proxy to write to 1 node only. In your case you will run sp on Node1 (does not matter which node, but always on 1 node, sort of "sticky sessions").

    More information here: https://severalnines.com/blog/avoiding-deadlocks-galera-set-haproxy-single-node-writes-and-multi-node-reads

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 LiBeAs的带隙等于0.997eV,计算阴离子的N和P
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 来真人,不要ai!matlab有关常微分方程的问题求解决,
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算