개요
Tibero에서 SQL 수행 시, 동일한 쿼리 내에서도 Current 모드와 Consistent Read 모드가 함께 사용되는 경우가 있습니다.
본 글에서는 계좌 테이블(acc1, acc2)을 활용하여 트랜잭션 처리 중 동일 쿼리 내에서 두 가지 읽기 모드가 어떻게 적용되는지를 확인하는 과정을 안내합니다.
방법
예제 테이블 데이터 생성
drop table acc1;
drop table acc2;
create table acc1(accno number, amt number, tamt number);
create table acc2(accno number, amt number, tamt number);
insert into acc1 select level, 1000, 2000 from dual connect by level <= 100000;
insert into acc2 select level, 1000, 2000 from dual connect by level <= 100000;
ALTER TABLE acc1 ADD CONSTRAINT PK_acc1_accno PRIMARY KEY(accno);
ALTER TABLE acc2 ADD CONSTRAINT PK_acc2_accno PRIMARY KEY(accno);
exec dbms_stats.gather_table_stats('TIBERO','ACC1',estimate_percent=>100,method_opt=>'FOR ALL COLUMNS SIZE 254');
exec dbms_stats.gather_table_stats('TIBERO','ACC2',estimate_percent=>100,method_opt=>'FOR ALL COLUMNS SIZE 254');
SQL
복사
읽기 모드가 혼합된 UPDATE 실행
다음 예제를 통해 계좌1.잔고는 Current 모드, 계좌2.잔고는 Consistent Read 모드로 읽힙니다.
update 계좌1
set 계좌1.총잔고
= 계좌1.잔고 + (select 계좌2.잔고 from 계좌2 where 계좌2.계좌번호=계좌1.계좌번호)
where 계좌1.계좌번호=7788;
SQL
복사
•
update중 계좌2에 변경이 발생해도 update, delete 문이 시작되는 시작점(변경전) 값을 사용합니다.
•
다음 실행예제에서 Session B 의 UPDATE 구문을 통해 계좌1.총잔고는 1100+1000즉 2100 이 됩니다.
No | Session A | Session B |
1 | SQL> select acc1.amt acc1_amt,
acc2.amt acc2_amt,
acc1.tamt acc1_tamt,
acc1.amt+acc2.amt sum_amt
from acc1, acc2
where acc1.accno=7788
and acc2.accno=acc1.accno;
ACC1_AMT ACC2_AMT ACC1_TAMT SUM_AMT
------------ -------------- -------------- ------------ 1000 1000 2000 2000 | |
2 | SQL> update acc1
set amt=amt+100
where accno=7788; | |
3 | SQL> update acc2
set amt=amt+200
where accno=7788; | |
4 | SQL> select acc1.amt acc1_amt,
acc2.amt acc2_amt,
acc1.tamt acc1_tamt,
acc1.amt+acc2.amt sum_amt
from acc1, acc2
where acc1.accno=7788
and acc2.accno=acc1.accno;
ACC1_AMT ACC2_AMT ACC1_TAMT SUM_AMT
------------ -------------- -------------- ------------ 1100 1000 2000 2000 | SQL> select acc1.amt acc1_amt,
acc2.amt acc2_amt,
acc1.tamt acc1_tamt,
acc1.amt+acc2.amt sum_amt
from acc1, acc2
where acc1.accno=7788
and acc2.accno=acc1.accno;
ACC1_AMT ACC2_AMT ACC1_TAMT SUM_AMT
------------ -------------- -------------- ------------ 1000 1000 2000 2000 |
5 | SQL> update acc1
set acc1.tamt = acc1.amt
+(select acc2.amt
from acc2
where acc2.accno = acc1.accno)
where acc1.accno = 7788; | |
6 | (no.2) 에서 발생한 row lock (acc1 테이블의
accno=7788 에 해당하는 row) 을 대기함 | |
7 | SQL> commit; | |
8 | - (no.6)commit 이후에 update 수행됨.
- acc1.amt 는 update 대상 row 이므로, current 읽기 모드 수행(acc1.amt 값은 1100 사용함).
- acc2.amt 는 consistent 읽기 모드 수행(acc2.amt 값은 1000 사용함) | |
9 | SQL> select acc1.amt acc1_amt,
acc2.amt acc2_amt,
acc1.tamt acc1_tamt,
acc1.amt+acc2.amt sum_amt
from acc1, acc2
where acc1.accno=7788
and acc2.accno=acc1.accno;
ACC1_AMT ACC2_AMT ACC1_TAMT SUM_AMT
------------ -------------- -------------- ------------ 1100 1200 2100 2300 | SQL> select acc1.amt acc1_amt,
acc2.amt acc2_amt,
acc1.tamt acc1_tamt,
acc1.amt+acc2.amt sum_amt
from acc1, acc2
where acc1.accno=7788
and acc2.accno=acc1.accno;
ACC1_AMT ACC2_AMT ACC1_TAMT SUM_AMT
------------ -------------- -------------- ------------ 1100 1200 2100 2300 |
10 | SQL> commit; | |
11 | SQL> select acc1.amt acc1_amt,
acc2.amt acc2_amt,
acc1.tamt acc1_tamt,
acc1.amt+acc2.amt sum_amt
from acc1, acc2
where acc1.accno=7788
and acc2.accno=acc1.accno;
ACC1_AMT ACC2_AMT ACC1_TAMT SUM_AMT
------------ -------------- -------------- ------------ 1100 1200 2100 2300 | SQL> select acc1.amt acc1_amt,
acc2.amt acc2_amt,
acc1.tamt acc1_tamt,
acc1.amt+acc2.amt sum_amt
from acc1, acc2
where acc1.accno=7788
and acc2.accno=acc1.accno;
ACC1_AMT ACC2_AMT ACC1_TAMT SUM_AMT
------------ -------------- -------------- ------------ 1100 1200 2100 2300 |
참고
Consistent Mode
•
SQL Trace 명칭: query
•
tbSQL Autotrace 명칭: consistent gets
•
TSN 확인 과정을 거치며 읽기 일관성이 보장된 상태에서 데이터 블록을 읽는 방식입니다.
•
대부분의 SELECT 쿼리가 여기에 해당되며, 쿼리가 시작된 시점을 기준으로 일관성 있게 읽어 들이며 읽는 도중에 값이 바뀌더라도 쿼리 시작시점의 값으로 읽습니다.
•
데이터 블록을 읽을 때 TSN(Tibero System Number) 값을 확인하게 되며, 이 값이 변경되었다면 TSN 번호가 증가합니다. 이 경우, Undo Segment에서 과거의 블록을 읽어오는 CR(Consistent Read) 블록 작업이 발생하며, CR 블록이 사용됩니다.
•
SQL AUTOTRACE에서는 consistent gets로 표시됩니다.
•
current 블록을 읽더라도 Consistent 모드로 접근할 경우에는 autotrace 상에서 역시 consistent gets로 집계됩니다.
Current Mode
•
SQL trace 명칭: current
•
tbSQL autotrace 명칭: db block gets
•
쿼리 시작 시점이 아닌, 실제 블록에 접근하는 그 시점의 최종값을 읽어들이는 방식입니다.
•
주로 아래와 같은 상황에서 발생합니다.
- DML 수행 시
- 디스크 소트가 필요할 정도의 대용량 정렬 작업 시
- SELECT FOR UPDATE 수행 시
- Table Full Scan 중 세그먼트의 익스텐트 정보를 읽는 경우