2017년 1월 1일 일요일

Database Lock

Tags

원문

http://www.programmerinterview.com/index.php/database-sql/database-locking/

SQL에서 lock은 무엇일까? 예제와 설명을 통해 알아보자

데이터베이스에서 한 데이터베이스에 한 사용자 혹은 세션만이 특정 데이터를 수정하기 위해 "lock"을 사용한다. 그래서 데이터베이스 락은 둘 혹은 그 이상의 사용자가 같은 시간에 같은 데이터를 업데이트하는 것을 방지하기 위해 존재한다. 데이터에 락이 걸린다는 것은, 이 락이 풀릴 때까지 다른 세션에서 사용자는 이 데이터를 업데이트 할 수 없다는 것을 의미한다. 락은 COMMIT이나 ROLLBACK 구문 이후에 풀리게 된다.

다른 세션에서 락이 걸린 데이터에 업데이트를 시도하면 어떤 일이 발생할까?


세션 B가 락을 건 데이터에 세션 A가 업데이트를 시도하려 한다고 해보자. 세션 A에서는 무슨일이 일어날까? 세션 A에서는 락 대기 상태 에 걸릴 것이고, 트랜잭션 처리 진행이 중단될 것이다. 즉 세션 B가 락을 풀 때까지 세션 A는 "멈춤 상태"(stalled)에 있을 것이다.


데이터 락이 풀릴 때까지 너무 오랜 시간을 기다리게 된다면, IBM의 DB2와 같은 일부 데이터베이스들은 timeout 에러를 내고, 에러를 리턴한다. 그러나 Oracle과 같은 일부 데이터베이스들은 다르게 처리한다 - Oracle은 무기한 세션을 대기상태로 둘 수 있다. 즉, database 제품에 따라 락과 대기 처리가 다를 수 있다. 

데이터베이스 락 기술

데이터베이스 락은 여러 레벨로 둘 수 있다.

아래 보통 지원되는 형태의 락 레벨에 대한 정보와 기술들이 있다.

데이터베이스 레벨 락킹

데이터베이스 레벨 락은 데이터베이스 전체가 잠긴다(데이터베이스를 업데이트 할 수 있는 것은 단 하나의 세션이다). 이 데이터베이스 락은 실제로 업데이트하려는 데이터 이외에 모든 데이터에 다른 사용자의 접근을 막아버리기 때문에 잘 사용하지는 않는다. 그러나, 새 소프트웨어 버전을 위한 데이터베이스로 업그레이드 하는 등과 같은 상황에서 유용할 수 있다. Oracle은 exclusive 모드를 지원하는데 이 모드는 데이터베이스 사용을 한 사용자 세션으로 제한하는데 이것이 데이터베이스 락이다.

파일 레벨 락킹

파일 락 레벨에서는 전체 데이터베이스 파일이 락이 된다. 데이터베이스에서 파일이라니?라고 할 수 있는데, 파일 하나는 방대한 데이터를 가질 수 있다. - 한 파일 내부에는, 전체 테이블이 될 수도 있고, 테이블의 일부가 될 수 있고, 서로 다른 테이블의 각각의 일부분이 될 수 있다. 파일에는 다양한 데이터가 저장되기때문에, 이 파일 락 레벨은 선호되는 락 타입은 아니다.

테이블 레벨 락킹

테이블 레벨 락은 꽤 간단하다. 테이블 전체가 락 된다는 것이다. 이 레벨의 락은, 모든 row를 업데이트 하거나, column을 추가/삭제 하는 등과 같이 테이블에서 하나의 변화가 테이블 전체에 영향을 미칠 때 유용하다. Oracle에서 이를 DDL 락이라고 부르는데 CREATE, ALTER, DROP(이것들은 기본적으로 테이블 전체를 변화시킨다.)과 같은 DDL 구문에서 사용되기 때문이다.

페이지 혹은 블럭 레벨 락킹

블럭 혹은 페이지 레벨 락킹은 데이터베이스 파일의 일부가 락 되는 것을 의미한다.(페이지와 블럭을 잘모르겠다면 Pages versus blocks.로 가서 읽어보도록 한다) 블럭/페이지 단위로 저장될 수 있는 데이터는 다양하기 때문에 오늘날 데이터베이스에는 선호되는 타입의 락은 아니다.

열 레벨 락킹

열 레벨 락킹은 주어진 table의 특정 row에서 일부 column들이 락이 걸림을 의미한다. 이 레벨의 락은 락과 해제에 많은 리소스가 들기때문에 흔히 사용되지는 않는다. 그리고 지원하는 데이터베이스도 별로 없다. 

행 레벨 락킹

한 테이블의 한 행에만 락이 걸린다. 매우 흔한 락 레벨로 사실상 대부분의 데이터베이스 제품들이 지원한다.

데이터베이스에서 락이 자동으로 사용될까?




데이터가 삭제 혹은 업데이트 될 때 항상 사용된다. 명시적으로 사용자가 lock구문을 SQL에 사용하지 않아도 사용된다.

예제

아래와 같은 SQL이 있을 때 데이터베이스에 락이 어떻게 걸리는지 알아보자.
UPDATE some_table SET some_field = "some_value" 
WHERE some_column = "XYZ";
위 SQL구문은 "some_column"열이 "XYZ"라는 값을 가지는 행들의 락을 건다. 행들에 락을 거는 것은 RDBMS 뒷단에서 일어나게 되고 동시간에 다른 데이터베이스 사용자 세션으로부터 해당 행들이 업데이트 되는 것을 방지한다.

락이 걸린 곳의 데이터를 읽을 수 있을까?

락에 따라 다르다. 몇몇 락은 읽는 것조차 lock이 걸린동안 할 수 없다.

그래서 데이터베이스 락킹의 요점은?

만약 동시다발적으로 업데이트가 일어난다면, 잠재적인 데이터 손실을 막을 수 있는데, 데이터베이스의 락은 이것을 방지한다. 만약 여러 데이터베이스 사용자가 같은 데이터를 동시간대에 수정을 허용한다면, 그 결과는 혼란스러운 결과가 될 수 있다. 그러나 락을 건다면, 동시간에 한 명만 수정할 수 있기때문에 이러한 일은 발생하지 않는다. 

lock contention은 또 뭐야?

락은 contention으로 알려진 상황을 야기할 수 있다. 데이터베이스에서 락이 있기때문에 동시간에 존재하는 세션은 같은 데이터를 수정할 권리를 얻기위해 경쟁해야하는데 이를 contention이라고 한다. 낙관적인 상황에서는 락을 기다려야 하기때문에 쿼리 실행이 늦어질 수 있으며, 최악에는 세션이 무기한 기다릴 수 있는 상황을 lock contention이라고 한다. 만약 세션이 무기한 기다리게 된다면 이를 deadlock이라고 한다. Deadlock은 Database deadlock에서 읽어볼 수 있다.


EmoticonEmoticon

:)
:(
hihi
:-)
:D
=D
:-d
;(
;-(
@-)
:o
:>)
(o)
:p
:-?
(p)
:-s
8-)
:-t
:-b
b-(
(y)
x-)
(h)