2PL protocol 종류

정민교·2023년 6월 24일
0

DB

목록 보기
9/12
post-thumbnail

📒

지난 시간에는 lock이 무엇인지 lock을 활용해서 concurrency control을 어떻게 구현할 수 있는지 알아보았습니다.

lock은 해당 데이터에 대한 작업을 하기 위해 취득(점유)해야 하는 리소스입니다.

read-lock, write-lock이 있습니다.

write-lock을 취득하여 읽기, 쓰기 작업이 가능하며 write-lock은 exclusive lock입니다.

read-lock을 취득하여 읽기 작업이 가능하며 read-lock은 shared-lock입니다.

lock을 사용한 트랜잭션 실행 schedule에서도 이상 현상이 발생할 수 있었습니다.

이런 현상을 해결하기 위해 2PL protocol(expanding phase, shirinking phase)을 적용하였고,

2PL protocol을 적용하더라도 deadlock(모든 트랜잭션들이 lock을 반납하기를 기다리며 트랜잭션 실행이 멈춰버리는 현상)이 발생할 수 있다는 것까지 알아보았습니다.

오늘은 2PL protocol의 종류에 대해 알아보겠습니다.

✔️2PL protocol 종류

tx x와 y와 z를 더해서 y에 쓴다. x에 2를 곱해서 z에 쓴다.

read_lock(x) - read(x) - write_lock(y) - read(y) - write_lock(z) - unlock(x) - read(z) - write(y=x+y+z) - unlock(y) - write(z=x*2) - unlock(z)

2PL 프로토콜이 적용된 위와 같은 트랜잭션이 있습니다.

📌conservative 2PL

모든 lock을 취득한 후에 데이터 엑세스 작업을 시작합니다(트랜잭션을 시작합니다).

read_lock(x) - write_lock(y) - write_lock(z) - read(x) - unlock(x) - read(y) - read(z) - write(y=x+y+z) - unlock(y) - write(z=x*2) - unlock(z)

consavative 2PL이 적용된 schedule입니다.

트랜잭션 시작에 필요한 모든 lock을 취득한 후에 트랜잭션을 실행합니다.

conservative 2PL은 deadlock-free입니다. 데드락이 발생하지 않습니다.

하지만 트랜잭션 실행에 필요한 모든 lock을 취득한 후에 작업을 진행하기 때문에 트랜잭션을 시작하는 데 있어 시간이 오래걸릴 수 있어서 실용적이지는 않습니다.

📌strict 2PL(S2PL)

strict 2PL은 strict schedule을 보장하는 2PL입니다. 따라서 recoverability를 보장하며, write-lock을 트랜잭션이 commit 혹은 rollback된 후에 반환합니다.(read-lock은 상관 없습니다)

read_lock(x) - read(x) - write_lock(y) - read(y) - write_lock(z) - unlock(x) - read(z) - write(y=x+y+z) - write(z=x*2) - commit - unlock(y) - unlock(z)

🚨strict schedule에 대해 잠깐 복습하자면,

strict schedule은 recoverability를 보장하는 schedule 중 가장 엄격한 schedule입니다.

recoverability를 보장하는 schedule은

한 트랜잭션(A)이 어떤 데이터에 대해 읽기 작업을 할 때 그 데이터가 commit 되지 않은 다른 트랜잭션(B)가 write 작업을 한 데이터라면 B가 commit되기 전까지 A도 commit하지 않는 schedule을 말합니다.

recoverable한 schedule은 cascading rollback을 발생시키며 cascading rollback을 발생시키지 않는 schedule을 cascadeless schedule이라고 합니다.

cascadeless schdule은 schedule 내에서 어떤 트랜잭션(A)이 다른 트랜잭션(B)에 의존하고 있을 때, B가 commit 혹은 rollback하여 트랜잭션이 종료된 후에 B가 write한 데이터를 A가 읽는 schedule을 말합니다.

그리고 recoverability를 보장하면서 가장 엄격한 schedule을 strict schedule이라고 합니다.

strict schedule은 schedule 내에서 어떤 트랜잭션(A)이 다른 트랜잭션(B)에 의존하고 있을 때, B가 commit 혹은 rollback하여 트랜잭션이 종료되기 전까지는 B가 write한 데이터를 A가 읽지도 쓰지도 않는 schedule을 말합니다.

📌strong strict 2PL(SS2PL or rigorous 2PL)

strong strict 2PL은 기본적으로 동일한데 read-lock도 트랜잭션이 commit 혹은 rollback된 후에 반환하는 2PL입니다.

read_lock(x) - read(x) - write_lock(y) - read(y) - write_lock(z) - read(z) - write(y=x+y+z) - write(z=x*2) - commit - unlock(x) - unlock(y) - unlock(z)

이렇게 하면 장점이 S2PL보다 구현이 쉽습니다.

하지만 이제는 x에 대한 read-lock까지 마지막에 반환하기 때문에 x에 대한 lock까지 오래 점유하게 되었습니다.

따라서 다른 트랜잭션에서 x에 대한 write 작업을 하려고 할 때 lock을 취득하기 위한 시간이 S2PL보다 더 길어졌습니다.

구현이 쉽지만 단점이 존재하는 것입니다.

recoverability 또한 매우 중요한 속성이기 때문에 2PL 중에서도 많이 쓰이는 2PL이 S2PL과 SS2PL이며 초창기 RDBMS가 concurrency control을 구현하기 위해 가장 많이 사용하는 프로토콜이었습니다.

📌2PL protocol을 적용한 concurrency control의 문제점

2PL은 read-lock, write-lock을 사용해서 concurrnecy control을 구현하기 위한 프로토콜입니다.

하지만 read-lock과 write-lock의 관계에서 보앗던 표처럼

서로 다른 트랜잭션에서 같은 데이터에 대해 read-lock을 쥐는 것만 허용되고 나머지는 모두 허용되지 않기 때문에,

즉, 한쪽 트랜잭션은 무조건 block되기 때문에 DBMS의 전체 처리량이 좋지 않은 문제점이 존재합니다.

그래서 write-write 작업은 정말 위험하니 얘는 허용하지 않더라도 read-write 작업은 허용할 수 있도록 해서 처리량을 높여보자 하는 생각을 하게 됩니다.

그렇게 해서 탄생한 것이 MVCC(multiversion concurrency control)입니다.

오늘날의 많은 RDBMS가 lock과 MVCC를 같이 사용합니다.

✔️정리

concurrency control을 구현하기 위해 lock을 사용하였습니다.

concurrency control이 serializability를 보장하기 위해 2PL protocol을 적용하였고,

serializability뿐만 아니라 recoverability도 보장하기 위해 2PL protocol중 좀 더 엄격한 S2PL, SS2PL이 많이 사용되었습니다.

하지만 2PL protocol을 사용해서 구현한 concurrency control을 적용하면 RDBMS의 전체 처리량이 낮아지기에 이를 해결하기 위해 MVCC를 구현해 적용하게 되었습니다.

다음 시간에는 MVCC를 사용한 concurrency control에 대해 알아보겠습니다.

profile
백엔드 개발자

0개의 댓글