Oracle高可用環境之DDL操作

shiri512003發表於2009-08-09

作者: 絃樂之花 | 可以轉載, 但必須以超連結形式標明文章原始出處和作者資訊及版權宣告

連結

http://shiri512003.itpub.net/post/37713/489130

[@more@]

在這之前,應該有鎖與阻塞的基礎知識。

DDL

Note:執行DDL會先commit當前會話操作,再執行DDL,即DDL是非原子性操作。

X型別鎖:truncatedropalter table drop/add/modify等絕大部分DDl,會在表上持有X型別的TM鎖。

S型別鎖:online操作,會在表上持有RS型別的鎖。

高可用環境下DDL操作風險分析:

1、 DDL阻塞DML,引發應用問題。

2、 因為修改表和欄位,導致現有SQL語句錯誤,無法執行。

3、 在有儲存過程、包或Trigger的物件上執行DDL,導致這些PL/SQL物件失效而無法編譯。

4、 DDL操作使SQL語句重新分析,引發SQL語句執行計劃改變。

5、 高並發表上執行DDL,導致library cache latch的嚴重等待。

面臨的挑戰:

1、 DDL阻塞DML,引發應用停頓。

2、 DDL導致語句重新解析,導致執行計劃改變,Latch爭用。

如何應對這些問題呢?

這與我們對DDL操作本身的理解有很大關係。

對於1,事實上,DDL操作並非都是原子操作,也就是一些DDL操作是可分解的,雖然我們一般都是把它當作一個操作去做了。這就為我們減少DDL阻塞時間提供了可行性。如果我們能精確把握相應DDL操作的原理,依據Oracle本身操作規則,將阻塞DML操作的部分與不阻塞DML的部分分離出來,則可能大大減少DDL對應用的阻塞時間,因為DDL操作中不阻塞DML的部分往往佔用很多的時間,從而使得整個DDL操作時間被拉長。更進一步,我們甚至可以利用Oracle本身的操作規則替代原本DDL操作所實現的內容。

對於2DDL操作引發語句重新解析,很難避免吧,或許Oracle以後會更加智慧——能自行區分是否應該invalid語句或者更加開放——提供給我們DDL操作invalid語句的開關。在這方面Oracle 11g也有所動作。

案例分析

線上增加欄位,並帶預設值

一般會這樣操作,

SQL>alter table t_name add col_name col_type default col_value;

11g之前,這個操作將會去修改表塊中的內容,並且會在表上持有X型別的TM鎖,對於表記錄數很多,且業務繁忙的情況,系統將遭遇大量鎖等待。

對於這個操作,實際上大量都是時間消耗在對錶塊內容的修改上,導致DDL操作時間被拉長。如果我們對於Oracle的操作規則足夠熟悉的話,我們會發現,我們可以把這部分操作從DDL分離出去的,將整個操作分解為3步執行:

1、增加一個欄位

SQL>alter table t_name add col_name col_type;

疑問:這個操作只是修改資料字典,而不修改塊內容嗎?

Note:當然這樣操作是無法避免語句重新解析問題的。

2、修改該欄位預設值

SQL>alter table t_name modify col_name default col_value;

這個操作只是標記以後的記錄預設值為col_value,並不修改以前的記錄。

3、修改以前的記錄

批次修改

參考

線上給表增加主鍵活其他約束

主鍵約束與唯一約束

實現約束=約束+索引+資料校驗

因為資料的校驗是不阻塞讀操作的,只有表約束的狀態該表是阻塞讀的,那麼如果可以將索引建立與資料校驗分離出去,則可以大大減少DDL阻塞時間。

參考:

線上增加索引

面臨挑戰:

1、 常規方法建立索引,可能會阻塞應用。

2、 索引的增加可能導致有些語句執行計劃發生改變。

3、 索引名稱的改變導致索引相關hint失效。

參考:

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7591490/viewspace-1025091/,如需轉載,請註明出處,否則將追究法律責任。

相關文章