一、概述
前一段時(shí)間,有一個(gè)DBA朋友在完畢重建表(rename)工作后,第二天早上業(yè)務(wù)無(wú)法正常執(zhí)行,出現(xiàn)數(shù)據(jù)無(wú)法插入的限制和錯(cuò)誤,后來(lái)分析才發(fā)現(xiàn),錯(cuò)誤的原因是使用rename方式重建表以后,其他引用這個(gè)表的外鍵約束指向沒有又一次定義到這個(gè)重建的新表中,從而導(dǎo)致這些表在插入新數(shù)據(jù)時(shí),違反數(shù)據(jù)完整性約束,導(dǎo)致數(shù)據(jù)無(wú)法正常插入。
影響了業(yè)務(wù)大概有1個(gè)多小時(shí),真是一次血淋淋的教訓(xùn)啊。
成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供魏都企業(yè)網(wǎng)站建設(shè),專注與網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、H5建站、小程序制作等業(yè)務(wù)。10年已為魏都眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。
使用rename方式重建表是我們?nèi)粘BA維護(hù)工作中常常使用的一種方法,由于CTAS+rename這樣的配合方式。非常有用和高效。
非常多DBA朋友應(yīng)該也都是用過rename方式重建表。并且重建完畢以后也都一切正常,沒有引起過問題。可是,我想說的是,使用rename重建表后。詳細(xì)須要完畢哪些掃尾工作你真的清楚嗎??
這篇文章主要就是歸納當(dāng)我們使用rename方式重建表后。須要進(jìn)行哪些掃尾工作,假設(shè)你還不是非常清楚。一定要細(xì)致閱讀這篇文章。同一時(shí)候在以后的重建表工作中矯正過來(lái)。否則。問題遲早有一天會(huì)降臨到你的身邊!
二、重建表的方式
這里先不談其他,只說一下重建表的方法,例如以下
1、為了確保全部表字段、字段類型、長(zhǎng)度全然一樣,我一般不建議使用CTAS方式來(lái)重建表。
2、一般我都是使用以下兩種方法中的一個(gè),來(lái)抽取表的定義
-
select dbms_metadata.get_ddl('TABLE',upper('&i_table_name'),upper('&i_owner')) from dual;
-
使用PL/SQL developer類似這種工具,來(lái)查看表定義語(yǔ)句
3、又一次建一張_old類型的表(依據(jù)上面的抽取的表定義),然后使用insert /*+ append */ xx select xxx 方式完畢數(shù)據(jù)的轉(zhuǎn)換
4、最后使用rename方式倒換這兩張表的名字
三、重建表注意事項(xiàng)
索引重建:這里最關(guān)鍵的是,重建后索引的名字是否必須和曾經(jīng)的一樣,假設(shè)須要一樣。則必須將當(dāng)前使用的索引名字先rename,否則創(chuàng)建的時(shí)候會(huì)出現(xiàn)索引名字已經(jīng)存在的錯(cuò)誤
例如以下查詢當(dāng)前表的索引并改名sql:
select 'alter index ' || owner || '.' || index_name || ' rename to ' ||
substr(index_name, 1, 26) || '_old;'
from dba_indexes a
where a.table_owner = 'DBMON'
AND A.table_name = 'DH_T';
依賴對(duì)象重建:一般能夠使用例如以下方式完畢
select 'alter '||decode(type,'PACKAGE BODY','PACKAGE',type)||' '||owner||'.'||name||' compile;'
from dba_dependencies a
where a.referenced_name = 'DH_T'
and a.referenced_owner = 'DBMON';
注意:
1、這里重建的僅僅是直接依賴對(duì)象,必須考慮那些間接依賴的對(duì)象(比如 view1依賴A表,view2依賴view1),查找方法和上面幾乎相同
2、假設(shè)這些依賴對(duì)象中存在一些私有對(duì)象(比如dblink等)。我們用DBA用戶編譯是會(huì)出現(xiàn)編譯錯(cuò)誤,對(duì)于這樣的對(duì)象。必須以相應(yīng)對(duì)象的所屬者才能編譯成功。(也可用用10g以后新出現(xiàn)的代理權(quán)限來(lái)完畢這類任務(wù)?。?br />
針對(duì)PL/SQL代碼(包、函數(shù)、過程等),是否存在私有對(duì)象的查找方法,例如以下:
select *
from dba_source a
where (a.owner, a.name) in
(select owner, name
from dba_dependencies b
where b.referenced_name = 'DH_T'
and b.referenced_owner = 'DBMON')
and a.TEXT like '%@%';
針對(duì)視圖中是否存在私有對(duì)象的查找方法,例如以下(因?yàn)槭莑ong類型。必須得一個(gè)一個(gè)查看):
select *
from dba_views a
where (a.owner, a.view_name) in
(select owner, name
from dba_dependencies b
where b.referenced_name = 'DH_T'
and b.referenced_owner = 'DBMON'
and b.type = 'VIEW')
權(quán)限重建:能夠使用例如以下語(yǔ)句
select 'grant ' || PRIVILEGE || ' on ' || owner || '.' || table_name ||
' to ' || grantee || ';'
from dba_tab_privs
where table_name = upper('&i_table_name')
and owner = upper('&i_owner');
外鍵重建:對(duì)于外鍵,如今的業(yè)務(wù)數(shù)據(jù)邏輯非常多都是在應(yīng)用層來(lái)實(shí)現(xiàn)。因此表上的外鍵可能都非常少,因此。導(dǎo)致非常多DBA都忘記須要檢查和重建這一部分了,從而導(dǎo)致業(yè)務(wù)出現(xiàn)故障,本章最開始說的故障案例就是由于沒有重建外鍵而引起,因此我們一定要提高警惕。
能夠使用以下語(yǔ)句查看,哪些表引用了重建表
select a.table_name,
a.owner,
a.constraint_name,
a.constraint_type,
a.r_owner,
a.r_constraint_name, --被外鍵引用的約束名
b.table_name --被外鍵引用的表名
from dba_constraints a, dba_constraints b
where a.constraint_type = 'R'
and a.r_constraint_name = b.constraint_name
and a.r_owner = b.owner
and b.table_name = 'FSPARECEIVEBILLTIME'
and b.owner='';