강좌

HOME > 강좌 >
강좌| 리눅스 및 오픈소스에 관련된 강좌를 보실 수 있습니다.
 
tablespace의 coalesce
조회 : 3,131  


작성자: 강명규
OS: Linux 2.4.10
Oralce: Oracle EE 8.1.7

db_block_size: 8kbytes



extent가 할당/해제되다 보면 테이블스페이스내 free한 extent가 연속적이지 못하게 된다.
이런 것들을 coalesce(합병)해주면 I/O를 줄일 수 있고, 시간또한 절약될 것이다.
보통 coalsce는 백그라운드 프로세스인 SMON(System Monitor)가 자동으로 실행한다.
DBA는 수동으로 'alter tablespace AAA coalesce'로 수동합병을 할 수 있다.

추가분(2002-12-15)
dictionary-managed tablespace의 coalesce
별다른 일이 없다면, 자신의 테이블스페이스는 dictionary-managed tablespace이다.
이와 달리, locally-managed tablespace라는 것이 있는데 이에 대한 내용은 이 사이트내 오라클 메뉴 
'Locally Managed Tablespace사용하기'를 참고하기 바란다. 참고로 locally-managed tablespace는 coalesce가 필요치 않다.
coalesce(코우얼레스: 마지막 음절에 강세가 있다. -.-)라는 말은 병합/합체라는 뜻이다. 
테이블스페이스내에 free extent는 연속된 free block들의 집합으로 구성된다. 
테이블스페이스의 세그먼트에 extent를 할당할 경우, 요청된 extent의 크기와 가장 근접한 free extent가 사용되어진다. 
세그먼트가 drop되면 세그먼트에 할당되었던 extent는 deallocated되어져 free한 상태로 된다. 
하지만, 인접한 free extent들이 즉시 하나의 큰 free extent들로 재결합되지는 않는다. 
이로 인해 단편화가 발생하며 이는 커다란 extent를 할당하는 것을 어렵게 한다.

단편화는 몇가지 방법으로 처리될 수 있다.

1. 세그먼트에 새로운 extent를 할당하려고 하면, 오라클은 우선 이 새로운 extent에 맞는 크기의 free extent를 검색한다. 
   만일 충분히 큰 free extent를 발견하지 못한다면, 오라클은 테이블스페이스내의 인접한 free extent들을 병합(coalesce)하고 난뒤, 
   다시 검색하게 된다. 이 병합과정은 적당한 크기의 free extent를 찾지 못한다면, 오라클에 의해 수행된다.

2. SMON 백그라운드 프로세스는 해당 테이블스페이스가 dictionary-managed tablespace이고, pctincrease가 0이 아니라면, 
   주기적으로 이웃한 free extent들을 병합한다. SMON의 병합작업은 오버헤드를 야기할 수 있으므로, 몇몇 DBA들은 
   PCTINCREASE값을 0로 설정하고, DBA 스스로 필요한 시기에 병합처리(coalesce)를 하기도 한다.

3. PCTINCREASE값이 0이 아닌 세그먼트가 drop/truncate되어지면, 제한된 형태의 병합과정이 수행된다. 

4. 사용자가 ALTER TABLESPACE .. COALESCE문장을 수행하여 수동으로 인접한 free extent들을 병합할 수 있다.

팁)
만일 테이블스페이스의 모든 extent가 동일한 크기를 가진다면 coalesce를 해줄 필요는 없다.
colaesce는 data extent에는 적용되지 않는다. 즉, data extent가 단편화되어 있는 경우 coalesce로
이 단편화된 것을 제거하지는 못한다. 이때는 exp/imp로 해결하면 된다.
추가분(2002-12-15)

테스트를 위해 ts_test라는 테이블스페이스를 생성
SQL> create tablespace ts_test
  2  datafile '/u01/app/oracle/oradata/dev2/ts_test01.dbf' size 1m
  3  autoextend on
  4  next 256k maxsize 2m;

생성된 테이블스페이스를 dba_free_space에서 조회해 보자
SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26          2    1040384        127           26


dba_free_space에서 주의깊게 볼 컬럼은 다음과 같다.
FILE_ID:  extent가 속한 파일식별번호
BLOCK_ID: free한 extent의 시작블럭번호
BLOCKS:   free한 블럭수
BYTES:    사용가능한 크기(BLOCKS x db_block_size)


테스트를 위한 notice테이블 생성
SQL> create table notice(
  2  regdate date,
  3  title   varchar(100),
  4  content varchar(2000))
  5  storage( initial 10k next 10k minextents 2 pctincrease 50)
  6  tablespace ts_test;

notice테이블에 1000개의 데이터를 INSERT
SQL> @d:	emp	emp_data.sql	

notice테이블을 ts_test에 생성하고 나서 이 테이블스페이스의 공간(extent)사용상황을 보기위해 dba_extents에 질의해 본다.
SQL> select extent_id, block_id, blocks, bytes
  2  from dba_extents
  3  where segment_name='NOTICE' and owner='SYSTEM';

 EXTENT_ID   BLOCK_ID     BLOCKS      BYTES
---------- ---------- ---------- ----------
         0          2          2      16384
         1          4          2      16384
         2          6          3      24576
         3          9          5      40960
         4         14         10      81920

dba_extents에서 주의깊게 볼 컬럼은 다음과 같다.
BLOCK_ID: 할당된 extent의 시작위치
BLOCKS:   extent내에 할당된 block수
BYTES:    extent의 크기


