如果是使用者主生產環境,通常不會有使用者會開啟這個功能。
但如果是在ADG備庫端,就會有不少客戶選擇開啟這個功能,這可以有效補充誤操作應急處置方法。
今天給某客戶做技術支援的時候,在現場遇到一個蠻有意思的問題:
XTTS測試場景,庫非常大,資料檔案很多,遠超db_files的預設值。
在表空間後設資料匯入階段,因此中斷報錯退出,修改db_files引數後發現很多表空間資料檔案已經存在,壓力就比較大,還好找到了方法drop tablespace xxx including contents
的方式,注意還不能是OMF管理的,否則即便不加including datafiles
也會被刪掉,那就麻煩了。。
如果能參考我之前寫過的一篇《XTTS系列之一:U2L遷移解決方案之XTTS的使用》,會發現我通常會建議大家在這種關鍵測試節點前,都會做一個動作;
就是開啟閃回資料庫的基礎上,建立強制還原點,這樣有任何問題,直接閃回資料庫到操作前狀態即可。
這個動作非常簡單,同時也為了順便驗證下在備庫開啟的步驟,我就在自己一套19c的ADG備庫環境下驗證下這個開啟操作:
我這裡單範例設定到檔案系統了,你也可以設定到ASM磁碟組中:
SQL> alter system set db_recovery_file_dest_size=100g scope=both;
System altered.
SQL> alter system set db_recovery_file_dest='/flash/fast_recovery_area' scope=both;
System altered.
備庫在應用的話,直接開啟會報錯ORA-01153,需要取消應用再開啟閃回,開啟閃回後再啟動備庫紀錄檔應用:
--1.直接開啟會報錯ORA-01153:
SQL> select database_role, open_mode from v$database;
DATABASE_ROLE OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY READ ONLY WITH APPLY
SQL> alter database flashback on;
alter database flashback on
*
ERROR at line 1:
ORA-01153: an incompatible media recovery is active
--2.需要取消應用再開啟:
SQL> recover managed standby database cancel;
Media recovery complete.
SQL> select database_role, open_mode from v$database;
DATABASE_ROLE OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY READ ONLY
SQL> alter database flashback on;
Database altered.
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
--3.開啟閃回後再啟動備庫紀錄檔應用
SQL> recover managed standby database disconnect;
Media recovery complete.
SQL> select database_role, open_mode from v$database;
DATABASE_ROLE OPEN_MODE
---------------- --------------------
PHYSICAL STANDBY READ ONLY WITH APPLY
比如這裡建立 before_imp_xtts 強制還原點:
SQL> create restore point before_imp_xtts guarantee flashback database;
Restore point created.
SQL> select name from v$restore_point;
--確認有剛建立的restore point。
注意:如果是在備庫建立,那也是需要先cancel紀錄檔應用才能建立的!
比如舉例在備庫建立一個 before_truncate_t 強制還原點:
目前T表有9條資料:
SQL> select count(*) from t;
COUNT(*)
----------
9
在ADG備庫建立還原點:
SQL> recover managed standby database cancel;
Media recovery complete.
SQL> create restore point before_truncate_t guarantee flashback database;
Restore point created.
開啟應用後(19cADG實時應用不再需要指定using current logfile關鍵字),
主庫此時去truncate T這張表,ADG備庫查詢已經實時同步被刪除了。
SQL> recover managed standby database disconnect;
Media recovery complete.
SQL> select count(*) from t;
COUNT(*)
----------
9
SQL> select count(*) from t;
COUNT(*)
----------
0
如何閃回到before_truncate_t呢?
SQL> flashback database to restore point before_truncate_t;
flashback database to restore point before_truncate_t
*
ERROR at line 1:
ORA-01153: an incompatible media recovery is active
SQL> recover managed standby database cancel;
Media recovery complete.
SQL> flashback database to restore point before_truncate_t;
Flashback complete.
SQL> select count(*) from t;
select count(*) from t
*
ERROR at line 1:
ORA-01219: database or pluggable database not open: queries allowed on fixed
tables or views only
SQL> select status from v$instance;
STATUS
------------
MOUNTED
SQL> alter database open;
Database altered.
SQL> select count(*) from t;
COUNT(*)
----------
9
還是要在停止應用紀錄檔的狀態下,直接閃回資料庫到指定的這個restore point,然後開庫就可以看到被誤操作的T表資料又回來了~
可能有人會問,除了計劃內的測試,誰也不會在誤操作之前去手工建立還原點,真實誤操作場景如何進行閃回呢?
蠻好的問題,其實閃回可以基於時間進行的。
刪除還原點,然後開啟同步,又到了誤操作場景,如何操作呢?
SQL> drop restore point BEFORE_TRUNCATE_T;
Restore point dropped.
SQL> recover managed standby database disconnect;
Media recovery complete.
SQL> select count(*) from t;
COUNT(*)
----------
0
可以查詢閃回資料庫的資訊:
SQL> alter session set nls_date_format='yyyy-mm-dd hh24:mi:ss';
Session altered.
SQL> SELECT * FROM V$FLASHBACK_DATABASE_STAT
2 /
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE CON_ID
------------------- ------------------- -------------- ---------- ---------- ------------------------ ----------
2023-06-27 22:09:07 2023-06-27 22:51:28 25362432 7741440 0 0 0
--此時主庫又插入一條資料,備庫也同步了:
SQL> select count(*) from t;
COUNT(*)
----------
1
SQL> select TIMESTAMP_TO_SCN(to_timestamp('2023-06-27 22:51:28','yyyy-mm-dd hh24:mi:ss')) from dual;
TIMESTAMP_TO_SCN(TO_TIMESTAMP('2023-06-2722:51:28','YYYY-MM-DDHH24:MI:SS'))
---------------------------------------------------------------------------
58518875
注意:這個轉換其實不夠精確,3秒內的時間都被轉換成同一個SCN。但這裡的場景是足夠用的;閃回到這個SCN,flashback database to scn 58518875;
SQL> recover managed standby database cancel;
Media recovery complete.
SQL> flashback database to scn 58518875;
Flashback complete.
SQL> alter database open;
Database altered.
SQL> select * from t;
no rows selected
SQL>
看T表又無資料了,相當於再沒有任何還原點存在的情況下,可以直接閃回到某個時間,而這個時間可以是 V$FLASHBACK_DATABASE_STAT
查到時間範圍區間內的任意時間。
真的是蠻強大的一個功能。
Tips:這裡用到了時間和SCN的轉換,其實Oracle很多場景都會用到SCN和時間的互相轉換,可以記下:
--eg:將SCN轉換成時間戳,使用 SCN_TO_TIMESTAMP(scn_number)
SQL> select SCN_TO_TIMESTAMP(58518875) from dual;
SCN_TO_TIMESTAMP(58518875)
---------------------------------------------------------------------------
27-JUN-23 10.51.27.000000000 PM
--eg:將時間戳轉換成SCN,使用 TIMESTAMP_TO_SCN(timestamp)
SQL> select TIMESTAMP_TO_SCN(to_timestamp('2023-06-27 22:51:28','yyyy-mm-dd hh24:mi:ss')) from dual;
TIMESTAMP_TO_SCN(TO_TIMESTAMP('2023-06-2722:51:28','YYYY-MM-DDHH24:MI:SS'))
---------------------------------------------------------------------------
58518875