ORACLE修改表空間方法

一、使用imp/exp。先導出源庫,再創建新庫把表空間創建好,然後再導入。(據說這樣可以,前提是新的庫裏面不能有與源庫相同名字的表空間。有待驗證!) 

二、使用腳本進行修改。據目前所瞭解,正長情況下需要修改表的空間表的索引的空間,如果涉及到BOLB字段的表,修改的方式又不一樣了! 
正常情況下的修改腳本: 
1.修改表的空間 
alter table TABLE_NAME move tablespace TABLESPACENAME 

查詢當前用戶下的所有表 
select 'alter table  '|| table_name ||'  move tablespace tablespacename;'  from user_all_tables; 

2.修改表的索引的空間 
alter index INDEX_NAME rebuild tablespace TABLESPACENAME 

查詢當前用戶下的所有索引 
select 'alter index '|| index_name ||' rebuild tablespace tablespacename;' from user_indexes; 

可以使用腳本執行查詢的結果,這樣就可以批量處理! 

不正常情況即含有BLOB字段的表: 
參考下面的文檔 

本人已經執行過,是可行的,但是不知道有沒有漏掉數據庫中其它對象。是否還存在有對象的表空間需要修改,需要進一步發現或有數據庫高手幫忙講解則不勝感激!目前的修改在項目中還沒有出現問題! 

在移植看注意研究了下ORACLE ALTER TABLE MOVE 的語法: 

       ALTER TABLE table_name MOVE [ONLINE] tablespace_name; 
通過上面的語句可以移植表到新表空間, 

