ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [테코톡] DB Lock
    DB/DB 2023. 5. 22. 02:18

    ---

    https://youtu.be/ZXV6ZqMyJLg - 마루, 자막

    https://youtu.be/onBpJRDSZGA - 오즈, 자막

    https://youtu.be/w6sFR3ZM64c - 카일

     

    ---

    https://youtu.be/ZXV6ZqMyJLg - 마루, 자막

     

    Database Lock? DB를 잠그는 것?

    왜 잠그고 어떻게 잠그는지

     

    ---

     

    ---

    재고가 하나일 때, 

    두명의 사용자가 동시에 접근하면 

     

    구매절차가

    1.재고 수량을 읽어

    2.구매하면

    3.재고 업데이트

     

     

    ---

    이런 문제를 해결하기 위해 동시성 제어가 필요하다

    동시성 제어를 Lock을 이용해서 한다

     

    ---

    Lock은 두 종류

    경합 안일어나겠지 - 낙관  ▽충돌이 드물거니까 이정도로 한다

    버전을 먼저 읽고, 일련의 과정을 거치고 구매를 완료한 후, 데이터를 업데이트 시켜주기 전 버전을 다시 읽는다.

    처음버전과 다음 읽은 버전이 똑같다면 버전을 다시 업데이트 시켜줄 수 있다.

    반면 구매를 뒤늦게 완료한 다른 사용자가 버전을 다시 읽으면, 방금 걔 때문에 업데이트 됐기 때문에 처음읽은 버전과 나중에 읽은 버전이 달라. 충돌이 발생했음을 알았다. 이후에 롤백을 시켜준다

     

    ---

    동시에 수정할 가능성이 높다라고 보는 잠금 - 비관  ▽충돌이 많을거니까 좀 세게한다. 충돌 비용(롤백)이 많이 드니까. 미리 방지해버려 -> 데드락 발생 가능성

    데이터에 접근하기전에 Lock을 걸어준다.

    그리고 일련의 과정을 거치고

    Unlock을 시켜준다

    이 동안 다른 사용자는 무조건 대기해야 한다.

     

    ---

    OL은 롤백을 할 가능성이 많고, 빈번하게 일어날 수 있기 때문에  ▽겹치면 롤백되는거니까 계속 그러면 진행이 안될것아냐

    PL은 롤백을 하기 힘든 외부 시스템과 연동한 경우에 쓰면 좋다

     

    ---

    PL 좀 자세히.

    PL의 연산의 종류

    공용락과 베타락

     

    공용락 먼저

    ▽일단 데이터에 접근할 때 락부터 거나봐. 그렇게 되면 락은 권한이라고 생각하면 되고. 락이 걸리냐 마느냐다.

    ChatGPT : 네, 일반적으로 데이터베이스에서 Shared Lock (S-lock)은 데이터의 읽기 권한을 나타냅니다.

    ▽lock은 데이터에 거는것이자, 트랜잭션이 갖는 권한이야? 뭔가 이중적인 개념이군. 코드에 어떻게 써있길래 - 밑에 씀

    ▽내 생각인데

    트랜잭션이 데이터에 락을 걸면, 무슨락, 건 트랜잭션 누구.. 이렇게 걸리나봐 -> 저~기 밑에다른 Lock유튜브 본거보니까 Lock mode이런거 써져있네

    s락이면 다른 애도 s락을 걸수 있으니 걔도 s락, 건 트랜잭션 누구.. 또 쓰이겠지

    근데 그 데이터에 s락이 써져 있으니까 거기에 x락을 걸려고 하면 금지! 되겠고(수정을 하려면 x락을 걸어야 하니까 수정을 하려면 금지! 이건 빼야겠지?)

     

    공용 락을 건 나 : Read연산 실행 가능, Write 불가능

    다른 트랜잭션 : Read연산 실행 가능, Write 불가능 -> 다 같은 락을 갖고 있으니까 다 똑같지 다 같이 읽을 수 있고 다 같이 못 쓰는 것.

     

    데이터에 대한 영향이 없기 때문에, 여러 트랜잭션이 함께 사용권을 가질 수 있다(s-lock을 걸 수 있다고. 이게 데이터에 대한 사용권이라고 하나봐. 동시에 데이터에 대해 s-lock을 가질 수 있다)

     

    ---

    베타락을 건 나 : read, write둘다 가능하고

    다른 트랜잭션 : 아무것도 못함 - 왜냐? 락을 갖고 있지 못하니까. 저 데이터의 s락이든 x락이든 가질 수 없어

     

    write는 데이터를 업데이트 시킬 수 있어서 데이터에 대한 독점권을 가진다.

     

    ---

    Lock 연산의 양립성

    베타락이 들어간 순간 양립이 불가능

     

    ▽누군가가 그 데이터의 공유락을 가졌으면 다른애는 그 데이터에 대해 x락을 못가진다는 것이지!!

     

    ---

    그럼 Lock의 단위를 좀 잘 정하는 것이 좋을 것 같아. 단위를 조절할 수가 있어. DBMS종류마다 다르다

    크게 가져가는 장점

    작게 가져가는 장점

     

    ---

    안되는 이유. 발생할 수 있는 문제점

    ▽베타lock은 양립이 불가능하니까~!

     

    ---

    어떻게 해결해?

     

    ---

    두번째 문제점. DeadLock, 교착상태

    공용 락 공유 락

    1.1의 1에 대한 베타락

    2.2의 2에 대한 공유락

    3.2의 1에 대한 공유락을 걸려고 했는데 이미 베타lock이 걸려있으니 대기

    4.1의 2에 대한 베타락을 걸려고 했는데 이미 공유lock이 걸려있어서, 베타 lock은 양립할 수 없기 때문에 대기

    =>그럼 트랜잭션이 서로가 서로를 기다리는 상황

     

    ---

    이건 어떻게 해결해

    1.같은 방향으로 처리하면, 블록킹은 발생할 수 있겠지만, 데드락은 확률이 현저히 줄어든다.

    2.3.블록킹과 마찬가지

     

    ---

     

    ---

    https://youtu.be/onBpJRDSZGA - 오즈, 자막

    Lock은 컴퓨터과학 관점으로는 데이터에 접근하지 못하도록 막는 장치

    DB는 데이터를 저장하는 애. DB는 Lock을 사용해서 데이터 접근을 막을 수 있다.

    레코드 단위, 테이블단위, schema단위로 접근을 막을 수 있다.

     

    lock이 없으면,

    데이터 무결성, 일관성이 깨진다

    -> 동시성 제어를 위해 lock필요하다

     

    ---

    lock은 벤더사마다 다르고, 전략도 다르다

    이번 발표에서는 MySQL5.7, InnoDB에 맞춰서 설명

     

    ---

    1.베타 잠금(Exclusive Locks)

    발표대회를 하는데, 발표부스 테이블이 있고,

    발표 부스와 트랜잭션 1이 발표자리에 update를 날리는 것. 발표 중간에 누가 끼어들지 않도록, Lock을 건다

    그리고 트랜잭션 2가 발표자리에 update를 또 날리는데, Lock이 충돌하면서 timeout에러가 뜸

    현재 걸린 lock에 대한 정보를 알고 싶으면 저 테이블을 조회, X Lock이 걸려 있다.

     

    ---

    뒤에 lock in share mode;를 명시해주고 조회하면 s lock을 걸면서 조회할 수 있다.

    8.0부터는 for share를 명시해도 lock을 획득할 수 있다

     

    이렇게 s lock이 걸린 상태에서 트랜잭션 2가 동일한 booth_no의 name을 수정하려고 하니 락이 충돌

    또 이미 s lock이 걸려져 있는 row에 대해 트랜잭션 3도 s lock을 걸 수 있다

    2개가 걸린걸 확인할 수 있다

     

    ---

    여기까지의 s lock, x lock은 다른 db에서도 존재하는 lock의 개념이다

    락은 크게 s lock, x lock 2개로 나뉘어져 있어.

     

    이제부턴 innodb에서 다른 db와는 좀 다른 방식으로 제공해주는 락을 알아보자

     

    ---

    booth_no 컬럼에 인덱스 추가, 

    트랜잭션 1 먼저 수정 시도한 프로젝트,

    트랜잭션 2 그 후에 수정을 시도하려는 프로젝트

     

    ---

    트랜잭션 1이 앞서 index를 추가한 booth_no를 이용해 booth_no를 4로 수정해주었다.

    트랜잭션2가 동일한 booth_no인 2를 가지고 수정을 시도, lock이 충돌한 모습

     

    =>lock은 동일한 조건의 record, 즉 row에 걸릴 수 있다는 뜻

     

    innodb에서는 다른 rdbms와 달리 테이블 레코드가 아닌 인덱스 레코드에 락을 건다

     

    ---

    앞서 소개했던 x lock, s lock 예제들도 인덱스 레코드에 걸렸던 것

     

    ---

    gap locks

    사이에도 못 넣는 것

    ▽아니 index record가 뭔데요?

    보면 0, 1, 3, 6뿐인데

    트랜잭션1은 1번부터 6번까지 lock

    트랜잭션 2는 비어있는 공간에 데이터를 삽입하려는 프로젝트의 주인

     

    select for update

    안 들어감.

    gap lock이라고 표시 돼 있음.

     

    ---

    데드락 예제 간단히

    ▽보고 또 보고를 3번으로 업데이트 하기 위해 1번부스에 X lock을 건다는데,

    테이블이

    1번부스 뭐~

    2번부스 뭐~ 이런식일텐데

     

    1번을 빈것으로 업데이트 해야 하니까 lock을 건다는 얘기겠지

    근데 이때 3번 부스도 바꿔야 할 것 아냐 3번으로 옮길거아냐 근데 3번 부스에 있던애가 1번으로 업데이트하려고 lock을 걸어버리면

    서로의 lock에 막혀서 대기를 하게됨

    이게 데드락, 서로의 자원을 원하고 있다.

     

    ---

    위의 상황을 db로 보면

    트1 : 1번 부스 프로젝트를 3번으로

    트2 : 3번 부스 프로젝트를 1번 부스로

     

    아직 트랜잭션이 끝나지 않은 상태에서, 

    트랜잭션1과

    트랜잭션2가

    Deadlock

     

    ---

    이걸 자세히 보기 위해서, innodb에서는 show engine innodb status라는 쿼리를 제공. 최근에 감지된 데드락 정보를 보여줌.

    어떤 트랜잭션, 무슨이유로 데드락 걸렸나, 어떤 트랜잭션 롤백했나..

     

    ---

    db의 데드락 해결법

    mysql, oracle : deadlock detection, lock wait timeout

     

    ---

    dba도 아니고, 개발자가 lock을 사용할일은 없겠지만, 장애 상황은 반드시 발생할 수 있으니, 빠른 대처를 위해 필요하다

    아예 모르고 장애 상황을 대하면 당황할 것.

     

    ---

     

    ---

    https://youtu.be/w6sFR3ZM64c - 카일

    Record locking : DB의 일관성과 무결성을 유지하기 위해 트랜잭션의 순차적 진행을 보장할 수 있는 직렬화 장치

    동시성 - 여러명이 데이터에 동시에 접근해서 수정하려고 할 때

    일관성 - 데이터의 일관성이 깨질 수 있다

    잠금 - 그래서 잠금을 한다

     

    종류는

    Optimistic Lock - 충돌나지 않을거다~(낙관적) = 락을 걸 이유가 없다(비선점적) = 락을 안거는 방식. 버전으로 관리

    update하려고 봤는데 처음에 체크했던 것과 버전이 달라졌을 때 Optimistic Lock Exception을 터뜨리는게 동작하는 방식

    JPA에 @Version이라는 애너테이션 하나 달면 알아서 적용이 된다

     

    Pessimistic Lock - 충돌이 날거라고 봄(비관적) = 미리 조회할때부터 락을 건다(선점적)

    OL은 애플리케이션 레이어에서의 락이라고하고, 이건 DB에 락을 건다고 하는데 이해 못하겠음

    무결성의 장점이 있지만, 데드락의 위험성이 있다

     

    Shared lock

    Exclusive lock

     

    버전이 안맞으면 롤백되는 단점

    락 자체가 비용이기 때문에 오버헤드가 발생할 수 있다.

     

    둘 중 뭘 쓸지

    읽기만 하면 수정은 없으니

    요즘은 롤백 오버헤드가 많이 줄어서 그냥 Optimistic Lock을 쓰기도 한다

    도메인 - 게시판이면 게시판에 락을 걸까 등을 고민

    연관관계 - 게시물을 가져올 때 댓글까지 락을 걸거냐..

    Lock이 트랜잭션이랑 같이 연결돼서 동작하기 때문에 트랜잭션 isolation 수준을 설정해놓고 락은 뭘 걸고 이런걸 연출해보기. 이해하는데 도움이 된다

    'DB > DB' 카테고리의 다른 글

    [테코톡] Deadlock  (0) 2023.05.22
    [테코톡] DB Index 2, MySQL 인덱스와 실행계획  (0) 2023.05.20
    [테코톡] DB Index 1  (0) 2023.05.18
    [테코톡] DB Replication 3, Clustering, Sharding  (0) 2023.03.10
    [테코톡] DB Replication 2  (0) 2023.03.08
Designed by Tistory.