위에서 보듯이 우리가 insert한 데이터가 continuous하게 insert되었음을 알 수 있다.
extent는 0,1,2,3,4로 총 5개가 존재한다.
이 5개의 extent는 위의 block_id, blocks컬럼값을 보면 알 수 있듯, 순서대로 인접하게 존재한다.


ts_test를 dba_free_space에 조회해 보면 block_id, bytes, blocks가 감소되어 free한 공간이 줄어들었음을 알 수 있다.
SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26         24     860160        105           26

테이블을 drop하고 다시 조회해보면 처음에 조회했을때와 같이 free한 공간이 다시 돌아왔음을 알 수 있다.
SQL> drop table notice;
SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26          2    1040384        127           26


위에서는 단편화가 발생하지 않는 경우를 보인 것이고, 이제부터 단편화되었을때의 예를 보이겠다.
우선 notice, notice1, notice2 3개의 테이블을 다시 생성하겠다.

SQL> create table notice(
  2  regdate date,
  3  title   varchar(100),
  4  content varchar(2000))
  5  storage( initial 10k next 10k minextents 2 pctincrease 50)
  6  tablespace ts_test;

SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26          6    1007616        123           26

잠 와서 설명을 달기 힘들다. 다음에 달아야지.. 

SQL> create table notice1
  2  storage( initial 4k)
  3  tablespace ts_test
  4  as select * from notice;

SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26          8     991232        121           26

SQL> create table notice2
  2  storage( initial 10k next 10k pctincrease 0)
  3  tablespace ts_test
  4  as select * from notice;

SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26         10     974848        119           26

SQL> drop table notice1;

SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26         10     974848        119           26
TS_TEST                 26          6      16384          2           26

SQL> @d:	emp	emp_data.sql

SQL> insert into notice2 select * from notice;
SQL> /
SQL> /
SQL> /
SQL> /
SQL> COMMIT;
SQL> select extent_id, block_id, blocks, bytes
  2  from dba_extents
  3  where segment_name='NOTICE2' and owner='SYSTEM';

 EXTENT_ID   BLOCK_ID     BLOCKS      BYTES
---------- ---------- ---------- ----------
         0          8          2      16384
         1          6          2      16384
         2         28          2      16384
         3         30          2      16384
         4         32          2      16384
         5         34          2      16384
         6         36          2      16384
         7         38          2      16384
         8         40          2      16384
         9         42          2      16384
        10         44          2      16384
        11         46          2      16384
        12         48          2      16384
        13         50          2      16384
        14         52          2      16384
        15         54          2      16384
        16         56          2      16384
        17         58          2      16384
        18         60          2      16384
        19         62          2      16384
        20         64          2      16384
        21         66          2      16384
        22         68          2      16384
        23         70          2      16384
        24         72          2      16384
        25         74          2      16384
        26         76          2      16384
        27         78          2      16384
        28         80          2      16384
        29         82          2      16384

30 개의 행이 선택되었습니다.

SQL> select * from dba_free_space
  2  where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26         84     368640         45           26

SQL> drop table notice;
SQL> drop table notice2;

SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26         74      16384          2           26
TS_TEST                 26          2      32768          4           26
TS_TEST                 26         84     368640         45           26
TS_TEST                 26         10     147456         18           26
TS_TEST                 26         72      16384          2           26
TS_TEST                 26         76      16384          2           26
TS_TEST                 26         78      16384          2           26
TS_TEST                 26         80      16384          2           26
TS_TEST                 26         82      16384          2           26
TS_TEST                 26         56      16384          2           26
TS_TEST                 26         58      16384          2           26
TS_TEST                 26         60      16384          2           26
TS_TEST                 26         62      16384          2           26
TS_TEST                 26         64      16384          2           26
TS_TEST                 26         66      16384          2           26
TS_TEST                 26         68      16384          2           26
TS_TEST                 26         70      16384          2           26
TS_TEST                 26         40      16384          2           26
TS_TEST                 26         42      16384          2           26
TS_TEST                 26         44      16384          2           26
TS_TEST                 26         46      16384          2           26
TS_TEST                 26         48      16384          2           26
TS_TEST                 26         50      16384          2           26
TS_TEST                 26         52      16384          2           26
TS_TEST                 26         54      16384          2           26
TS_TEST                 26          8      16384          2           26
TS_TEST                 26          6      16384          2           26
TS_TEST                 26         28      16384          2           26
TS_TEST                 26         30      16384          2           26
TS_TEST                 26         32      16384          2           26
TS_TEST                 26         34      16384          2           26
TS_TEST                 26         36      16384          2           26
TS_TEST                 26         38      16384          2           26

33 개의 행이 선택되었습니다.

SQL> select extent_id, block_id, blocks, bytes
  2  from dba_extents
  3  where segment_name='NOTICE2' and owner='SYSTEM';

선택된 레코드가 없습니다.

SQL> alter tablespace ts_test coalesce;

SQL> select * from dba_free_space where tablespace_name='TS_TEST';

TABLESPACE_NAME    FILE_ID   BLOCK_ID      BYTES     BLOCKS RELATIVE_FNO
--------------- ---------- ---------- ---------- ---------- ------------
TS_TEST                 26          2    1040384        127           26


Copyleft(C) 명규의 DBAKOREA All rights free 


[원글링크] : https://www.linux.co.kr/home2/board/subbs/board.php?bo_table=lecture&wr_id=729


이 글을 트위터로 보내기 이 글을 페이스북으로 보내기 이 글을 미투데이로 보내기

 
강명규
홈페이지 : http://dbakorea.pe.kr/

e-mail : myunggyu골뺑이orgio.net