如果要移植LOB字典需要參考以下語法: 
ALTER TABLE table_name LOB (lob_item) STORE AS [lob_segment] 
      ( 
        TABLESPACE tablespace_name 
                   (STORAGE.....) 
           ENABLE|DISABLE STORAGE IN ROW 
           CHUNK integer 
           PCTVERSION integer 
            RETENTION 
            FREEPOOLS integer 
            CACHE|NOCACHE|CACHE READS 
           INDEX lobindexname 

(TABLESPACE tablesapce_name 

((STORAGE.....)) 


.... 

註解: 

LOB (lob_item):表中的lob字段 
STORE AS [lob_segment]:每個lob字段在表創建後系統都會自動單獨創建一個段,可以通過這個參數手動指定一個段名
   tablespace_name:LOB字段新的存儲表空間 
(STORAGE.....):指定tablespace_name的存儲屬性 
    ENABLE STORAGE IN ROW:如果設置了enable storage in row 那麼oracle會自動將小於4000bytes的數據存儲在行內, 這是ORACLE的默認值,對於大於4000字節的lob字段保存在lob段(同disable storage in row),在表段將保留36-84字節的控制信息。對於disable storage in row,Oracle將lob字段分開保存在lob段中,而僅僅在行位置保留20字節的指針。對於相當於disable storage in row的這部分(也就是單獨保存在LOB段的這部分數據),UNDO僅僅是記錄指針與相關lob索引改變,如果發生更新操作等DML操作,原始數據將保留在LOB段。 

    DISABLE STORAGE IN ROW:如果DISABLE這個屬性,那麼lob數據會在行外存儲,行內只存儲該lob值得指針,而且這個屬性在表 
創建後只能在MOVE表時纔可以被改變 
    CHUNK:是一個很特別的屬性,對一次LOB數據的操作(插入或更新),因該分配多少存儲空間,指定的值最好是數據庫塊的倍數,而且指定的值不能大於表空間區間中NEXT的值, 要不然ORACLE會return一個錯誤,如果以前已經設置這個值了,那麼在後期指定的值是不能被改變的。 

storage as ( CHUNK bytes )表示對於disable storage in row的這部分,最小的LOB塊的大小,必須是數據庫塊(DB_BLOCK_SIZE)的整數倍。一個chunk最多隻保留一行LOB數據,也就是說,如果你設置了32K的CHUNK,但是如果LOB字段大小隻有4K,也將佔用32K的空間 

storage as(cache|nocahce)表示是否允許lob段經過buffer cache並緩存。默認是nocache,表示直接讀與直接寫,不經過數據庫的data buffer。所以,默認情況下,對於單獨保存在LOB段的這部分數據,在發生物理讀的時候,是直接讀,如direct path read (lob) 

storage as(nocache logging |nocache nologging),logging/nologging屬性只對nocache方式生效,默認是logging,如果是nologging方式,對於 保存在行外的log部分,在update等DML操作時將不記錄redo日誌。 

    PCTVERSION integer、RETENTION:都是ORACLE用來管理LOB字段鏡像數據的。在LOB 數據的更新過程中, 
ORACLE沒有用UNDO TABLESPACE空間,而是從LOB字段所在的表空間裏劃分一段空間來做鏡像空間的, 
這個空間的大小由PCTVERSION參數控制,默認值爲10,代表劃分表空間的10%作爲鏡像空間, 
每個鏡像空間的單元大小由CHUNK參數指定,pctversion可以使用在manual undo mode和automatic undo mode 環境中. 
retention應用了automatic undo mode中的undo_retention通過時間來管理lob鏡像空間. 
pctversion和retention不能同時被指定.建議數據庫在automatic undo mode下使用retention參數。 
FREEPOOLS integer:給LOG segment指定free list.RAC環境下integer爲實例的個數.單實例環境下爲1.在automatic undo mode下oracle默認採用 
FREEPOOLS來管理空閒塊列表。除非我們在表的storage配置中指定了freelist groups參數. 
CACHE|NOCACHE|CACHE READS:指定lob塊是否在database buffer中緩存. 
INDEX lobindexname (TABLESPACE tablesapce_name ((STORAGE.....):給lob列指定索引存儲參數 
舉例: 
SQL> show parameter db_create_file_dest 

SQL> create tablespace test datafile size 100M autoextend off; 
SQL> create table test(a varchar2(100), b clob, d blob) pctfree 10 tablespace test; 

SQL> desc test 
SQL> SELECT segment_name,tablespace_name,segment_type FROM dba_segments WHERE tablespace_name='TEST'; 

我們發現每個LOB字段單獨有一個LOGSEGMENT和LOBINDEX; 

SQL> set linesize 200 
col table_name format a5 
col column_name format a5 
SELECT b.table_name, 
a.segment_name, 
b.index_name, 
a.segment_type, 
b.column_name, 
a.tablespace_name, 
b.chunk, 
b.cache, 
b.freepools, 
b.pctversion, 
b.retention 
FROM dba_segments a,dba_lobs b 
WHERE a.segment_name = b.segment_name 
AND a.tablespace_name = 'TEST' 


SQL> 

從上面的結果我們可以觀察到LOB字段的各個屬性. 
下面我們對LOB字段move到另一個表空間 

SQL> create tablespace lob_test datafile size 100M autoextend off; 

SQL> ALTER TABLE TEST MOVE LOB(B) STORE AS TEST_B ( 
TABLESPACE lob_test 
DISABLE STORAGE IN ROW 
CHUNK 16384 
RETENTION 
FREEPOOLS 1 
NOCACHE); 
SQL> ALTER TABLE TEST MOVE LOB(D) STORE AS TEST_D ( 
TABLESPACE lob_test 
DISABLE STORAGE IN ROW 
CHUNK 16384 
RETENTION 
FREEPOOLS 1 
NOCACHE); 
SQL> SELECT segment_name,tablespace_name,segment_type FROM dba_segments WHERE tablespace_name='TEST'; 

SQL> set linesize 200 
col table_name format a5 
col column_name format a5 
SELECT b.table_name, 
a.segment_name, 
b.index_name, 
a.segment_type, 
b.column_name, 
a.tablespace_name, 
b.chunk, 
b.cache, 
b.freepools, 
b.pctversion, 
b.retention 
FROM dba_segments a,dba_lobs b 
WHERE a.segment_name = b.segment_name 
AND a.tablespace_name = 'LOB_TEST' 
/SQL> 

在一些複雜情況下可能需要連表一起移植 
alter table table_name move [tablespace_name] lob (lob_item) store as [lobsegmentname] (tablespace tablespace_name.....); 
移植分區中lob 
alter table table_name move partition [partition_name] lob (lob_item) store as [logsegmentname] (tablespace_name.....); 
移植分區表 
alter table table_name move partition [partition_name] tablespace_name lob (lob_item) store as [logsegmentname] (tablespace_name.....); 
如果不需要修改lobsegmentname,可以同時移植多個列 
alter table table_name move lob (lob_item1,lob_item2,lob_item3...) store as [lobsegmentname] (tablespace tablespace_name.....); 



    LOB段也可以利用move來重整數據,以下的語句會將表與lob字段move到指定的表空間: 

   alter table table_name move [tablespace tbs_name] 

lob(lob_field1,lob_field2) store as (tablespace new_tbs_name); 

如果LOB字段在分區表中,則增加partition關鍵字,如 

   alter table table_name move [partition partname] [tablespace tbs_name] 

lob(field) store as (tablespace new_tbs_name); 



在數據庫中合理的存儲LOB列,不僅可以提升性能,而且還可以有效的管理存儲空間.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章