今天測(cè)試下了oracle在刪除表的數(shù)據(jù)后的恢復(fù)方法。 在Oracle生產(chǎn)系統(tǒng)的維護(hù)測(cè)試中有一張表,將里面的數(shù)據(jù)delete并commit了,由于業(yè)務(wù)不能中斷(數(shù)據(jù)庫(kù)不能停機(jī)),并且系統(tǒng)還在不斷有數(shù)據(jù)往該表中寫入。現(xiàn)在需要將之前delete掉的數(shù)據(jù)恢復(fù),可以使用基于scn的恢
今天測(cè)試下了Oracle在刪除表的數(shù)據(jù)后的恢復(fù)方法。
在Oracle生產(chǎn)系統(tǒng)的維護(hù)測(cè)試中有一張表,將里面的數(shù)據(jù)delete并commit了,由于業(yè)務(wù)不能中斷(數(shù)據(jù)庫(kù)不能停機(jī)),并且系統(tǒng)還在不斷有數(shù)據(jù)往該表中寫入。現(xiàn)在需要將之前delete掉的數(shù)據(jù)恢復(fù),可以使用基于scn的恢復(fù)。
在刪除之前,最好查詢到數(shù)據(jù)庫(kù)當(dāng)前的scn,恢復(fù)的時(shí)候就采用基于這個(gè)scn點(diǎn)的恢復(fù)。
example:
方法一:
1)創(chuàng)建一張測(cè)試表;
????? CREATE TABLE w AS SELECT * FROM dba_objects WHERE 1 = 2;
2)向該表插入測(cè)試數(shù)據(jù);
????? SQL> insert into w select * from dba_objects;
????? 72558 rows created.
????? SQL> commit;
????? Commit complete.
3)SQL> select count(*) from w;
????? COUNT(*)
????? ———-
????? 72558
4)在刪除之前,先獲取數(shù)據(jù)庫(kù)的scn,便于恢復(fù)的時(shí)候查找到數(shù)據(jù)在什么時(shí)候還是存在的;
????? SQL> select dbms_flashback.get_system_change_number from dual;
????? GET_SYSTEM_CHANGE_NUMBER
????? ————————
?????? 117853514???????????????? —— 當(dāng)前scn號(hào)
???? 由于數(shù)據(jù)庫(kù)沒有停,因此scn號(hào)也在不斷變化,因此需要查出數(shù)據(jù)在哪個(gè)scn點(diǎn)的時(shí)候還是存在的
????? SQL> select count(*) from w as of scn 117854000; ——查看數(shù)據(jù)在scn號(hào)為117854000時(shí)是否存在
????? select count(*) from w as of scn 117854000
???????????????????? *
????? ERROR at line 1:
????? ORA-08181: specified number is not a valid system change number? ——應(yīng)該是系統(tǒng)還沒有走到這個(gè)scn號(hào)
????? SQL> select count(*) from w as of scn 117853000;——查看數(shù)據(jù)在scn號(hào)為117853000時(shí)是否存在
????? COUNT(*)
????? ———-
?????? 0?????? ——不存在
????? SQL> select count(*) from w as of scn 117853500;
????? COUNT(*)
????? ———-
?????? 0
????? SQL> select count(*) from w as of scn 117853510;?? 直到查到這個(gè)scn才發(fā)現(xiàn)數(shù)據(jù)才存在,因此屆時(shí)就是基于這個(gè)scn點(diǎn)進(jìn)行恢復(fù)
????? COUNT(*)
????? ———-
?????? 72558
5)模擬刪除數(shù)據(jù);
????? SQL> delete from w;
????? 72558 rows deleted.
????? SQL> commit;
????? Commit complete.
????? SQL> SELECT COUNT(*) FROM w;
????? COUNT(*)
????? ———-
?????? 0
6)模擬數(shù)據(jù)庫(kù)不停機(jī),業(yè)務(wù)在不斷向表中插入數(shù)據(jù); 【Linux公社 http://www.linuxidc.com 】
?????? SQL> insert into w select * from w as of scn 117844000;
?????? 72558 rows created.
?????? SQL> select count(*) from w;
?????? COUNT(*)
?????? ———-
?????? 72558
7)執(zhí)行基于刪除之前數(shù)據(jù)仍然存在的scn點(diǎn)的恢復(fù);
????? SQL> insert into w select * from w as of scn 117853510;
????? 72558 rows created.
????? SQL> commit;
????? Commit complete.
8)查詢驗(yàn)證,之前刪除的數(shù)據(jù)是否恢復(fù)回來(lái)了,并且新插入的數(shù)據(jù)也存在;
????? SQL> select count(*) from w;
?????? COUNT(*)
?????? ———-
??????? 145116
大功告成。之前delete掉的72558條數(shù)據(jù)+新進(jìn)來(lái)的72558條數(shù)據(jù),總共是145116條數(shù)據(jù)。達(dá)到我們的要求!
現(xiàn)在稍微總結(jié)一下:
??????? 在做數(shù)據(jù)表的刪除操作之前,一點(diǎn)要謹(jǐn)慎,尤其是在生產(chǎn)系統(tǒng)不能停機(jī)的情況下,要么首先將數(shù)據(jù)庫(kù)或者表備份一下,再進(jìn)行刪除,這樣就算需要恢復(fù)也可以用備份進(jìn)行恢復(fù);如果刪除時(shí)候沒有做相關(guān)備份,在刪除之前一定要先查下系統(tǒng)當(dāng)前scn,并且驗(yàn)證出數(shù)據(jù)在哪個(gè)scn點(diǎn)的時(shí)候還是存在的(這點(diǎn)很重要,如果沒有找到,就無(wú)法恢復(fù)刪除的數(shù)據(jù))恢復(fù)的時(shí)候就基于這個(gè)scn點(diǎn)的恢復(fù)。
方法二:
1)同樣創(chuàng)建上面的測(cè)試表和數(shù)據(jù);
????? SQL> select count(*) from w;
????? COUNT(*)
????? ———-
?????? 72558
2)查詢下數(shù)據(jù)庫(kù)的時(shí)間,用于確定刪除的數(shù)據(jù)在什么時(shí)間點(diǎn)還存在;
????? SQL> select to_char(sysdate, ‘yyyy-dd-mm hh24:mi:ss’) from dual;
????? TO_CHAR(SYSDATE,’YY
????? ——————-
?????? 2011-23-03 17:23:55
????? SQL> select count(*) from w;
????? COUNT(*)
?????? ———-
??????? 72558????? ——-數(shù)據(jù)在2011-23-03 17:23:55的時(shí)間還存在
3)模擬數(shù)據(jù)的刪除操作;
?????? SQL> delete from w;
?????? 72558 rows deleted.
??????? SQL> commit;
??????? Commit complete.
4)將刪除數(shù)據(jù)之前的時(shí)間(數(shù)據(jù)還存在的時(shí)間)轉(zhuǎn)換為scn;
????? SQL> select timestamp_to_scn(to_timestamp(‘2011-03-23?????? 17:22:00′,’yyyy-mm-dd hh24:mi:ss’)) from dual;
????? TIMESTAMP_TO_SCN(TO_TIMESTAMP(‘2011-03-2317:22:00′,’YYYY- MM-DDHH24:MI:SS’))
?????? —————————————————————————
????????????????????????????????? 117872363
5)驗(yàn)證這個(gè)scn點(diǎn)時(shí)數(shù)據(jù)的存在;
????? SQL> select count(*) from w as of scn 117872363;
????? COUNT(*)
?????? ———-
?????? 72558
6)創(chuàng)建基于原表數(shù)據(jù)還存在時(shí)的臨時(shí)表;
?????? SQL>create table q as select * from w as of scn 117872363;
?????? Table created.
?????? 以上語(yǔ)句由兩條語(yǔ)句合并而成:
?????? SQL>create table q as select * from w where 1 = 0;
?????? Table created.
?????? SQL>insert into q select * from w as of scn 117872363;
?????? 72558 rows created.
?????
?????? SQL> select count(*) from q;
??????? COUNT(*)
???????? ———-
???????? 72558
7)由于業(yè)務(wù)并未中斷,所以原表里面也有新數(shù)據(jù)進(jìn)來(lái)了,此時(shí)只要將剛創(chuàng)建的臨時(shí)表的數(shù)據(jù)導(dǎo)出,然后再倒入到原表中即可。