[DB] 데이터베이스 (3)
트랜잭션 격리수준
- 데이터베이스의 ACID 성질 중
Isolation
에 해당 - 여러 트랜잭션이 동시에 변경을 수행할 때 성능과 안정성, 일관성 및 재현성 간의 규형을 미세하게 조정하는 설정
- 특정 트랜잭션이 다른 트랜잭션에 변경한 데이터를 볼 수 있도록 허용 여부를 결정
- 격리 수준은 총 4가지로 나뉘며, 아래로 내려갈수록 고립 정도가 떨어지며 성능이 떨어진다. 일반적인 온라인 서비스에서는
READ COMMITTED
나REPEATABLE READ
중 하나를 사용한다.READ UNCOMMITTED
READ COMMITTED
REPEATABLE READ
SERIALIZABLE
READ UNCOMMITTED
- 트랜잭션의 변경내용이
COMMIT
이나ROLLBACK
과 상관없이 다른 트랜잭션에서 보여진다. - Dirty Read 문제가 발생할 수 있다. (데이터 정합성 문제)
READ COMMITTED
- 트랜잭션의 변경 내용이
COMMIT
되어야만 다른 트랜잭션에서 조회 가능하다. - Oracle DBMS에서 기본으로 사용한다.
NON-REPEATABLE READ
문제가 발생할 수 있다.
REPEATABLE READ
- 트랜잭션이 시작되기 전 COMMIT된 내용에 대해서만 조회할 수 있는 격리 수준
- MySQL DBMS에서 기본으로 사용한다.
- 자신의 트랜잭션 번호보다 낮은 트랜잭션 번호에서 변경된 내용만 보게 된다.
UPDATE
부정합,Phantom Read
문제가 발생할 수 있다.
SERIALIZABLE
- 가장 엄격한 격리수준
- 읽기 작업에도 공유 잠금을 설정하고, 다른 트랜잭션에서 해당 레코드 변경 불가
- 동시처리 능력이 떨어지며 성능저하 발생
교착상태 (Dead lock)
- 두 개 이상의 작업이 서로 상대방의 작업이 끝나기만을 기다리는 상태
- 결과적으로 아무것도 완료되지 않음
4가지 필요조건
- 4가지 조건을 모두 만족하는 경우 교착 상태가 발생할 수 있다.
- 하나라도 만족하지 않으면 발생하지 않는다.
- 상호 배제(Mutual Exclusion)
- 자원은 동시에 하나의 프로세스나 스레드만 사용할 수 있도록 상호 배제되어야 한다.
- 어떤 프로세스나 스레드가 자원을 사용하고 있으면 다른 프로세스나 스레드는 그 자원에 대한 접근을 제한받게 된다.
- 점유와 대기(Hold and Wait)
- 프로세스나 스레드가 자원을 점유한 상태에서 다른 자원을 요청하면서 대기하면서 데드락이 발생할 수 있다.
- 프로세스나 스레드는 이미 점유한 자원을 해제하지 않고 다른 자원을 기다리게 된다.
- 비선점(Non-preemtion)
- 다른 프로세스나 스레드가 이미 점유한 자원을 선점할 수 없는 경우에도 데드락이 발생할 수 있다.
- 점유한 자원을 다른 프로세스나 스레드가 선점할 수 없기 때문에 대기 상태가 지속
- 환형 대기(Circular Wait)
- 두 개 이상의 프로세스나 스레드가 자원을 점유하고 있으면서, 각 프로세스나 스레드가 서로가 점유한 자원을 요청하면서 대기하면 데드락이 발생할 수 있다.
- 자원 요청이 환형을 이루는 것이 원인이 된다.
방지법
- 사전에 교착 상태가 발생하지 않게 하거나, 발생한 뒤 고치는 방법이 있다.
- 방지(Prevention)
- 교착 상태가 발생하는 조건을 만족하지 않도록 함으로써 방지한다.
- 회피(Avoidance)
- 리소스 할당의 측면에서, 교착 상태가 발생할 가능성이 있는 자원 할당을 하지 않는다.
- 탐지 및 회복(Detection and Recovery)
- 교착상태가 발생 할 경우 찾아내어 고친다.
인덱스
인덱스 개념
- 추가적인 쓰기 작업과 저장 공간을 활용하여 데이터베이스 테이블의 검색 속도를 향상시키기 위한 자료구조
- 조회 기능 외에도 update, delete 성능이 함께 향상된다. (조회해야만 작업 가능함)
- 기존 연산에 비해 추가적인 연산이 필요하며, 이에 따른 오버헤드가 발생한다.
- 규모가 작지 않은 테이블이고, DML을 자주 사용하지 않고 데이터의 중복도가 낮은 컬럼에 사용하면 좋다.
장점
- 테이블을 조회하는 속도와 그에 따른 성능을 향상시킬 수 있다.
- 전반적인 시스템의 부하를 줄일 수 있다.
단점
- 인덱스 관리를 위한 추가 저장공간과 작업이 필요하다.
- 잘못 사용할 경우 오히려 성능이 저하될 수 있다. (overhead)
Clustered index, Non-Clustered index
Clustered index
- 테이블의 데이터를 지정된 컬럼에 대해 물리적으로 데이터를 재배열한다.
- 인덱스로 생성되어 있는 컬럼을 기준으로 정렬되어 삽입한다.
- index page를 key-pageId로 구성하고, 조회하려는 데이터의 키 값으로 페이지 번호를 검색해 데이터를 찾는다.
- 테이블 당 한개씩만 존재 가능
- 데이터가 많이 저장된 상태에서 추가하면, 많은 데이터를 정렬해야 해서 많은 리소스를 차지함
Non-Clustered index
- 별도 장소에 키값과 RID로 구성된 인덱스 페이지를 생성한다.
- 인덱스 페이지의 리프 페이지에 열을 정렬한 후 위치 포인터(RID)를 생성한다.
- 리프 페이지를 찾기 위한 루트 페이지를 생성한다.
- 조회하려는 데이터의 키 값을 루트 페이지에서 비교해 리프 페이지 번호를 찾고, 리프 페이지에서 RID 정보로 실제 데이터 위치로 이동한다.
인덱스 자료구조
인덱스는 여러 자료구조를 이용해 구현할 수 있다.
해시 테이블을 통한 구현
- 인덱스가 (key, value) = (컬럼의 값, 데이터의 위치)로 구현된다.
- 해시 테이블은 등호 연산에 최적화되어 있기 때문에, 실제로는 인덱스 구현에 잘 사용되지 않는다.
B+테이블을 통한 구현
- B-Tree의 단점을 개선한 구현 방법이다.
- B-Tree는 어느 한 데이터의 검색은 효율적이나, 모든 데이터를 순회하는 데에는 트리의 모든 노드를 탐색해야 하므로 비효율적이다.
- 리프 노드에만 데이터를 저장한다.
- 메모리를 더 확보할 수 있다.
- 리프 노드가 아닌 노드에는 자식 포인터만 저장한다.
- 검색 속도를 높일 수 있다.
- 리프 노드간 Linked List로 연결되어 있다.
- 중간 노드의 키는 중복될 수 있다.
Leave a comment