Oracle, PostgreSQL, MySQL Core Architecture, Oracle, PostgreSQL, MySQL Core Architecture II 책 공부Multiversion Concurrency control(MVCC)?
Multiversion이라는 말 그대로, 데이터 변화를 여러 버전으로 관리하여 동시성 제어를 한다Multiversion)Synchronization? a mechnism
MVCCMulti Generation Architecture(MGA, 추기형)라고 한다Rollback Segment 도입MGA 아키텍처 채택하여 PostgreSQL 6.5에 MVCC 아키텍처 도입Multi Generation Architecture, MGA
MGA 예제XMIN에 XID 10 세팅 & XMAX 세팅된 값 없음 = XID 10부터 현재까지 유효 의미| XMIN 10 | XMAX – | TUPLE 1 |
| XMIN 10 | XMAX – | TUPLE 2 |
| XMIN 10 | XMAX – | TUPLE 3 |
XID 30일 때, 기존 TUPLE 2의 XMAX에 XID 30 세팅하여 OLD 버전임을 표시XID 10부터 XID 30 범위에서 visible한 값XMIN의 XID 30, XMAX는 없음XID 30부터 현재까지 유효 의미| XMIN 10 | XMAX – | TUPLE 1 |
| XMIN 10 | XMAX 30 | OLD TUPLE 2 |
| XMIN 10 | XMAX – | TUPLE 2 |
| XMIN 10 | XMAX – | TUPLE 3 |
| XMIN 30 | XMAX – | NEW TUPLE 2 |
XID 10XID 20XID 30XID 40PAGE HEADER
... FREE SPACE ...
[TUPLE 3][TUPLE 2][TUPLE 1][PAGE TAIL]
PAGE HEADER
... FREE SPACE ...
[NEW TUPLE 2]
[TUPLE 3][OLD TUPLE 2][TUPLE 1][PAGE TAIL]
Rollback Segment 도입하여 MVCC 구현Rollback segment 메커니즘
Rollback segment에 보관SELECT SCN(System Change Number)과 데이터 블록의 SCN(System Change Number)을 비교CR(Consistence Read) 블록을 생성Ora-1555 snapshot too old라는 한계점 제외하고는 동시성을 극대화해주는 최고의 방법이었다Rollback segment 예제| data block | undo block |
|---|---|
| ITL(Interested Transaction List) | TX(Transaction) Table Slot |
Data Row A |
| data block | undo block | |
|---|---|---|
| ITL(Interested Transaction List) | ┬XID─> | TX(Transaction) Table Slot ┐UBA |
Data Row (new Image B) |
└UBA─> | Undo Record(Old Image A)<┘ |
ITL?
Interested Transaction List의 약자이며, transaction table이라고도 한다UBA?
Undo Block AddressConsistence Read?
Consistent? 일관된, 언행이 일치된, 모순이 없는| DML | 비고 | |||
|---|---|---|---|---|
| 1 | UPDATE savings_accounts | SET balance = balance - 500 | WHERE account = 3209 | Savings 계좌 금액 감소 |
| 2 | UPDATE savings_accounts | SET balance = balance + 500 | WHERE account = 3208 | Checking 계좌 금액 증가 |
| 3 | INSERT INTO journal | VALUES (journal_seq.NEXTVAL, ‘1B’, 3209, 3208, 500) | 트랜잭션 저널에 기록 | |
| 4 | COMMIT WORK | 트랜잭션 종료 |
lock?| lock | ||
|---|---|---|
| DML Lock | 데이터 보호. 테이블 락은 테이블 전체를 잠그고, 로우 락은 선택된 로우만 잠근다 | Row Lock(TX), Table Lock(TM) |
| DDL Lock | 스키마 오브젝트의 구조를 보호. 가령 테이블과 뷰의 데이터 사전 정의(Dictionary definition) | Exlusive DDL Locks, Share DDL Locks, Breakable Parse Locks |
| System Lock | data file 같은 내부 데이터베이스 구조 보호. |
Latches, Mutexes, Internal Locks |
deadlock?| 시간 | Session1 | Session2 | |
|---|---|---|---|
| t0 | UPDATE employees | UPDATE employees | 각 트랜잭션은 수정하려는 로우를 잠그고 있으므로 문제 없다 |
| SET salary = salary * 1.1 | SET salary = salary * 1.1 | ||
| WHERE employees_id = 100; | WHERE employees_id = 200; | ||
| 1 row updated. | 1 row updated. | 나중에 데드락으로 롤백할 때 이 시점의 변경 사항은 롤백하지 않는다 | |
| t1 | UPDATE employees | UPDATE employees | 데드락 발생 |
| SET salary = salary * 1.1 | SET salary = salary * 1.1 | employees_id=100은 Session1이 잠그고 있고, |
|
| WHERE employees_id = 200; | WHERE employees_id = 100; | employees_id=200은 Session2가 잠그고 있다 |
|
| t2 | ORA-00060: deadlock detected | Session1은 데드락 시그널을 받고 t1 시점의 UPDATE는 롤백된다 |
|
| while waiting for resource | 오직 한 세션만 데드락 에러를 받으며, 둘 중 한 세션이 받을 수 있다 | ||
| t3 | SQL> COMMIT; | t0 시점의 수정 사항을 커밋하고 Session1의 트랜잭션이 끝난다 |
|
| Commit complete. | t1 시점의 수정 사항은 커밋되지 않는다 |
||
| t4 | 1 row updated. | t1 시점에 Session1에 의해 막혔던 Session2의 UPDATE가 실행된다 |
|
| t5 | SQL> COMMIT; | t0과 t1 시점의 수정 사항이 커밋되고 Session2는 종료 |
|
| Commit complete. |
XID(위치 정보)를ITL에 저장SCN(시간관련정보)을트랜잭션 테이블과 ITL에 저장XID(시간관련정보)튜플 헤더에t_xmin, t_xmax 컬럼에 저장TRX_ID(시간관련정보)를레코드 헤더에 저장TRX_ID(시간관련정보)를언두 블록에 저장언두 세그먼트에 저장동일 데이터 페이지에 저장언두 세그먼트에 저장UBA(Undo Block Address)T_CTID(Current Tuple ID)Roll PointerRow offsetLine pointerDirectory Slott_nfomask 칼럼에 상태정보 업데이트언두 블록의 TRX_NO 컬럼에 TRX_ID(시간관련정보) 저장히스터리 리스트 등록TRX_SYS의 TRX_STRUCTURE 더블 링크트 리스트에서 제외언두 헤더에 위치한 트랜잭션 테이블. v$transactionpg_log 디렉토리 아래에 256 Kbyte의 clog 파일들언두 세그먼트의 언두 블록에 저장TRX_SYS의 TRX_STRUCTURE 더블 링크트 리스트| 위치정보 | 시간관련정보 | |
|---|---|---|
| Oracle | XID |
SCN |
| PostgreSQL | XID |
|
| MySQL/InnoDB | TRX_ID |
data block?
extent?
segment?
segment는 오직 하나의 테이블 스페이스에 속한다. 즉, 어떤 segment의 extent들도 모두 같은 테이블스페이스에 저장된다tablespace?
data file이 tablespace에 저장된다undo tablespace를 기반으로 하며, 롤백 세그먼트를 다양한 크기로 할당하기보다는, 언두 테이블스페이스의 형식으로 공간을 할당한다erDiagram
undo_tablespace ||--o{ undo_segments : has
undo_segments ||--o{ transaction-table : has
transaction-table {
string transaction_ID
}
SQL> UPDATE hr.employees SET salary=salary;
107 rows updated.
SQL> SELECT
XID AS "txn id",
XIDUSN AS "undo seg",
XIDSLOT AS "slot",
XIDSQN AS "seq", STATUS AS "txn status"
FROM V$TRANSACTION;
txn id undo seg slot seq txn status
---------------- ---------- ---------- ---------- ----------------
0600060037000000 6 6 55 ACTIVE
XID(공간 정보)와 SCN(시간관련정보)를 적절하게 조합하여 사용
XID:
Undo Segment Number + Slot + Sequence numberSCN(System Change Number)
출처:exem
XID(시간관련정보)를 t_xmin과 t_xmax를 적절하게 조합하여 사용
XID
t_xmin에 저장t_xmax에 저장Snapshop Structure에서 SELECT 시작 시점의 ACTIVE TX 리스트 관리해야 한다TRX_ID(시간관련정보)
페이지의 데이터 레코드에 저장TRX_NO
TRX_ID를TRX_NO 컬럼에 저장.TRX_NO’] = TRX_IDUp_Limit_ID, Low_Limit_ID, Active TX List에 의해 결정t_ctid는 New Version의 위치를 가리킨다t_ctid 컬럼에 저장된 New Version의 위치를 찾아간다SELECT XIDt_xmin의 XIDt_xmax의 XID블록 또는 페이지라 불리는 단위 구조에 저장블록 단위로 I/O블록의 크기는 8K 또는 16K 주로 사용하지만 내부 구조는 DBMS마다 다르며 구조에 따라 트랜잭션 처리 및 각 DBMS의 주요 특성 결정INSERT 시 블록 아래쪽부터 차례대로 저장블록 헤더에에는 새로운 레코드를 가리키는 포인터가 차례대로 생긴다10(Active) $\to$ 9(Committed)로 변경SCN 칼럼에 커밋 시점의 SCN 기록ITL: Flag, Lock, Scn/Fsc 칼럼을 커밋 시의 값으로 정리Lock Byte 칼럼을 커밋 시의 값으로 정리UPDATE 시
DELETE 되고INSERT 된다t_infomask 칼럼의 상위 4bits를 사용(0010(0x2))t_infomask 칼럼에서
DELETE 시의 DELETE bit와UPDATE 시의 DELETE bit를 구분| COMMAND | COMMIT 여부 | xmax invalid/aborted | xmax committed | xmin invalid/aborted | xmin committed | value |
|---|---|---|---|---|---|---|
INSERT |
X | 1 | 0 | 0 | 0 | $2^{3}$ = 8 |
INSERT |
O | 1 | 0 | 0 | 1 | $2^{3} + 2^{0}$ = 9 |
DELETE |
X | 0 | 0 | 0 | 1 | $2^{0}$ = 1 |
DELETE |
O | 0 | 1 | 0 | 1 | $2^{2} + 2^{0}$ = 5 |
FROZEN |
1 | 0 | 1 | 1 | $2^{3} + 2^{1} + 2^{0}$ = 11 = B(hex) |
Readview(Snapshop)?