MariaDB Galera 클러스터가 대기하는 대신 교착 상태를 던진 이유는 무엇입니까?
단일 서버 데이터베이스에서 Galera 클러스터로 응용 프로그램을 이동하려고 하는데 이 응용 프로그램은 몇 가지를 사용합니다.FOR UPDATE
자물쇠
이 경우를 고려해 보십시오.
create table rooms ( id int not null, owner int null, PRIMARY KEY (`id`));
insert into rooms values (1, null);
동시에 문의가 있을 경우 객실 소유자를 덮어쓰지 않도록 하고 싶습니다.현재 소유자가 NULL인 경우에만 룸에 소유자 ID를 설정합니다.
첫 번째 테스트 - 단일 데이터베이스 서버
TRX1 - 서버 A
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT * FROM rooms WHERE id=1 FOR UPDATE;
TRX2 - 서버 A
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT * FROM rooms WHERE id=1 FOR UPDATE;
-> 여기서 TRX2는 TRX1 대기 중입니다.
TRX1 - 서버 A
UPDATE rooms SET owner=1 WHERE id=1;
COMMIT;
-> 여기서 TRX2가 해제되고 TRX1의 업데이트된 소유자와 함께 룸이 검색됩니다.올바른 동시성 처리를 위한 현재 올바른 동작입니다.
2차 테스트 - 2개의 데이터베이스 서버가 있는 GALERA 클러스터
TRX1 - 서버 A
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT * FROM rooms WHERE id=1 FOR UPDATE;
TRX2 - 서버 B
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
START TRANSACTION;
SELECT * FROM rooms WHERE id=1 FOR UPDATE;
-> 여기서 TRX2는 보류되지 않습니다!
TRX1 - 서버 A
UPDATE rooms SET owner=1 WHERE id=1;
COMMIT;
TRX2 - 서버 B
UPDATE rooms SET owner=2 WHERE id=1;
COMMIT;
-> 여기서 TRX2는 교착 상태 오류와 함께 실패합니다.
두 번째 트랜잭션이 두 번째 클러스터된 서버에서 실행되더라도 첫 번째 트랜잭션의 커밋을 대기할 수 있는 해결책이 있습니까?
Galera는 낙관적인 잠금입니다.이 패턴은 커밋 중에 충돌이 없을 것으로 가정하고, 충돌이 발생하면 교착 상태가 발생합니다.COMMIT
SQL. 낙관적이라는 가정은 클러스터를 통해 전달되는 사전 잠금 메커니즘이 없으며 커밋 시에만 전달된다는 것을 의미합니다.
이는 로컬에서 업데이트되는 동일한 행에 대해 진행 중인 트랜잭션으로 다른 Galera 노드가 있는 경우 잠금 대기 또는 초기 교착 상태가 발생하지 않음을 의미합니다.
이는 관찰된 바와 같이 Galera 클러스터에서 여러 노드에 걸친 로컬 트랜잭션과 트랜잭션 간에 동작에 차이가 있음을 의미합니다.
전체 패턴이 낙관적이기 때문에 잠금을 획득하는 일관된 순서를 사용하여 로컬 시나리오에서 교착 상태를 피할 수 있지만 Galera 클러스터에서는 동일한 작업이 불가능합니다.업데이트 쿼리와 일치하는 올바른 인덱스를 갖는 것과 같은 최소화 기술은 Galera에서 로컬이므로 효과적입니다. 따라서 질문된 질문에서,id
기본 키 또는 보조 인덱스의 첫 번째 요소입니다.
충돌을 처리하려면 Galera 클러스터에서 교착 상태 처리 코드를 수행해야 합니다.SQL에서 논리적 작업 과정을 결정할 수 없기 때문에 예외적으로 교착 상태가 발생합니다.이러한 경우에 어떤 일이 발생했는지는 비즈니스 논리에 달려 있습니다.이것은 객실 예약 시스템이기 때문에 논리적으로(비즈니스 사례를 인식하지 않는 관찰자인 제가 결정한 바와 같이) 해당 객실을 예약하고 다른 옵션을 제시하기에는 너무 느린 사용자에게 오류를 제공하는 것입니다.
교착 상태를 방지하려면 응용 프로그램이 잠금 대기의 동일한 효과를 얻기 위해 예측 가능한 Galera 노드에서 룸 예약을 수행하도록 해야 합니다.
업데이트를 위해 을 선택합니다. 예약에서 어떤 행에 엄격하게 의존하지 않는 유용한 패턴인 skip locked도 로컬에서만 적용됩니다.
언급URL : https://stackoverflow.com/questions/75413460/why-mariadb-galera-cluster-thrown-a-deadlock-instead-of-waiting
'programing' 카테고리의 다른 글
열의 IDENTITY 속성을 변경합니다. 열을 삭제하고 다시 만들어야 합니다. (0) | 2023.06.09 |
---|---|
문자열 리터럴 앞에 "r"이 붙는 것은 무엇을 의미합니까? (0) | 2023.06.09 |
스트립 레이블 g 그림의 위치를 위에서 아래로 변경하시겠습니까? (0) | 2023.06.09 |
해결 방법: "'@typescript-eslint/consistent-type-assertions' 규칙에 대한 정의를 찾을 수 없습니다." (0) | 2023.06.09 |
Bash 별칭을 만들려면 어떻게 해야 합니까? (0) | 2023.06.04 |