일반적으로 테이블을 읽는다는 것은 해당 테이블의 처음부터 HWM이 가리키는 곳까지 읽는 것을 말한다. 여기서 HWM이란 고수위라고도 하며, 이것은 테이블의 데이터가 어디까지 들어있다는 것을 가리키는 일종의 포인터이고, 자동적으로 HWM의 뒤는 데이터가 들어있지 않은 공간이라는 것이 확인된다.

그러나 테이블에 delete작업이 일어나면 HWM도 같이 내려가야 하지만 실제로 보면 그대로이다. 이렇게 되면 테이블에 데이터는 조금밖에 들어있지 않은데, 테이블에 용량이 부족한 경우가 생길 수 있다. 이때는 HWM을 내려주는 조치를 해주어야 한다.

조치 방법은 크게 두가지가 있는데,
첫번째 방법은 해당 테이블을 export받아놓고 테이블을 드랍시킨 후 다시 import를 이용하여 들이부으면 된다.
두번째 방법은 해당 테이블을 잠시 다른 테이블스페이스로 이동한 후 다시 원래 테이블스페이스로 이동시켜주면 된다. 하지만 두번째 방법의 주의사항은 만약 해당 테이블에 인덱스가 걸려 있었다면 꼭 이동시킨 후 인덱스 리빌드 작업 또한 해주어야 한다.


여기서는 두번째 방법을 테스트 해보기로 한다.
users테이블스페이스에 테스트용 테이블 tt05를 생성
SQL> create table tt05 (no number, name varchar2(20)) tablespace users;

tt05테이블에 500000건의 데이터를 입력
SQL> begin
   for i in 1..500000 loop
   insert into tt05 values (i, dbms_random.string('A', 15));
   end loop;
   commit;
   end;
   /

tt05테이블 용량 확인(여기서는 테이블크기 대략 15M정도로 확인)
SQL> select sum(bytes)/1024/1024 MB
   from user_segment
   where segment_name='TT05';

SQL> save sum.sql

데이터 건수 500000건 확인
SQL> select count(*) from tt05;

테이블에서 전체 데이터 건수 중 반을 삭제함
SQL> delete from tt05
   where no between 1 and 250000;

데이터 건수 250000건 확인
SQL> select count(*) from tt05;

용량 조회하면 원래 테이블 15M용량인데, 반절을 삭제했으니 우리가 생각하기로 7.5M정도로 줄어들었을 것으로 생각하지만 실제 조회해보니 15M가 나옴.
SQL> @sum

해당 테이블을 분석함.(통계정보만 생성하는 것이지 HWM을 앞으로 당기지는 않음)
SQL> analyze table tt05 compute statistics;

잠시 옮길 ts_new테이블스페이스를 생성
SQL> create tablespace ts_new
   datafile '/dev/raw/raw28';

해당 테이블을 새로 생성한 테이블스페이스로 옮김.
SQL> alter table tt05 move tablespace ts_new;

이제 테이블 용량을 조회해보면 7.5M로 줄어든 것을 확인 가능.
SQL> @sum

다시 원래 테이블스페이스로 옮겨줌.
SQL> alter table tt05 move tablespace users;

SQL> @sum



[Tip] 위의 예에서 잠시 보았던 것처럼 로우디바이스를 사용한다 해도 사용할 때에는 똑같이 해주면 되는데, 몇가지 다른 점이 있다면 OS상에서 데이터파일 복원 시에 dd명령을 사용해야 하고, 테이블스페이스 생성시 autoextend on 옵션을 사용할 수 없다.
그 이유는 로우디바이스는 그 자체가 하나의 디스크이기 때문에 extent가 꽉 찼다는 등의 에러가 발생했을 시에는 로우디바이스용으로 디스크를 하나 더 추가시킨 후 add datafile 명령어를 이용해 추가시켜주면 된다.

Posted by 겨울섬
,