1. 程式人生 > >解決Oracle 11g在用EXP匯出時,空表不能匯出

解決Oracle 11g在用EXP匯出時,空表不能匯出

一、問題原因:
11G中有個新特性,當表無資料時,不分配segment,以節省空間
1、insert一行,再rollback就產生segment了。

該方法是在在空表中插入資料,再刪除,則產生segment。匯出時則可匯出空表。

2、設定deferred_segment_creation 引數

show parameter deferred_segment_creation

NAME TYPE VALUE

------------------------------------ ----------- ----------

deferred_segment_creation boolean TRUE

SQL> alter system set deferred_segment_creation=false;

系統已更改。

SQL> show parameter deferred_segment_creation

NAME TYPE VALUE

------------------------------------ ----------- ----------


deferred_segment_creation boolean FALSE

該引數值預設是TRUE,當改為FALSE時,無論是空表還是非空表,都分配segment。

需注意的是:該值設定後對以前匯入的空表不產生作用,仍不能匯出,只能對後面新增的表產生作用。如需匯出之前的空表,只能用第一種方法。

二、解決方法:

1、先查詢一下當前使用者下的所有空表

select table_name from user_tables where NUM_ROWS=0;

2、用以下這句查詢空表

select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0

把查詢結果匯出,執行匯出的語句

'ALTERTABLE'||TABLE_NAME||'ALLOCATEEXTENT;'

-----------------------------------------------------------

alter table AQ$_AQ$_MEM_MC_H allocate extent;

alter table AQ$_AQ$_MEM_MC_G allocate extent;

alter table AQ$_AQ$_MEM_MC_I allocate extent;

alter table AQ$_AQ_PROP_TABLE_T allocate extent;

alter table AQ$_AQ_PROP_TABLE_H allocate extent;

alter table AQ$_AQ_PROP_TABLE_G allocate extent;

alter table AQ$_AQ_PROP_TABLE_I allocate extent;

alter table AQ$_KUPC$DATAPUMP_QUETAB_T allocate extent;

alter table AQ$_KUPC$DATAPUMP_QUETAB_H allocate extent;

alter table AQ$_KUPC$DATAPUMP_QUETAB_G allocate extent;

alter table AQ$_KUPC$DATAPUMP_QUETAB_I allocate extent;

3、然後再執行

exp 使用者名稱/密碼@資料庫名 file=/home/oracle/exp.dmp log=/home/oracle/exp_smsrun.log 成功!


ORACLE 11G在用EXPORT匯出時,空表不能匯出。

11G中有個新特性,當表無資料時,不分配segment,以節省空間

  解決方法:
  1、insert一行,再rollback就產生segment了。
  該方法是在在空表中插入資料,再刪除,則產生segment。匯出時則可匯出空表。

  2、設定deferred_segment_creation 引數
  該引數值預設是TRUE,當改為FALSE時,無論是空表還是非空表,都分配segment。

  需注意的是:該值設定後對以前已經存在的空表不產生作用,仍不能匯出,只能對後面新增的表產生作用。如需匯出之前的空表,只能用第一種方法】

覺得不是解決方法,然後就用了expdp和impdp
create directory expdp_dir as '/data/app1/dp';
grant read,write on directory expdp_dir to DRGN_OWNER;

expdp DRGN_OWNER/DRGN_OWNER DIRECTORY=expdp_dir DUMPFILE=DRGN_OWNER.dmp SCHEMAS=DRGN_OWNER logfile=DRGN_OWNERexpdp.log

create directory impdp_dir as '/data/app1/dp';
grant read,write on directory impdp_dir to DRGN_OWNER;

impdp DRGN_OWNER/DRGN_OWNER DIRECTORY=impdp_dir DUMPFILE=DRGN_OWNER.dmp logfile=DRGN_OWNER.dmpimpdp.log

空表果然已經匯入了

對於DBA新建資料庫,我個人建議,建立了空的資料庫後,馬上執行
alter system set deferred_segment_creation=flase sscope=spfile;
shutdowm immediate
startup




【總結】
1、自己沒有好好學習11g的新特性,導致了這個問題花費了2個小時的
2、建議客戶使用穩定的10.2.0.4,客戶拒絕,現在11g已經是主流了,並不是每一個客戶都很保守使用穩定版本,而非最新版本
3、某美 和 某ELL 的專案以後少接觸,4年前IBM P570雙機Oracle10g的實施問題就折騰的無語。
4、再次論證了很多甲方和廠商基本都是:事前豬一樣,事後諸葛亮。和目前國內流行的磚家叫獸有異曲同工之妙。
5、做技術果然是一條不歸之路



在Oracle 11g中,exp預設不能匯出空表。用傳統的exp,imp進行異構平臺數據庫遷移會比較麻煩。不過可以使用expdp、impdp進行遷移。

