set unused的用法(ORACLE刪除字段)

轉載:https://blog.csdn.net/li19236/article/details/41486477
set unused的用法(ORACLE刪除字段)

一、問題

現場有一張大數據量的分區表,數據量在10G以上。因某種原因需要刪除其中的某些字段。如果直接用
alter table1 drop (column1,column2);
或者alter table1 drop column column1;和alter table1 drop column column2;
的話,需要執行很長時間,這期間該表被鎖,會影響到其它應用。

二、解決方法

使用set unused,等系統空閒時再drop unused。

1.

alter table table1 set unused (column1,column2);
或者
alter table table1 set unused column column1;
alter table table2 set unused column column2;

2.

alter table drop unused columns checkpoint 1000;

三、知識點(set unused的用法)

原理:清楚掉字典信息(撤消存儲空間),不可恢復。

可以使用 SET UNUSED 選項標記一列或者多列不可用。
使用DROP SET UNUSED 選項刪除被標記爲不可用的列。

語法:

ALTER TABLE table SET UNUSED (COLlist多個) 或者 ALTER TABLE table SET UNUSED COLUMN col單個;

ALTER TABLE table DROP UNUSED COLUMNS [checkpoint 1000];

set unused不會真地刪除字段。

除了alter table drop field外,也可以
alter table set unused field;
alter table drop unused;

set unused系統開銷比較小,速度較快,所以可以先set unused,然後在系統負載較小時,再drop。如系統負載不大,也可以直接drop。

不管用何種方法,都不會收回空間。

如果你有這個需求,要刪除某一個表上的某些列,但是由於這個表擁有非常大量的資料,如果你在尖峯時間直接執行 ALTER TABLE ABC DROP(COLUMN);可能會收到
ORA-01562 - failed to extend rollback segment number string,
這是因爲在這個刪除列的過程中你可能會消耗光整個RBS,造成這樣的錯誤出現,因此這樣的做法並不是一個好方法,就算你拼命的加大RBS空間來應付這個問題,也不會是個好主意。

我的建議做法:

1>
CREATE TABLE T1 (A NUMBER,B NUMBER);

SQL> begin
2 for i in 1 …… 100000
3 loop
4 insert into t1 values (i,100);
5 end loop;
6 commit;
7 end;

SQL> select count(*) from t1;

COUNT(*)

100000

2>

SQL> ALTER TABLE T1 SET UNUSED COLUMN A CASCADE CONSTRAINTS;
不要馬上drop column,應該先set unused讓column無法使用,避開系統尖峯時間再來處理刪除列裏的資料,要注意的是一旦你set unused column,這個列是無法再恢復使用的。

3>

重點來了,若你的列有一百萬筆資料,我們應該避免一次寫入那麼多的undo log,所以我準備每刪除一千筆資料就commit一次。

SQL> alter table t1 drop unused columns checkpoint 1000;
Table altered.
在高峯的時間進行這樣的動作,應該可以避免 ORA-01562 的錯誤發生。

剛纔有個人問我如何修復被設置爲UNUSED的字段,我考慮了一下,以下的方法可以恢復(以下步驟執行前要做好備份),沒有經驗的DBA不要輕易嘗試。

1、創建實驗表TTTA

SQL> CREATE TABLE TTTA ( A INTEGER,B INTEGER,C VARCHAR2(10),D INTEGER);
表已創建。

SQL> INSERT INTO TTTA VALUES (1,2,'3',4);
已創建 1 行。

SQL> INSERT INTO TTTA VALUES (2,3,'4',5);
已創建 1 行。

SQL> COMMIT;
提交完成。

ALTER TABLE TTTA SET UNUSED COLUMN C;

2、以下進行恢復

SYS下
SQL> SELECT OBJ# FROM OBJ$ WHERE NAME='TTTA';

  OBJ#

 32067

SELECT COL#,INTCOL#,NAME FROM COL$ WHERE OBJ#=32067;
COL# INTCOL# NAME


     1          1 A
     2          2 B
     0          3 SYS_C00003_08031720:09:55$   被UNUSED的字段
     3          4 D

SQL> SELECT COLS FROM TAB$ WHERE OBJ#=32067;

  COLS

     3      ------字段數變爲3了

SQL> UPDATE COL$ SET COL#=INTCOL# WHERE OBJ#=32067;
已更新4行。

SQL> UPDATE TAB$ SET COLS=COLS 1 WHERE OBJ#=32067;
已更新 1 行。

UPDATE COL$ SET NAME='C' WHERE OBJ#=32067 AND COL#=3;

UPDATE COL$ SET PROPERTY=0 WHERE OBJ#=32067;
SQL> COMMIT;

3、重啓數據庫
SQL> SELECT * FROM SCOTT.TTTA;

     A          B C                   D

     1          2 3                   4
     2          3 4                   5

恢復完成

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