今天在生産環境中,開發人員送出了一個腳本,是做update操作的,但是update操作的時候過濾條件有些大,本來預計修改的資料隻有5000條,結果這個語句運作下來更改了500萬條資料。對生産系統來說算是一個資料災難,趕緊和開發确認了問題發生的時間,結果說是在半夜11點多,剛好在後半夜才開始做資料備份,這樣這個變更也同時影響了備份,就算做緊急的資料恢複也是沒有任何效果的。目前采用的備份都是全量的按天備份,備份收到影響,恢複還是比較困難的。
這個問題就在緊急的讨論中分為了兩個步驟,我來嘗試恢複昨天備份前的資料,提供的時間戳是23:48:48 ,而且經過确認這個表中的資料變化很小。如果能夠恢複出表中的資料在那個時間點之前,就能把問題降低到最低。
開發從業務的角度看能不能同時提供一些修複。
我檢視了undo的空間使用,還是比較充足的,早上已經是10點左右了,是以就是盡快的做資料的恢複,使用閃回查詢來做。這個操作也不是百分百好使,畢竟還是依賴一些緩存空間和系統的負載,在反複确認時間後,寫了如下的語句。把時間戳提前了3秒。
create table tmp_xxxxx as select * from owner_account.xxxxx as of timestamp to_timestamp('20140723234845','yyyymmddHH24miss');
為了保證不會有其他潛在的因素影響,是以保守起見,沒啟并行,沒加hint
然後就是通過腳本來監控表空間的使用率。看着空間消耗開始一點點增加,最終恢複了昨晚的資料。有了這些資料,就算暫時不會用到,心裡也踏實了。
後來開發确認,有一個字段a,這個字段在表裡存放的資料就是null,結果開發的update語句相當于又修改了一次,經過反複确認,算是虛驚一場,不過也需要總結不少的經驗。
1.在腳本送出之前,如果是dml語句,最好能夠評估修改的影響範圍,
2.如果腳本比較大,有性能方面的潛在因素,需要讓dba來把把關,看看能不能做點什麼。
3.充分的測試也很重要,保證資料的安全和高可用是很重要的。