把64位windows 2003的Oracle11gR2資料庫遷移到64位Linux RedHat Enterprise 5中,可以使用expdp、impdp進行遷移資料。

如:Windows為A伺服器,Linux為B伺服器,資料庫使用者為test,把A伺服器的資料遷移到B伺服器中


在A伺服器操作:

1、

SQL> create directory expdp_dir as 'D:\mzl\backup ';

SQL> grant read,write on directory expdp_dir to test;

2、在windows目錄建立目錄D:\mzl\backup

3、在DOS命令視窗匯出:

expdp test/test DIRECTORY=expdp_dir DUMPFILE=test.dmp logfile=testexpdp.log

在B伺服器中操作:

4、SQL> create directory impdp_dir as '/home/oracle/impdp_dir';

SQL> grant read,write on directory impdp_dir to test;

1、 在系統中需要有/home/oracle/impdp_dir目錄,在impdp_dir目錄下必須有讀寫許可權

(chmod 777 impdp_dir)

5、用ftp把A伺服器匯出的資料上傳到B伺服器的/home/oracle/impdp_dir目錄中

在A伺服器中配置好B伺服器的伺服器名,在A伺服器匯入資料

6、在DOS命令視窗匯出:

impdp test/
[email protected]
_database DIRECTORY=impdp_dir DUMPFILE=test.dmp logfile=testimpdp.log

(這裡注意大小寫,如果test.dmp在linux中為大寫,必須更改為大寫。Linux區分大小寫)



本篇文章來源於 Linux公社網站(www.linuxidc.com) 原文連結:http://www.linuxidc.com/Linux/2011-08/41146.htm

在oracle 11g r2中,發現傳統的exp居然不能匯出空的表,然後查詢一下,
發現需要如下的步驟去搞,筆記之。

oracle 11g 新增了一個引數:deferred_segment_creation,含義是段延遲建立,預設是true。具體是什麼意思呢?

如果這個引數設定為true,你新建了一個表T1,並且沒有向其中插入資料,那麼這個表不會立即分配extent,也就是不佔資料空間,只有當你insert資料後才分配空間。這樣可以節省少量的空間。

解決辦法

1 設定deferred_segment_creation 引數為FALSE後,無論是空表還是非空表,都分配segment。

在sqlplus中,執行如下命令:

SQL>alter system set deferred_segment_creation=false;

檢視:
SQL>show parameter deferred_segment_creation;


該值設定後只對後面新增的表產生作用,對之前建立的空表不起作用。

注意並且要重新啟動資料庫,讓引數生效

2 使用ALLOCATE EXTENT的說明


使用ALLOCATE EXTENT可以為資料庫物件分配Extent。其語法如下:

-----------
ALLOCATE EXTENT { SIZE integer [K | M] | DATAFILE 'filename' | INSTANCE integer }
-----------

可以針對資料表、索引、物化檢視等手工分配Extent。

ALLOCATE EXTENT使用樣例:

ALLOCATE EXTENT
ALLOCATE EXTENT(SIZE integer [K | M])
ALLOCATE EXTENT(DATAFILE 'filename')
ALLOCATE EXTENT(INSTANCE integer)
ALLOCATE EXTENT(SIZE integer [K | M] DATAFILE 'filename')
ALLOCATE EXTENT(SIZE integer [K | M] INSTANCE integer)


針對資料表操作的完整語法如下:

-----------
ALTER TABLE [schema.]table_name ALLOCATE EXTENT [({ SIZE integer [K | M] | DATAFILE 'filename' | INSTANCE integer})]
-----------


故,需要構建如下樣子簡單的SQL命令:

-----------
alter table aTabelName allocate extent
-----------



3.2 構建對空表分配空間的SQL命令,


查詢當前使用者下的所有空表(一個使用者最好對應一個預設表空間)。命令如下:

-----------
SQL>select table_name from user_tables where NUM_ROWS=0;
-----------


根據上述查詢,可以構建針對空表分配空間的命令語句,如下:

-----------
SQL>Select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0
-----------


批量輸出上述生成的SQL語句,建立C:\createsql.sql,其內容如下:

-----------
set heading off;
set echo off;
set feedback off;
set termout on;
spool C:\allocate.sql;
Select 'alter table '||table_name||' allocate extent;' from user_tables where num_rows=0;
spool off;
-----------


執行C:\createsql.sql,命令如下:
-----------
SQL>@ C:\createsql.sql;
-----------

執行完畢後,得到C:\allocate.sql檔案。

開啟該檔案會看到,已經得到對所有空表分配空間的命令SQL語句。


3.4 執行SQL命令,對空表分配空間:

執行C:\allocate.sql,命令如下:
-----------
SQL>@ C:\allocate.sql;
-----------

執行完畢,表已更改。


3.4 此時執行exp命令,即可把包括空表在內的所有表,正常匯出。