OLTP 와 OLAP 는 개발자로서 생각보다 친숙한 개념임에도 불구하고 실제로 많이 사용되는 단어가 아니다보니 생소한 경우가 많다.

 

* OLTP (Online Transaction Processing)

 OLTP 란 온라인 트랜잭션 처리를 말하며, 네트워크 상의 온라인 사용자들의 Database 에 대한 일괄 트랜잭션 처리를 의미한다. 

흔히 말하는 "트랜잭션(Transaction) 처리" 를 OLTP 라 부른다. 트랜잭션이라 부르는 용어의 의미 자체가 OLTP 의 의미를 포함하고 있다고 할 수 있겠다. 

Transaction 에 대한 보다 자세한 설명은 다음 포스팅을 참조해보자.

https://jins-dev.tistory.com/entry/Database-%ED%8A%B8%EB%9E%9C%EC%9E%AD%EC%85%98%EC%9D%84-%EC%9C%84%ED%95%9C-ACID-%EC%9D%98-%EA%B0%9C%EB%85%90

 

트랜잭션의 주 특징은 그루핑된 연산의 실패시, Rollback 이 지원된다는 점이다.

주로 기술적 특성상, 대규모의 처리보다는 소규모의 정교한 데이터 구성이 필요한 데이터의 처리가 중점이 된다.

 

 

* OLAP (Online Analytical Processing)

 OLAP 란 Database 자체적으로 운용되는 시스템이라기 보다는 데이터 웨어하우스 등의 시스템과 연관되어 Data 를 분석하고 의미있는 정보로 치환하거나, 복잡한 모델링을 가능하게끔 하는 분석 방법을 말한다.

 

기능 자체에 중심을 두는 OLTP 와는 다르게 사용하는 목적과 주제에 보다 중점을 둔다.

그렇기 때문에 주로 대용량의 데이터에 대해 처리하고 보다 복잡한 Data processing 으로 의미를 추출하는데 중점을 둔다.

 

대부분의 경우 OLAP 연산을 수행한다 라고 하면 적재된 데이터에 대한 분석 또는 SELECT Query 를 통한 데이터 스캔 Operation 이 주가 된다. 이는 OLTP 가 Transaction 의 과정에서 INSERT/UPDATE 를 중점적으로 수행하는 것과 대조되게 된다.

(하지만 언급했듯이, 쿼리의 읽기냐 쓰기냐 에 따라 구분되는 개념이라고 보기는 애매하다!)

 

 

면접에서 물어보면 트랜잭션은 알아도 OLTP 는 모르는 경우가 많다..

용어 자체가 중요하다고 보지는 않지만 알아둘 필요가 있겠다.


Database 는 서비스 운영 시 대게 큰 부하(Load)를 감당하게 되는 부분이다. 

특히 RDB를 통해 운영할 경우 데이터 정합성의 오류는 RDB를 기반으로 만들어진 서비스에 악영향을 미칠 가능성이 높아진다.

Transaction Isolation Level 이란, RDB가 Data Processing 에 있어서 ACID 원칙을 지키기 위해 정의된 다수의 Transaction 을 처리하기 위한 규약이다.


가령 MySQL에서 전체 데이터를 Scan 하는 쿼리 실행 시 서비스에는 큰 부하가 발생한다. 설계 시에 이런 가능성은 최대한 제거하는 것이 맞지만 피하지 못했을 경우를 생각해보자.

만약 Transaction Isolation Level 의 미설정으로 InnoDB의 Transaction Isolation Level 이 Repeatable-Read(Default) 상태에서 Select가 들어간 참조 쿼리 실행 시 데이터 변경 작업이 대기 상태에 빠지게 된다. 

특히나 참조할 데이터가 많을 경우에는 시간 지연으로 인해 wait timeout이 초과되거나, Deadlock 현상에 빠질 수도 있다.

그 외에도 Master 데이터에 대한 Write Transaction 이 진행 중인 상태에서 유저의 데이터 접근이 일어나거나, DB내의 공통 자원에 대한 접근이 발생할 때 MySQL 은 트랜잭션의 관리를 위한 몇가지 방안을 제시한다.


MySQL 의 Transaction Isolation Level의 종류


- Read uncommitted : 다른 트랜잭션이 Commit 전상태를 볼 수 있으며 Binary Log가 자동으로 Row Based로 기록.

다른 트랜잭션이 진행중인 작업 상태를 Read 를 통해 읽어올 수 있다. 이렇게 커밋되지않은 신뢰할 수 없는 데이터를 로드하는 것을 Dirty Read 라 한다. 

따라서 한 트랜잭션이 진행 중일 때에 여러번의 Select 쿼리가 서로 다른 결과(Phantom-read)를 발생시킨다. 

(Non-repeatable Read)



- Read committed : Commit 된 내용을 읽을 수 있으며 트랜잭션이 다르더라도 다른 트랜잭션이 Commit시 Read 가능. 자동으로 Row based로 기록. 

Commit 하지않은 내용은 읽을 수 없기 때문에 Dirty Read 는 발생하지 않는다. 대신 한 트랜잭션 내에서 Select 쿼리문의 결과가 다를 수 있으므로 Non-repeatable Read 가 발생한다.



- Repeatable Read : 현재 버전의 Snapshot을 만들고 데이터를 조회한다. 일관성을 보장하고 데이터를 읽기 위해서는 트랜잭션을 재시작 해야 한다. 

Read committed 와 마찬가지로 Commit 되지않은 다른 트랜잭션의 결과값이 보이지 않는다. (Non-Dirty Read) 

대신 한 트랜잭션 내에서는 다른 트랜잭션의 작업 여부에 상관없이 Select 쿼리문의 결과가 같은 데이터를 조회한다. (Non-repeatable read 가 발생하지 않는다.)



- Serializable : 가장 높은 Isolation level로 트랜잭션 완료 이전까지 참조하는 모든 데이터에 Shared Lock이 걸린다. 변경 수정 및 입력이 불가능하다.

가장 엄격한 레벨로, 유일하게 위에 언급된 3가지 문제(Dirty Read, Non-repeatable Read, Phantom Read)를 커버가능하다.

하지만 성능에 있어 가장 부하가 크게 작용한다.



가령 위의 Select 참조 쿼리 문제에 대한 설정 해결법으로 기본 Isolation level을 Repeatable Read -> Read committed 로 바꾸고 InnoDB lock wait timeout 을 늘려주는 방안이 있다.

이유는 Repeatable Read 에서 Lock이 발생하는 이유는 해당 옵션이 현재 Select 버전을 보장하기 위해 Snapshot을 이용하고 이 때문에 Lock이 발생하기 때문이다.


Transaction Isolation Level 은 실무자 입장에서 빈번하게 다룰 내용은 아니지만, DB를 이해하고 있다면, 아키텍처를 이해하고 있는 위치에 있다면 반드시 알아두어야 할 내용이다.


+ Recent posts