內(nèi)容來源:https://blog.csdn.net/Ruishine/article/details/120972330
一)問題:
最近在做Oracle數(shù)據(jù)清理,在對分區(qū)表進(jìn)行數(shù)據(jù)清理時,采用的方法是drop partition,刪除的過程中,沒有遇到任何問題,大概過了10分鐘,開發(fā)人員反饋部分分區(qū)表上的業(yè)務(wù)失敗。具體錯誤為:
ORA-01502錯誤:索引或這類索引的分區(qū)處于不可用狀態(tài)(英文:ora-01502:index ‘schema.index_name’ or partition of such index is in unusable state)。
(二)原因分析
查看出現(xiàn)問題的分區(qū)表,均有一個共同點(diǎn):表上以“pk_”開頭的索引為unusable狀態(tài),以“pk_”開頭的索引是隨創(chuàng)建主鍵約束而創(chuàng)建的。當(dāng)用戶在創(chuàng)建主鍵約束或唯一性約束的時候,會在相應(yīng)的列上創(chuàng)建唯一性索引
經(jīng)過查證,發(fā)現(xiàn)是在刪除分區(qū)的時候,導(dǎo)致分區(qū)表上的<mark style="box-sizing: border-box; outline: 0px; background-color: rgb(248, 248, 64); color: rgb(0, 0, 0); overflow-wrap: break-word; font-weight: 700;">唯一性全局索引</mark>為不可用狀態(tài),導(dǎo)致新的數(shù)據(jù)無法正常插入,從而引發(fā)了該錯誤。
是不是索引不可用會導(dǎo)致DML操作失敗呢?經(jīng)過驗(yàn)證,發(fā)現(xiàn)以下特點(diǎn):
1.對于非唯一性索引,如果索引不可用,是不會影響到到DML操作的;
2.對于唯一性索引,如果索引不可用,在進(jìn)行DML操作時,會觸發(fā)ORA-01502錯誤;
這里記錄一下哪些操作會導(dǎo)致索引失效:
[圖片上傳失敗...(image-830606-1694070658640)]
(三)解決方案
(3.1)了解唯一性索引
在解決問題之前,我們來分析一下,哪些行為會創(chuàng)建唯一性索引(3種):
–直接創(chuàng)建唯一性索引。
語法為:CREATE UNIQUE INDEX index_name on table_name(col1,col2,…);
–創(chuàng)建主鍵約束時自動創(chuàng)建唯一性索引。
語法為:ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY(col1,col2,..);
–創(chuàng)建唯一性約束時自動創(chuàng)建唯一性索引。
語法為:ALTER TABLE table_name ADD CONSTRAINT constraint_name UNIQUE(col1,col2,…);
這里,我總結(jié)了3套方案來對應(yīng)ORA-01502問題。
(3.2)方案一:刪除唯一性索引
與業(yè)務(wù)方面溝通,確認(rèn)唯一性索引是否可以刪除,如果可以,直接刪除索引,刪除語法為:
SQL> DROP INDEX schema.index_name;
對于由主鍵約束或唯一性約束創(chuàng)建的唯一性索引,不能直接刪除:
SQL> drop index lijiaman.sale_pk;
drop index lijiaman.sale_pk
ORA-02429: cannot drop index used for enforcement of unique/primary key
正確的方法是刪除相應(yīng)的約束:
SQL> alter table sales drop constraint sale_pk;
Table altered
小結(jié):該方法簡單粗暴,前提是在約束或索引在業(yè)務(wù)方面可以刪除的情況下才能使用。
(3.3)方案二:重建唯一性索引(針對非分區(qū)表)
語法為:
SQL> ALTER INDEX [schema.]index_name REBUILD [ONLINE] [TABLESPACE tablespace name]
小結(jié):該方法可以使索引可用。但對于分區(qū)表而言,依然存在問題:在下一次刪除分區(qū)后,索引狀態(tài)又會變?yōu)椴豢捎谩?/p>
(3.4)方案三:刪除不可用的索引,創(chuàng)建唯一性分區(qū)索引(針對分區(qū)表)
創(chuàng)建唯一性分區(qū)索引:
SQL> CREATE UNIQUE INDEX index_name on [schema.]table(col1,col2,...);
對于主鍵約束、唯一性約束,可以使用以下語法添加唯一性局部分區(qū)索引:
SQL> ALTER TABLE [schema.]table_name ADD CONSTRAINT constarint [PRIMARY KEY | UNIQUE](col1,col2)
USING INDEX LOCAL TABLESPACE tablespace_name;
小結(jié):該方法可以有效解決分區(qū)表因刪除分區(qū)導(dǎo)致的索引不可用問題。
