SQL/sql 문법(mysql, mariaDB)

트랜잭션(transection): deadlock

읽히는 블로그 2024. 5. 16. 20:18

▤ 목차

    deadlock

    교착 상태 또는 데드락이라 부른다. 두 개 이상의 작업이 서로 상대방의 작업이 끝나기를 기다리고 있기 때문에 결과적으로 아무것도 완료하지 못하는 상태를 의미한다.

     

    > 프로세스가 자원을 얻지 못해 다음처리를 하지 못하는 상태

    발생되는 상황

    • 멀티 프로그래밍 환경에서 한정된 자원을 사용하려는 상황
    • 대용량 데이터 처리로 인해 쿼리문의 실행시간이 길어져 오랜 시간 Lock을 잡고 있는 경우
    • 어떤 프로세스가 자원을 요청했을 때 그 시각에 자원을 사용할 수 없는 상황이 발생할 수 있다. 이런 경우 프로세스는 대기 상태로 들어가게 된다.
    • 트랜잭션을 걸었지만 Commit 또는 Rollback되지 않은 경우
    • 리소스 경합으로 인한 교착상태(DeadLock) 발생 

    ⌨ 데드락(Deadlock) 발생 조건

    • 상호 배제 (Mutual Exclusion) : 한번에 프로세스 하나만 해당 자원을 사용할 수 있다. 
    • 점유 및 대기 (Hold and Wait) : 자원을 최소한 하나 보유하고 다른 프로세스에 할당된 자원을 점유하기 위해 대기하는 프로세스가 존재한다.
    • 비선점 (No Preemption) : 이미 할당된 자원을 강제로 빼앗을 수 없다.
    • 순환대기 (Circular Wait) : 대기 프로세스의 집합이 순환 형태로 자원을 대기하고 있어야 한다.

    💻 해결 방법

    • 예방(Prevention)  

    교착 상태 발생 조건 중 하나를 제거하며 해결한다.  교착 상태가 자원의 낭비가 심한 방법이다.

    - 상호배제 부정: 읽기 전용 파일과 같은 공유 자원을 사용한다.

     같은 자원이라면 데드락을 고려할 필요가 없을 것이다.

    - 점유 및 대기 부정: 프로세스가 자원을 요청할 때 다른 자원을 갖고 있으면 안 된다.

     1) 프로세스 시작 시 필요한 자원을 한 번에 할당받도록 한다.(사용하지 않는 자원도 갖기 때문에 낭비)

     2) 자원이 필요한 경우 보유한 자원을 모두

    - 비선점 부정: 자원 점유 중인 프로세스가 다른 자원을 요구할 때 가진 자원 반납

    - 순환대기 부정: 모든 자원에 할당 순서를 정하고 그 순서대로만 자원을 할당한다. 

    • 회피 : 데드락 발생 가능성을 인정하면서도 피해나간다.

    프로세스가 평생 사용할 자원을 미리 알고 있을 때,  자원을 할당한 후 데드락이 발생할지 확인 후 안전한 상태에서만 자원을 할당한다.

    각 프로세스가 요구한 양만큼의 자원을 할당해 줄 수 있는 순서를 안전순서열이라고 한다.

    > 안전 상태 :  안전 순서열이 존재하는 상태

    > 불안전 상태: 안전 순서열이 존재하지 않는 상태 (데드락이 발생 가능한 상태)

     

    ※은행원 알고리즘 Banker's Algorithm
    은행은 최소한 고객 한 명에게 대출할 정도의 돈이 있어야 한다.
    자원 분배를 잘못해서 자원(돈)이 부족한 상태를 불안정한 상태로 판단한다.
    https://velog.io/@minu-j/%EC%9A%B4%EC%98%81%EC%B2%B4%EC%A0%9C-%EB%A7%8C%ED%99%94%EB%A1%9C-%EC%95%8C%EC%95%84%EB%B3%B4%EB%8A%94-%EC%9D%80%ED%96%89%EC%9B%90-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EA%B5%90%EC%B0%A9%EC%83%81%ED%83%9C-%ED%9A%8C%ED%94%BC-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
     

    [운영체제] 만화로 알아보는 은행원 알고리즘(Banker's algorithm) (교착상태 회피 알고리즘)

    잘 이해가 안돼서 만화로 그려본 은행원 알고리즘(Banker's algorithm)

    velog.io

     

    • 탐지와 회복

    시스템에 교착 상태가 발생했는지 점검하여 교착 상태에 있는 프로세스와 자원을 발견한다. 교착 상태 발견 알고리즘, 자원 할당 그래프 등을 사용한다.

    • 탐지 : 자원 할당 그래프를 통해 교착 상태 탐지한다.
    • 회복 : 교착 상태를 일으킨 프로세스를 종료하거나 할당된 자원을 해제시켜 회복시킨다.

    프로세스 종료

     - 교착 상태의 프로세스를 모두 중지

     - 교착 상태가 제거될 때까지 1개의 프로세스씩 중지

    자원 선점 방법

     - 자원을 빼앗긴 프로세스는 강제 종류 이후 재시작

     - 교착 상태에 빠진 프로세스가 필요로 하는 자원을 강제로 가져온다.

    • 무시(Deadlock Ignorance)

    데드락은 사실 드물게 발생한다. 데드락에 대한 조치가 더욱 큰 오버헤드가 발생할 수 있다.

    일반적으로 운영체제는 deadlock ignorance를 채택한다.

    deadlock이 발생해도 무시한다. 프로그래머가 deadlock이 발생하지 않도록 해야 한다.

     

    ✔ deadlock 코드

    ⌨transections 시작

    A라는 작업자가 jik1 테이블에서 작업 중이다.

    jikwon 번호가 7번인 사람 이름을 '김밥'으로 바꾸고 

    14,15,16번은 지울 것이다.

    SET AUTOCOMMIT = FALSE;
    SELECT * FROM jik1;
    UPDATE jik1 SET jikwon_name = '김밥' WHERE jikwon_no = 7;
    DELETE FROM jik1 WHERE jikwon_no IN (14, 15, 16);
    SELECT * FROM jik1;

    A 작업자는 자신의 일을 모두 마치고 나갔다고 가정해 보자.

     

    다른 작업자 B가 같은 jik1테이블에 7번 데이터를 삭제하려고 한다.

    데드락에 걸렸다.

    이후 아무 진행이 일어나지 않는다.

    시간이 지나 lock상태라 시간이 지연되었다는 메시지가 출력됐다.

    에러 메시지가 나오기 전까지 lock이 풀릴 때까지 대기하고 있다.

    COMMIT;

    대기 와중에 A작업자가 돌아와 commit을 한다면 B작업자의 코드는 들어간다.

    하지만 A작업자가 알아차리지 못하면 발생 위치를 찾아다녀야 한다.

    👏 중요

    코드는 특정 상황을 가정한 것이다. 이외에도 많은 발생 원인이 있으며

    데드락을 무조건 막을 순 없지만 최소화할 수 있다.

     

    😊정리

    트랜잭션을 일괄처리로 작은 시간단위로 유지하는 것이 좋다.

    트랜잭션을 길게 유지하는 경우 lock의 잠금 시간도 길어지기 때문에 쿼리 성능을 개선하여 짧은 시간 내에 데이터를 처리하는 것이 좋다.