Tablespace içerisinden büyük objelerin silinmesi durumunda disk üzerinde alan kazanımı olmadığı için tablespace’i recreate etme yoluna gidebiliriz. Bu durumda diskten alan kazanmanın yanında tablespace içerisinde bulunan objeler defragmente olup db üzerinde performans artışlarını beraberinde getirecektir. Tablespaceyi recreate etmenin aşamaları şu şekildedir:
- Yeni tablespace create etmek (bundan sonra TS_DATA_NEW olarak adlandırılacaktır)
- default_tablespace’i TS_DATA olan schemaların alter edilmesi ve gerekli quota ayarlarının yapılması.
- Varolan tablespace (TS_DATA olarak adlandırılacaktır) içerisindeki tüm objelerin move edilmesi.
- Tablo partition ve subpartitionların taşınması
- Lobların taşınması
- Lob partitionların taşınması
- İndexlerin taşınması
- Partitionlu indexlerin taşınması
- TS_DATA’yı offline konumuna almak
- Gerekli olması durumunda modify default attributes yapmak
- TS_DATA’yı drop etmek
- TS_DATA_NEW’i rename edip TS_DATA olarak değiştirmek.
- İndexlerin kontrolü
1. Create Tablespace
Yeni oluşturulacak TS_DATA_NEW tablespace için örnek komut aşağıdaki gibidir. Tabiki varolan tablespace üzerinde tanımlanan kota, yetki v.s gibi yetkilerin de varolan tablespace den alınıp yeni oluşturulan tablespaceye tanımlanması gerekmektedir. Aksi halde objeler taşındıktan sonra yetki problemleri nedeniyle başka sorunlara sebebiyet verebiliriz.
CREATE TABLESPACE TS_DATA_NEW
DATAFILE '+DATA'
SIZE 31G;
2. Default Tablespace Değiştirmek
Default tablespacesi TS_DATA olarak ayarlanmış kullanıcıların yeni tablespace tanımını ayarlamak için aşağıdaki komutu kullanabilirsiniz.
SELECT username,default_tablespace,'alter user '||username||' default tablespace TS_DATA_NEW; alter user '||username||' quota unlimited on TS_DATA_NEW;' FROM dba_users WHERE default_tablespace='TS_DATA';
3. Objelerin Taşınması
Varolan tablespace (TS_DATA) içerisindeki tüm objeler yeni tablespace içerisine taşınacaktır.
3.1. Tablo Partitionların Taşınması
Tablo partition ve sub partitionların taşınması için örnek komutaşağıdaki şekildedir. Burada klasik yöntem ile taşınacaktır. Sistemin kesintiye uğramaması için redef gibi taşıma yöntemlerini de tercih edebilirsiniz.
select 'ALTER TABLE '||table_owner||'.'||table_name||' MOVE PARTITION '||partition_name||' TABLESPACE TS_DATA_NEW parallel 8;'
from dba_tab_partitions
where tablespace_name = 'TS_DATA';
Subpartitionların taşınması aşağıdaki şekilde gerçekleştirilebilir.
select 'ALTER TABLE '||table_owner||'.'||table_name||' MOVE SUBPARTITION '||subpartition_name||' TABLESPACE TS_DATA_NEW parallel 8;'
from dba_tab_subpartitions
where tablespace_name = 'TS_DATA';
3.2. Lob ve Lobparitionların Taşınması
Loblar aşağıdaki şekilde taşınabilir.
SELECT owner,table_name,COLUMN_NAME,SEGMENT_NAME,TABLESPACE_NAME, 'alter table '||owner||'.'||table_name||' move lob ('||COLUMN_NAME||') store as '||SEGMENT_NAME||' (tablespace TS_DATA_NEW);' from dba_lobs where tablespace_name ='TS_DATA';
Lob partitionlar aşağıdaki şekilde taşınabilir.
SELECT 'alter table ' || TABLE_OWNER || '.' || TABLE_NAME || ' move partition ' || partition_name || ' lob (' || COLUMN_NAME || ') store as (tablespace TS_DATA_NEW);'
FROM DBA_LOB_PARTITIONS
WHERE TABLESPACE_NAME = 'TS_DATA' ;
3.3. İndexlerin Taşınması
İndexler aşağıdaki şekilde taşınabilir.
select distinct 'ALTER INDEX '||owner||'.'||index_name||' REBUILD ONLINE TABLESPACE TS_DATA_NEW PARALLEL 16; ALTER INDEX '||owner||'.'||index_name||' NOPARALLEL;'
from dba_indexes
where tablespace_name = 'TS_DATA';
İndex partitionlar aşağıdaki şekilde taşınabilir.
select 'ALTER INDEX '||index_owner||'.'||index_name||' REBUILD PARTITION '||partition_name||' TABLESPACE TS_DATA_NEW ONLINE PARALLEL 16; ALTER INDEX '||index_owner||'.'||index_name||' NOPARALLEL;' from dba_ind_partitions where tablespace_name = 'TS_DATA';
3.4. Objeleri Otomatik Taşımak için Script
Yukarıdaki taşıma adımlarını teker teker yapmak yerine aşağıdaki komutu kullanıp tablespace içerisindeki tüm objeleri sırası ile taşıyabilirsiniz. Bu komut size taşınacak objelerin scriptini öncelik sırasına göre verecektir.
SELECT * FROM (SELECT 0 sira, owner, table_name, 'alter table ' || owner || '.' || table_name || ' modify default attributes tablespace TBS_EXISTING ;' move_sql FROM dba_part_tables WHERE DEF_TABLESPACE_NAME = '&&tbsname' UNION ALL SELECT 1 sira, owner, table_name, 'alter index ' || owner || '.' || index_name || ' modify default attributes tablespace TBS_EXISTING ;' move_sql FROM dba_part_indexes WHERE DEF_TABLESPACE_NAME = '&&tbsname' UNION ALL SELECT 2 sira, owner, table_name, 'ALTER TABLE ' || owner || '.' || table_name || ' MOVE TABLESPACE TBS_EXISTING parallel 8;' move_sql FROM dba_tables WHERE tablespace_name = '&&tbsname' UNION ALL SELECT 3 sira, table_owner owner, table_name, 'ALTER TABLE ' || table_owner || '.' || table_name || ' MOVE PARTITION ' || partition_name || ' TABLESPACE TBS_EXISTING parallel 8;' move_sql FROM dba_tab_partitions WHERE tablespace_name = '&&tbsname' UNION ALL SELECT 4 sira, owner, table_name, 'alter table ' || owner || '.' || table_name || ' move lob (' || COLUMN_NAME || ') store as ' || SEGMENT_NAME || ' (tablespace TBS_EXISTING );' move_sql FROM dba_lobs WHERE tablespace_name = '&&tbsname' UNION ALL SELECT 5 sira, owner, table_name, 'ALTER INDEX ' || owner || '.' || index_name || ' REBUILD TABLESPACE TBS_EXISTING PARALLEL 16; ALTER INDEX ' || owner || '.' || index_name || ' NOPARALLEL;' move_sql FROM dba_indexes WHERE tablespace_name = '&&tbsname' UNION ALL SELECT 6 sira, i.owner, i.table_name, 'ALTER INDEX ' || p.index_owner || '.' || p.index_name || ' REBUILD PARTITION ' || p.partition_name || ' TABLESPACE TBS_EXISTING PARALLEL 16; ALTER INDEX ' || p.index_owner || '.' || p.index_name || ' NOPARALLEL;' FROM dba_ind_partitions p, dba_indexes i WHERE p.tablespace_name = '&&tbsname' AND p.index_owner = i.OWNER AND p.index_name = i.index_name) aa ORDER BY 2, 3, 1;
4. Tablespace’nin Offline Duruma Getirilmesi
Aşağıdaki şekilde TS_DATA’yı offline konuma getirebiliriz. Burada normal şeçeneğini kullanmak mantıklı olabilir. Çünkü tablespace içerisinde unutulan bir obje olduğu durumlarda uyarı verecektir.
ALTER TABLESPACE TS_DATA OFFLINE NORMAL/IMMEDIATE;
5. Modify Default Attribute
Varolan TS_DATA tablespace’i drop ettikten sonra dba_part_tables ve dba_part_indexes viewlerinden taşınan objelerin ownerleri altında bulunan objelerin kontrolünün yapılması gerekmektedir. Tablespace drop edildikten sonra bu viewlerin içerisinde bulunan DEF_TABLESPACE_NAME kolonunda bulunan değerlerin bazınlar veya bir çoğu “_$deleted$25$3” gibi bir değere dönebilir.
Bunun bu şekilde değişmesinin nedeni partitionlu tablo ve indexlerin move edilmesi sonucunda metadata diyebileceğimiz adresin değişmemesinden kaynaklanmaktadır. Buradan bu kayıtları bulup aşağıdaki şekilde alter edilmesi gerekmektedir. Aksi halde insert gibi transactionlarda “ORA-00959: tablespace ‘_$deleted$25$3’ does not exist” gibi hatalar alabilirsiniz.
alter index SCHEMA.INDEX_NAME modify default attributes tablespace TBS_EXISTING;
alter table SCHEMA.TABLE_NAME modify default attributes tablespace TBS_EXISTING;
6. Drop Tablespace
Varolan tablespace aşağıdaki şekilde drop edilebilir.
DROP TABLESPACE TS_DATA INCLUDING CONTENTS AND DATAFILES;
7. Rename Tablespace
Varolan tablespace aşağıdaki şekilde rename edilebilir. Oracle’nin rename tablespace komutunu 11g ve üzeri sürümlerde desteklediğini unutmamak gerekir.
ALTER TABLESPACE TS_DATA_NEW RENAME TO TS_DATA;
Bunun çalıştırılmasının ardından 2. aşamada değiştirdiğimiz default tablespace değeri de otomatik değişecektir. Yine de her ihtimale karşı dba_users view’inden kontrol edilmesi daha sağlıklı olacaktır.
8. İndexlerin Kontrolü
Son olarak indexlerin kontrolünü yapmak gerekiyor. Aşağıdaki şekilde yapılabilir.
select * from dba_indexes where tablespace_name = 'TS_DATA' and status <> 'USABLE';
select * from dba_ind_partitions where tablespace_name = 'TS_DATA' and status <> 'USABLE';