關於move tablespace的問題總結(r2筆記50天)
現在得到一個需求,需要把生產環境的多個schema下的表結構複製到測試環境中的一個schema下。
生產環境和測試i環境的表空間配置都不一樣。
目前可以考慮用如下的幾種方式來實現。
1)使用exp/imp來做表結構的匯出匯入。
2)使用dbms_metadata.get_ddl來生成對應的ddl語句。
3)使用expdp/impdp來做表結構的匯入匯出。
因為涉及的表大約有2000個,採用dbms_metadata是一個很大的工作量而且在多個schema中需要權衡,所以沒有采用。
expdp需要在服務端配置directory,客戶要求只能在備庫上做匯出,備庫是在read only狀態下的,所以一下子切斷了使用expdp的希望。
最後只能使用傳統的exp/imp來做了,根據我的經驗,這方面exp/imp的速度一點也不遜色。
exp prod_user1/prod_user1 file=prod_user1.dmp buffer=9102000 log=prod_user1.log statistics=none indexes=y constraints=y grants=n rows=n
exp prod_user3/prod_user2 file=prod_user2.dmp buffer=9102000 log=prod_user2.log statistics=none indexes=y constraints=y grants=n rows=n
exp prod_user3/prod_user3 file=prod_user3.dmp buffer=9102000 log=prod_user3.log statistics=none indexes=y constraints=y grants=n rows=n
alter index SYS_IL0002310750C00009$$ rebuild tablespace large_data
*
ERROR at line 1:
ORA-02327: cannot create index on expression with datatype LOB
SQL> select index_name,table_name from user_indexes where index_name='SYS_IL0002310750C00009$$';
INDEX_NAME TABLE_NAME
------------------------------ ------------------------------
SYS_IL0002310750C00009$$ APP_XML_CONFIG
SQL> select index_name,column_name from user_ind_columns where index_name='SYS_IL0002310750C00009$$';
no rows selected
select table_name,column_name,tablespace_name,index_name from user_lobs where index_name='SYS_IL0002310750C00009$$'
SQL> /
TABLE_NAME COLUMN_NAME TABLESPACE_NAME INDEX_NAME
------------------------------ ------------------------------ ------------------------------ ------------------------------
APP_XML_CONFIG XML DATAL01 SYS_IL0002310750C00009$$
可以使用下面形式的語句來做lob欄位的遷移。
SQL> alter table app_xml_config move tablespace large_data lob(xml) store as lobsegment(tablespace large_data);
Table altered.
對於上千張表來說,使用如下的sql能夠自動生成move tablespace的語句。
--對錶中的非lob列進行move tablespace操作
select 'alter table '|| table_name||' move tablespace large_data;' from user_tables t where tablespace_name!='LARGE_DATA' and exists ( select null from user_tab_cols where table_name=t.table_name and data_type not in ('LONG','BLOB','CLOB'));
--對錶中的lob 列進行move tablespace操作
select 'alter table '||table_name||' move tablespace large_data lob('||column_name||') store as '||SEGMENT_NAME||'(tablespace large_data);' from user_lobs where index_name in (select index_name from user_indexes where tablespace_name!='LARGE_DATA');
--對錶中的索引進行rebuild,因為lob資料段已經做了move 操作,對於索引lob段就不用再做move 操作了。
select 'alter index '||index_name||' rebuild tablespace large_data;' from user_indexes where tablespace_name!='LARGE_DATA';