it-source

MariaDB 교착 상태 방지

criticalcode 2022. 12. 9. 21:52
반응형

MariaDB 교착 상태 방지

저의 원래 실수는

오류 번호: 1213 - 잠금을 받을 때 교착 상태가 발견되었습니다. 트랜잭션을 다시 시작해 보십시오.

난 최대 재시도 횟수와 그 사이에 교착상태를 타개하기 위해 대기시간을 기록했어

$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);
}

그러나 현재도 계속 원래의 에러가 발생하고 있습니다.또, 새로운 에러가 발생하고 있습니다.

COMMIT 중에 에러 35 "Resource dislock effaided"가 발생하였습니다.

하지만 이게 무슨 의미인지, 어떻게 고쳐야 하는지 정말 알 수가 없는 것 같아요.


편집

처음 작성했을 때는 많은 정보가 누락되어 있었습니다만, 서버는 Galera & MariaDB 클러스터에 있는 RedHat 7 AWS EC2(그 중 3개)입니다.

실행 중인 쿼리는 저장 프로시저 호출입니다.

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

그리고 저장 프로시저는 다음과 같습니다.

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

Galera 클러스터(MariaDB Galera 클러스터, 3 노드)의 교착 상태는 일반적인 교착 상태가 아니라 멀티 마스터 충돌을 전달하는 방법입니다.

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

교착 상태를 피하는 가장 쉬운 방법은 한 번에 한 노드에 쓰는 것입니다. 즉, HA 프록시가 한 노드에만 쓰도록 구성하는 것입니다.이 경우 Node1에서 sp를 실행합니다(어느 노드든 상관없습니다만, 항상 1개의 노드, 일종의 "스틱 세션"입니다).

상세한 것에 대하여는, https://severalnines.com/blog/avoiding-deadlocks-galera-set-haproxy-single-node-writes-and-multi-node-reads 를 참조해 주세요.

트랜잭션 내에서 이 Pro를 호출하고 있습니까?만약 그렇다면, 나는 그것의 디자인에 강하게 반대한다.당신은 거래가 잠자고 있는 루프를 가지고 있다.

그 대신,UPDATE거래 그 자체입니다.

이것은 교착 상태를 사실상 해소할 수 있을 것이다.그러나 다른 답변에서 설명한 바와 같이 교착 상태에 대해서는 여전히 대처해야 합니다.

편집이 없기 때문에BEGINs,그리고.autocommit=ONOP는 이미 이 조언을 따르고 있습니다.아아.

언급URL : https://stackoverflow.com/questions/45062771/mariadb-avoid-deadlocks

반응형