Flashback database基礎知識問答
彙總一下學習flashback database過程中容易被問到的一些問題,不是單純談理論,輔有實際操作驗證
//////////////////
//如何配置flashback database
//////////////////
滿足條件:
資料庫必須要是archivelog mode,否則會有ORA-38706、ORA-38707
資料庫可以為open或者mount狀態,若處於mount狀態則上一次shutdown時不能使用abort,否則會有ORA-38706、ORA-38714
,否則會有ORA-38706、ORA-38709
設定好db_recovery_file_dest_size、db_recovery_file_dest引數
db_flashback_retention_target引數為可選,預設值是1440分鐘(如果設定為0,等同於禁用flashback database),表示Flashback database能夠將資料庫帶回到的最早的那個時間點與當前時間的間隔,如果db_flashback_retention_target=1440,那麼是最早的時間點就是sysdate-1,db_flashback_retention_target不是一個硬指標,如果fast recovery area設定的比較小而flashback log又增長的比較快,以至於FRA裡沒有可用的空間存放新增的flashback log,較早的flashback log可能會被清除掉,就無法保證database能flashback到db_flashback_retention_target指定的時間點。因為flashback log裡存放的都是data block的before-image,對空間上的要求比online redolog要高的多,可以在資料庫執行一段時間以後參照V$FLASHBACK_DATABASE_LOG.ESTIMATED_FLASHBACK_SIZE來估算flashback log的大小,從而合理的設定db_recovery_file_dest_size
###flashback on database
SQL> show parameter db_flashback_retention_target
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_flashback_retention_target integer 120
SQL> show parameter recovery_file
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_recovery_file_dest string /oradata06/fra
db_recovery_file_dest_size big integer 10G
SQL> alter database flashback on;
Database altered.
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
###記錄flashback log的後臺程式RVWR啟動,在fast recovery area目錄下有名為flashback的目錄生成,初始有兩個.flb檔案,大小和Redolog file size一致
oracle@jq570322b:/oradata06/fra/TSTDB1/archivelog>ps -ef|grep -i rvwr | grep -v grep
tstdb1 18089330 1 0 17:25:46 - 0:00 ora_rvwr_tstdb1
oracle@jq570322b:/oradata06/fra>ls -l TSTDB1
total 16
drwxr-x--- 8 oracle oinstall 8192 Apr 16 17:28 archivelog
drwxr-x--- 3 oracle oinstall 96 Apr 16 17:36 autobackup
drwxr-x--- 2 oracle oinstall 96 Apr 16 17:29 flashback
oracle@jq570322b:/oradata06/fra>ls -l TSTDB1/flashback
total 524320
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:03 o1_mf_1j6D2RXXr_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:17 o1_mf_1j6D2HxYT_.flb
###進行dml操作後,觀察到.flb從2個增加到了5個
create table t0416_1 as select * from all_users;
insert into t0416_1 select * from t0416_1; <---執行n遍
select count(*) from t0416_1;
COUNT(*)
----------
1720320
oracle@jq570322b:/oradata06/fra>ls -l TSTDB1/flashback
total 1310800
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6D2HxYT_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6D2RXXr_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6G7_Xrb_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:30 o1_mf_1j6G9Ptth_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6GAilaq_.flb
###記錄一下當前的系統時間,這個時間將會是後面flashback database的第一個目標時間點
SQL> select sysdate from dual;
SYSDATE
-----------------
20150416 18:51:24
###刪除表中的部分記錄,記錄當前的系統時間20150416 20:35:05database的第二個目標時間點
SQL> delete t0416_1 where user_id>50;
573440 rows deleted.
SQL> commit;
Commit complete.
SQL> select count(*) from t0416_1;
COUNT(*)
----------
1146880
SQL> select sysdate from dual;
SYSDATE
-----------------
20150416 20:35:05
###再建立一個測試表t0416_2
SQL> create table t0416_2 tablespace users as select * from dict;
Table created.
SQL> select count(*) from t0416_2;
COUNT(*)
----------
1792
SQL> select sysdate from dual;
SYSDATE
-----------------
20150416 20:37:28
###重新啟動至mount狀態後,flashback到20150416 18:51:24這個時間點
SQL> flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss');
flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38757: Database must be mounted and not open to FLASHBACK.
SQL> shutdown immediate;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount;
ORACLE instance started.
Total System Global Area 6413680640 bytes
Fixed Size 2233480 bytes
Variable Size 4328524664 bytes
Database Buffers 2063597568 bytes
Redo Buffers 19324928 bytes
Database mounted.
SQL> flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss'); <--------------此處的報錯見下面的解釋
ERROR at line 1:
ORA-38754: FLASHBACK DATABASE not started; required redo log is not available
ORA-38762: redo logs needed for SCN 12723360396485 to SCN End-of-Redo
ORA-38761: redo log sequence 510 in thread 1, incarnation 1 could not be
accessed
--從v$archived_log裡看到sequence#=510這個redolog沒有被正常歸檔就被清除了,它的next_change#=281474976710655使得oracle認為要恢復到的SCN 12723360396485就包含在這個log裡,所以必須去applied這個log,因此出現了上面這個錯誤,這個錯誤在後面的測試裡也會多次出現,閱讀的過程中可以忽略,它並不是重點
SYS@tstdb1-SQL> select sequence#,first_change#,first_time,NEXT_CHANGE#,next_time,archived,name from v$archived_log where SEQUENCE#=510;
SEQUENCE# FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME ARC NAME
---------------- ---------------- ----------------- ---------------- ----------------- --- --------------------------------------------------
510 12723358967141 20150330 21:30:05 281474976710655 NO
--但實際上我們看到sequence#=596這個redolog才是真正包含這個SCN的redolog
SYS@tstdb1-SQL> select sequence#,first_change#,first_time,NEXT_CHANGE#,next_time,archived,name from v$archived_log where first_change#<=12723360396485 and next_change#>=12723360396485;
SEQUENCE# FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME ARC NAME
---------------- ---------------- ----------------- ---------------- ----------------- --- --------------------------------------------------
510 12723358967141 20150330 21:30:05 281474976710655 NO
596 12723360396183 20150416 18:26:01 12723360405745 20150416 20:27:11 YES /oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_
1_596_1j6Myy1FQ_.arc
---顯然RMAN裡flashback database更聰明,能正確找到sequence#=596這個redolog進行apply
RMAN> flashback database to time '20150416 18:51:24';
Starting flashback at 20150417 05:05:06
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=463 device type=DISK
starting media recovery
archived log for thread 1 with sequence 596 is already on disk as file /oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_1_596_1j6Myy1FQ_.arc
media recovery complete, elapsed time: 00:00:02
Finished flashback at 20150417 05:05:24
---執行flashback database期間alert.log裡能告訴我們當前恢復到的時間點是04/16/2015 18:51:38(比指定的時間18:51:24晚了14秒),對應的SCN是12723360398209
Fri Apr 17 05:05:07 2015
alter database recover datafile list clear
Completed: alter database recover datafile list clear
RMAN flashback database to time 04/16/2015 18:51:24
Flashback Restore Start <----restore是將flashback log裡儲存的data block修改前的image還原到datafile裡
Flashback Restore Complete
Flashback Media Recovery Start <----recover就是apply redo的過程
started logmerger process
Parallel Media Recovery started with 16 slaves
Fri Apr 17 05:05:23 2015
Flashback Media Recovery Log /oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_1_596_1j6Myy1FQ_.arc
Fri Apr 17 05:05:23 2015
Incomplete Recovery applied until change 12723360398209 time 04/16/2015 18:51:38
Flashback Media Recovery Complete
Completed: RMAN flashback database to time 04/16/2015 18:51:24
---檢查datafile和controlfile當前的SCN號均為12723360398209
set numwidth 16
col name format a50
set linesize 150
SYS@tstdb1-SQL> select name,checkpoint_change# from v$datafile;
NAME CHECKPOINT_CHANGE#
-------------------------------------------------- ------------------
/oradata06/testaaaaa/system01.dbf 12723360398209
/oradata06/testaaaaa/sysaux01.dbf 12723360398209
/oradata06/testaaaaa/undotbs01.dbf 12723360398209
/oradata06/testaaaaa/users01.dbf 12723360398209
/oradata06/testaaaaa/ts0329_1.dbf 12723360398209
/oradata06/testaaaaa/xdbts1.dbf 12723360398209
/oradata06/testaaaaa/ts0212.dbf 12723357761339 <--- read only tablespace除外
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 <--- read only tablespace除外
8 rows selected.
SYS@tstdb1-SQL> select name,checkpoint_change# from v$datafile_header;
NAME CHECKPOINT_CHANGE#
-------------------------------------------------- ------------------
/oradata06/testaaaaa/system01.dbf 12723360398209
/oradata06/testaaaaa/sysaux01.dbf 12723360398209
/oradata06/testaaaaa/undotbs01.dbf 12723360398209
/oradata06/testaaaaa/users01.dbf 12723360398209
/oradata06/testaaaaa/ts0329_1.dbf 12723360398209
/oradata06/testaaaaa/xdbts1.dbf 12723360398209
/oradata06/testaaaaa/ts0212.dbf 12723357761339 <--- read only tablespace除外
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 <--- read only tablespace除外
###先將資料開啟至read only,看一下flashback後的資料是否我們所需要的
SYS@tstdb1-SQL> alter database open read only;
Database altered.
SCOTT@tstdb1-SQL> select count(*) from t0416_1; <---04/16/2015 18:51:24時刻t0416_1表的記錄數確實是1720320
COUNT(*)
----------
1720320
SCOTT@tstdb1-SQL> select count(*) from t0416_2; <---04/16/2015 18:51:24時刻t0416_2表還沒有建立
select count(*) from t0416_2
*
ERROR at line 1:
ORA-00942: table or view does not exist
//////////////////
//flashback database過程中如何選定所需要的flashback log
//////////////////
Flashback log介紹
flashback log是在資料庫開啟閃回模式(alter database flashback on)或者建立了garanteed restore point的情況下才會生成,flashback log裡儲存的是data block修改前的image。當我們對一個data block修改之前,該data block會從buffer cache複製到shared pool中的flashback generation buffer區域,RVWR程式會將flashback generation buffer裡儲存的data block before-image寫入到flashback log。flashback log必須存放在Fast recovery area裡,其命名方式遵循OMF格式,例如:o1_mf_1j6D2RXXr_.flb。db_flashback_retention_target引數設定決定了flashback log的保留時間,對於超出保留時間的flashback log會被清除(在Fast Recovery Area空間緊張時)或者重複利用,如果資料庫的dml操作非常頻繁,且現有的flashback log都沒有超出db_flashback_retention_target所指定的保留時間,那麼會有新的flashback log生成,這一點和online redo稍有不同,另外flashback log不屬於備份恢復體系中的成員,我們無法針對flashback log進行備份或者使用backup recovery area實現對於flashback log間接備份的目的,因為flashback log作用主要在於邏輯錯誤的修復,備份flashback log並沒有實際意義
我們先配置一個flashback database的環境,後面關於flashback log諸多特性的介紹都將基於這個測試環境
在Flashback database的過程中Flashback log是如何被利用的?
Flashback Database的整個過程由兩個階段組成,第一階段:apply flashback log,將flashback log裡記錄的data block before-image覆蓋到對應資料檔案的對應block,這時各個資料檔案可能是不一致的;第二階段:apply redolog(archived redo or online redo),目的是將資料庫帶到一個consistent point
在上面搭建的flashback database環境的過程中,我們做了一個簡單的測試:將資料庫從current狀態flashback到'20150416 18:51:24'這一時間點。期間我們僅能從alert.log裡或者透過RMAN的命令輸出觀察到第二階段:apply redolog的過程,對於第一階段:apply flashback log的過程我們能找到的僅是alert.log裡
Flashback Restore Start
Flashback Restore Complete
這兩行內容,沒有更多的細節展示出來,也沒有已知的Event設定能夠豐富這方面的輸出。
我們只能將FRA裡的flashback log改名,以儘可能多的獲取apply flashback log過程中的細節
--改名前
oracle@jq570322b:/oradata06/fra/TSTDB1/flashback>ls -rlt
total 2621600
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6D2RXXr_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6G7_Xrb_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 20:00 o1_mf_1j6G9Ptth_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 20:27 o1_mf_1j6GAilaq_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 21:55 o1_mf_1j6LVKto5_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 16 23:55 o1_mf_1j6D2HxYT_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 17 02:25 o1_mf_1j6RuNt1f_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 17 04:55 o1_mf_1j6YbsKVD_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 17 04:55 o1_mf_1j6pMheJF_.flb
-rw-r----- 1 oracle oinstall 134225920 Apr 17 14:21 o1_mf_1j6g-H73H_.flb
--改名
oracle@jq570322b:/oradata06/fra/TSTDB1/flashback>ls -1 *.flb | xargs -n1 -I{} mv {} {}.old
--改名後
oracle@jq570322b:/oradata06/fra/TSTDB1/flashback>ls -rlt
total 2621600
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6D2RXXr_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6G7_Xrb_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 20:00 o1_mf_1j6G9Ptth_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 20:27 o1_mf_1j6GAilaq_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 21:55 o1_mf_1j6LVKto5_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 23:55 o1_mf_1j6D2HxYT_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 17 02:25 o1_mf_1j6RuNt1f_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 17 04:55 o1_mf_1j6YbsKVD_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 17 04:55 o1_mf_1j6pMheJF_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 17 14:21 o1_mf_1j6g-H73H_.flb.old
在執行flashback database的時候可能有兩種場景:
1、flashback的目標時間早於資料庫當前所處的時間,比如資料庫datafile的最新時間戳是10:00,要flashback到8:00的狀態
2、flashback的目標時間晚於資料庫當前所處的時間,比如在經過1次flashback database操作後資料庫datafile的最新時間戳是8:00,發現8:00那一時刻的資料漏掉了一些關鍵的更新,現在又要再次flashback database到9:00時的狀態
官方文件裡並沒有對這兩種情況進行詳細的闡述,我們暫且把第1種場景稱為後向flashback,第2種場景稱為前向flashback,這兩個場景裡flashback databae的過程稍有區別
###後向flashback的場景(這也是我們用的最多,最容易理解的場景)
--資料庫當前所處的時間點是'20150416 21:00:00',在sqlplus裡執行flashback database回到'20150416 18:51:24'這個時間點
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/sysaux01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/undotbs01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/users01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0329_1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/xdbts1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
8 rows selected.
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile_header;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/sysaux01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/undotbs01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/users01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0329_1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/xdbts1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
SYS@tstdb1-SQL> flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss');
flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38701: Flashback database log 9 seq 14 thread 1:
"/oradata06/fra/TSTDB1/flashback/o1_mf_1j6g-H73H_.flb" <---因為改名了所以提示找不到此檔案
ORA-17503: ksfdopn:4 Failed to open file
/oradata06/fra/TSTDB1/flashback/o1_mf_1j6g-H73H_.flb
ORA-17500: ODM err:File does not exist
--我們從V$FLASHBACK_DATABASE_LOGFILE裡看一下o1_mf_1j6g-H73H_.flb這個flashback log的資訊,該log的sequence#=14,first_time是最近的時間20150417 04:55:26,表明是當前正在使用的flashback log
col name format a30
col type format a10
set numwidth 16
set linesize 150 pagesize 100
SYS@tstdb1-SQL> select * from V$FLASHBACK_DATABASE_LOGFILE order by sequence#;
NAME LOG# THREAD# SEQUENCE# BYTES FIRST_CHANGE# FIRST_TIME TYPE
------------------------------ ---------------- ---------------- ---------------- ---------------- ---------------- ----------------- ----------
/oradata06/fra/TSTDB1/flashbac 10 1 1 134217728 0 RESERVED
k/o1_mf_1j6pMheJF_.flb
/oradata06/fra/TSTDB1/flashbac 2 1 6 134217728 12723360387123 20150416 18:25:00 NORMAL
k/o1_mf_1j6D2RXXr_.flb
/oradata06/fra/TSTDB1/flashbac 3 1 7 134217728 12723360390761 20150416 18:25:21 NORMAL
k/o1_mf_1j6G7_Xrb_.flb
/oradata06/fra/TSTDB1/flashbac 4 1 8 134217728 12723360394268 20150416 18:25:44 NORMAL
k/o1_mf_1j6G9Ptth_.flb
/oradata06/fra/TSTDB1/flashbac 5 1 9 134217728 12723360403709 20150416 20:00:59 NORMAL
k/o1_mf_1j6GAilaq_.flb
/oradata06/fra/TSTDB1/flashbac 6 1 10 134217728 12723360405698 20150416 20:27:08 NORMAL
k/o1_mf_1j6LVKto5_.flb
/oradata06/fra/TSTDB1/flashbac 1 1 11 134217728 12723360414458 20150416 21:55:23 NORMAL
k/o1_mf_1j6D2HxYT_.flb
/oradata06/fra/TSTDB1/flashbac 7 1 12 134217728 12723360445736 20150416 23:55:26 NORMAL
k/o1_mf_1j6RuNt1f_.flb
/oradata06/fra/TSTDB1/flashbac 8 1 13 134217728 12723360459837 20150417 02:25:26 NORMAL
k/o1_mf_1j6YbsKVD_.flb
/oradata06/fra/TSTDB1/flashbac 9 1 14 134217728 12723360476287 20150417 04:55:26 NORMAL
k/o1_mf_1j6g-H73H_.flb
因為是flashback操作所以要從最新的一個flashback log開始往前恢復
--將o1_mf_1j6g-H73H_.flb改回原來的名稱,繼續執行flashback
mv o1_mf_1j6g-H73H_.flb.old o1_mf_1j6g-H73H_.flb
SYS@tstdb1-SQL> flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss');
flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38701: Flashback database log 8 seq 13 thread 1: "/oradata06/fra/TSTDB1/flashback/o1_mf_1j6YbsKVD_.flb" <---這次要尋找的是sequence#=13的log
ORA-17503: ksfdopn:4 Failed to open file /oradata06/fra/TSTDB1/flashback/o1_mf_1j6YbsKVD_.flb
ORA-17500: ODM err:File does not exist
sequence#=13的first_time是20150417 02:25:26
--將o1_mf_1j6YbsKVD_.flb改回原來的名稱,繼續執行flashback
mv o1_mf_1j6YbsKVD_.flb.old o1_mf_1j6YbsKVD_.flb
SYS@tstdb1-SQL> flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss');
flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38701: Flashback database log 7 seq 12 thread 1: "/oradata06/fra/TSTDB1/flashback/o1_mf_1j6RuNt1f_.flb" <---這次要尋找的是sequence#=12的log
ORA-17503: ksfdopn:4 Failed to open file /oradata06/fra/TSTDB1/flashback/o1_mf_1j6RuNt1f_.flb
ORA-17500: ODM err:File does not exist
sequence#=12的first_time是20150416 23:55:26,照此我們可以推斷出如果要flashback到'20150416 18:51:24',必須一直應用到sequence#=8對應的o1_mf_1j6G9Ptth_.flb
--我們先把sequence#=12、11、10、9三個檔案改回原來的名稱,繼續執行flashback
mv o1_mf_1j6RuNt1f_.flb.old o1_mf_1j6RuNt1f_.flb
mv o1_mf_1j6GAilaq_.flb.old o1_mf_1j6GAilaq_.flb
mv o1_mf_1j6LVKto5_.flb.old o1_mf_1j6LVKto5_.flb
mv o1_mf_1j6D2HxYT_.flb.old o1_mf_1j6D2HxYT_.flb
SYS@tstdb1-SQL> flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss');
flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38701: Flashback database log 4 seq 8 thread 1: "/oradata06/fra/TSTDB1/flashback/o1_mf_1j6G9Ptth_.flb"
ORA-17503: ksfdopn:4 Failed to open file /oradata06/fra/TSTDB1/flashback/o1_mf_1j6G9Ptth_.flb
ORA-17500: ODM err:File does not exist
--我們把sequence#=8所對應的o1_mf_1j6G9Ptth_.flb改回原來的名稱,再執行flashback database時不在索要新的flashback log,在apply完o1_mf_1j6G9Ptth_.flb這個flashback log後資料庫所處的時間點應該大於20150416 18:25:44,因為o1_mf_1j6G9Ptth_.flb的first time=20150416 18:25:44,隨後進入apply redolog階段
mv o1_mf_1j6G9Ptth_.flb.old o1_mf_1j6G9Ptth_.flb
SYS@tstdb1-SQL> flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss');
flashback database to timestamp to_date('20150416 18:51:24','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38754: FLASHBACK DATABASE not started; required redo log is not available
ORA-38762: redo logs needed for SCN 12723360396485 to SCN End-of-Redo
ORA-38761: redo log sequence 510 in thread 1, incarnation 1 could not be accessed
--在RMAN裡執行flashback database成功
RMAN> flashback database to time '20150416 18:51:24';
Starting flashback at 20150418 16:31:39
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=794 device type=DISK
starting media recovery
archived log for thread 1 with sequence 596 is already on disk as file /oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_1_596_1j6Myy1FQ_.arc
media recovery complete, elapsed time: 00:00:01
Finished flashback at 20150418 16:31:57
--因為apply完flashback log後資料庫所處的時間大於等於20150416 18:25:44,而sequence#=596這個archivelog涵蓋了'20150416 18:51:24'時間點,FIRST_TIME<'20150416 18:51:24'<NEXT_TIME,所以只需要sequence#=596這一個archivelog就可完成
set numwidth 16
col name format a50
set linesize 150
SYS@tstdb1-SQL> select sequence#,first_change#,first_time,NEXT_CHANGE#,next_time,archived,name from v$archived_log where SEQUENCE# in (596);
SEQUENCE# FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME ARC NAME
---------------- ---------------- ----------------- ---------------- ----------------- --- --------------------------------------------------
596 12723360396183 20150416 18:26:01 12723360405745 20150416 20:27:11 YES /oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_
1_596_1j6Myy1FQ_.arc
我們推薦使用RMAN來進行flashback database操作,RMAN的操作更為自動化,比如當所需要的archivelog備份之後從磁碟上刪除了,rman能自動執行restore archivelog的操作。上面在sqlplus裡執行flashback database只是為了看清apply flashback log的過程
後向flashback的總結:
在apply flashback log階段總是從sequence#最大的那個flashback log開始,按照sequence#從大到小的順序逐個進行apply,直至應用到first_time<flashback目標時間的那個flashback log為止,在apply某個特定flashback log的時候也是先從檔案尾部開始往檔案頭方向逆向的讀取,因為flashback log是順序寫入的,先更新的data block的before-image較之後更新的data block的before-image存放在更加靠近檔案頭的位置,所以在flashback的時候要從後往前apply,總之對於flashback過程中涉及的操作都要逆向的去考慮。apply redolog階段選取的archivelog其時間範圍一定要處於"最後一個被應用的flashback log的first_time"及"flashback目標時間"所構成的這個時間範圍,上面的例子裡就是涵蓋20150416 18:25:44~20150416 18:51:24這一範圍的archivelog都會被apply。
###前向flashback的場景
如果進行了一次後向flashback後,發現這個時間太舊了進而要繼續flashback到一個較近的時間點,這個時候就要用到前向恢復了。我們延用後向flashback的結果,
--假設資料庫當前所處的時間點是'20150416 21:00:01'現在要flashback到'20150417 02:00:00'這個時間點
set numwidth 16
col name format a50
set linesize 150
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile_header;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/sysaux01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/undotbs01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/users01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0329_1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/xdbts1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
8 rows selected.
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/sysaux01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/undotbs01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/users01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0329_1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/xdbts1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
SYS@tstdb1-SQL> select status from v$instance;
STATUS
------------
MOUNTED
--仍然先將flashback log改名
oracle@jq570322b:/oradata06/fra/TSTDB1/flashback>ls -1 *.flb | xargs -n1 -I{} mv {} {}.old
oracle@jq570322b:/oradata06/fra/TSTDB1/flashback>ls -rlt
total 2621600
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6D2RXXr_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 18:25 o1_mf_1j6G7_Xrb_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 20:00 o1_mf_1j6G9Ptth_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 20:27 o1_mf_1j6GAilaq_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 21:55 o1_mf_1j6LVKto5_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 16 23:55 o1_mf_1j6D2HxYT_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 17 02:25 o1_mf_1j6RuNt1f_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 17 04:55 o1_mf_1j6YbsKVD_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 17 04:55 o1_mf_1j6pMheJF_.flb.old
-rw-r----- 1 oracle oinstall 134225920 Apr 18 17:52 o1_mf_1j6g-H73H_.flb.old
--當前flashback log資訊
col name format a30
set linesize 170 pagesize 100
select * from V$FLASHBACK_DATABASE_LOGFILE order by sequence#;
NAME LOG# THREAD# SEQUENCE# BYTES FIRST_CHANGE# FIRST_TIME TYPE
------------------------------ ---------------- ---------------- ---------------- ---------------- ---------------- ----------------- ---------
/oradata06/fra/TSTDB1/flashbac 4 1 8 134217728 12723360394268 20150416 18:25:44 RESERVED
k/o1_mf_1j6G9Ptth_.flb
/oradata06/fra/TSTDB1/flashbac 5 1 9 134217728 12723360403709 20150416 20:00:59 NORMAL
k/o1_mf_1j6GAilaq_.flb
/oradata06/fra/TSTDB1/flashbac 6 1 10 134217728 12723360405698 20150416 20:27:08 NORMAL
k/o1_mf_1j6LVKto5_.flb
/oradata06/fra/TSTDB1/flashbac 1 1 11 134217728 12723360414458 20150416 21:55:23 NORMAL
k/o1_mf_1j6D2HxYT_.flb
/oradata06/fra/TSTDB1/flashbac 7 1 12 134217728 12723360445736 20150416 23:55:26 NORMAL
k/o1_mf_1j6RuNt1f_.flb
/oradata06/fra/TSTDB1/flashbac 8 1 13 134217728 12723360459837 20150417 02:25:26 NORMAL
k/o1_mf_1j6YbsKVD_.flb
/oradata06/fra/TSTDB1/flashbac 9 1 14 134217728 12723360476287 20150417 04:55:26 NORMAL
k/o1_mf_1j6g-H73H_.flb
--仍然是一個不斷改回原來名稱的過程
SYS@tstdb1-SQL> flashback database to timestamp to_date('20150417 02:00:00','yyyymmdd hh24:mi:ss');
flashback database to timestamp to_date('20150417 02:00:00','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38701: Flashback database log 9 seq 14 thread 1:
"/oradata06/fra/TSTDB1/flashback/o1_mf_1j6g-H73H_.flb"
ORA-17503: ksfdopn:4 Failed to open file
/oradata06/fra/TSTDB1/flashback/o1_mf_1j6g-H73H_.flb
ORA-17500: ODM err:File does not exist
mv o1_mf_1j6g-H73H_.flb.old o1_mf_1j6g-H73H_.flb <----將sequence#=14的flashback log恢復原來的名稱
SYS@tstdb1-SQL> r
1* flashback database to timestamp to_date('20150417 02:00:00','yyyymmdd hh24:mi:ss')
flashback database to timestamp to_date('20150417 02:00:00','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38701: Flashback database log 8 seq 13 thread 1:
"/oradata06/fra/TSTDB1/flashback/o1_mf_1j6YbsKVD_.flb"
ORA-17503: ksfdopn:4 Failed to open file
/oradata06/fra/TSTDB1/flashback/o1_mf_1j6YbsKVD_.flb
ORA-17500: ODM err:File does not exist
mv o1_mf_1j6YbsKVD_.flb.old o1_mf_1j6YbsKVD_.flb <----將sequence#=13的flashback log恢復原來的名稱
SYS@tstdb1-SQL> r
1* flashback database to timestamp to_date('20150417 02:00:00','yyyymmdd hh24:mi:ss')
flashback database to timestamp to_date('20150417 02:00:00','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38701: Flashback database log 7 seq 12 thread 1:
"/oradata06/fra/TSTDB1/flashback/o1_mf_1j6RuNt1f_.flb"
ORA-17503: ksfdopn:4 Failed to open file
/oradata06/fra/TSTDB1/flashback/o1_mf_1j6RuNt1f_.flb
ORA-17500: ODM err:File does not exist
mv o1_mf_1j6RuNt1f_.flb.old o1_mf_1j6RuNt1f_.flb <----最後將sequence#=12的flashback log改回原名
SYS@tstdb1-SQL> flashback database to timestamp to_date('20150417 02:00:00','yyyymmdd hh24:mi:ss') <---再次執行flashback後提示需要archivelog,說明apply flashback log階段結束,進入apply redolog階段
flashback database to timestamp to_date('20150417 02:00:00','yyyymmdd hh24:mi:ss')
*
ERROR at line 1:
ORA-38754: FLASHBACK DATABASE not started; required redo log is not available
ORA-38762: redo logs needed for SCN 12723360398209 to SCN End-of-Redo
ORA-38761: redo log sequence 510 in thread 1, incarnation 1 could not be accessed
從v$flashback_database_logfile能看到o1_mf_1j6RuNt1f_.flb的時間跨度在20150416 23:55:26~20150417 02:25:26,我們要flashback的目標時間20150417 02:00:00包含在此範圍,o1_mf_1j6RuNt1f_.flb應該是apply flashback log的終點
select * from V$FLASHBACK_DATABASE_LOGFILE order by sequence#;
NAME LOG# THREAD# SEQUENCE# BYTES FIRST_CHANGE# FIRST_TIME TYPE
------------------------------ ---------------- ---------------- ---------------- ---------------- ---------------- ----------------- ---------
/oradata06/fra/TSTDB1/flashbac 7 1 12 134217728 12723360445736 20150416 23:55:26 NORMAL
k/o1_mf_1j6RuNt1f_.flb
--這時我們觀察一下v$datafile、v$datafile_header兩個檢視,發現checkpoint_time還是維持在'20150416 21:00:01',所以還需要recover
set numwidth 16
col name format a50
set linesize 150
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile_header;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/sysaux01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/undotbs01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/users01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0329_1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/xdbts1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
8 rows selected.
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/sysaux01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/undotbs01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/users01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0329_1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/xdbts1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
--在RMAN裡執行flashback database以完成整個flashback過程
RMAN> flashback database to time '20150417 02:00:00';
Starting flashback at 20150419 05:21:51
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: SID=596 device type=DISK
starting media recovery
archived log for thread 1 with sequence 597 is already on disk as file /oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_1_597_1j6QDIw3d_.arc
archived log for thread 1 with sequence 598 is already on disk as file /oradata06/fra/TSTDB1/archivelog/2015_04_17/o1_mf_1_598_1j6b6vl8N_.arc
archived log for thread 1 with sequence 599 is already on disk as file /oradata06/fra/TSTDB1/archivelog/2015_04_17/o1_mf_1_599_1j6nSR03C_.arc
media recovery complete, elapsed time: 00:00:07
Finished flashback at 20150419 05:22:03
--sequence#=597、598、599三個archivelog的時間跨度是20150416 20:27:11~20150417 04:21:16
set numwidth 16
col name format a50
set linesize 150
SYS@tstdb1-SQL> select sequence#,first_change#,first_time,NEXT_CHANGE#,next_time,archived,name from v$archived_log where SEQUENCE# in (597,598,599);
SEQUENCE# FIRST_CHANGE# FIRST_TIME NEXT_CHANGE# NEXT_TIME ARC NAME
---------------- ---------------- ----------------- ---------------- ----------------- --- --------------------------------------------------
597 12723360405745 20150416 20:27:11 12723360412398 20150416 21:25:26 YES /oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_
1_597_1j6QDIw3d_.arc
598 12723360412398 20150416 21:25:26 12723360449943 20150417 00:40:30 YES /oradata06/fra/TSTDB1/archivelog/2015_04_17/o1_mf_
1_598_1j6b6vl8N_.arc
599 12723360449943 20150417 00:40:30 12723360473840 20150417 04:21:16 YES /oradata06/fra/TSTDB1/archivelog/2015_04_17/o1_mf_
1_599_1j6nSR03C_.arc
被apply的redolog的起始點是資料庫執行flashback前的時間點20150416 21:00:01,而非之前應用的最後一個flashback log o1_mf_1j6RuN1f_.flb所對應的first_time:20150416 23:55:26(如果這樣僅需從598這個archivelog開始)
---觀察datafile的checkpoint_time是20150417 02:00:03比我們目標時間快了3秒鐘,因為我們使用的是time而不是scn作為恢復目標的,有一定偏差是正常的
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile_header;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/sysaux01.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/undotbs01.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/users01.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/ts0329_1.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/xdbts1.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
8 rows selected.
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/sysaux01.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/undotbs01.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/users01.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/ts0329_1.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/xdbts1.dbf 12723360457457 20150417 02:00:03
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
前向flashback的總結:
回顧一下上面的例子,資料庫所處時間是20150416 21:00:01,flashback的目標時間是20150417 02:00:00,在apply flashback log階段還是從sequence#最大的那個flashback log開始,按照sequence#從大到小的順序逐個進行apply,最後一個被apply的flashback log其first_time剛好小於20150417 02:00:00,這個邏輯與後向flashback一樣。但在apply redolog的時候卻僅參考資料庫在執行flashback前所處的時間20150416 21:00:01,選取20150416 21:00:01~flashback目標時間20150417 02:00:00時間段內Archivelog進行apply,並沒有將最後一個被apply的flashback log o1_mf_1j6RuNt1f_.flb所對應的20150416 23:55:26這一時間作為選擇archivelog的起始時間,這一點和後向flashback是有區別的。其實我們仔細想一下,前向flashback就是recover的過程,只需Apply redolog,flashback log可以不參與進來,但RMAN還是循規蹈矩的把它作為一次flashback來看待先apply flashback log再apply redolog,這樣做的好處是使用上比較方便使用者不必去關心目標時間點與資料庫當前所處時間點間的先後關係,但當flashback log比較多的時候效率會降低不如直接執行recover來的快。
--使用recover database將database 從20150416 21:00:01 flashback到20150417 02:00:00
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/sysaux01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/undotbs01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/users01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0329_1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/xdbts1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
8 rows selected.
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile_header;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/sysaux01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/undotbs01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/users01.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0329_1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/xdbts1.dbf 12723360408715 20150416 21:00:01
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
SYS@tstdb1-SQL> recover database until time '20150417 02:00:00';
ORA-00279: change 12723360408715 generated at 04/16/2015 21:00:01 needed for
thread 1
ORA-00289: suggestion :
/oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_1_597_1j6QDIw3d_.arc
ORA-00280: change 12723360408715 for thread 1 is in sequence #597
Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
Log applied.
Media recovery complete.
***alert.log顯示598、599兩個是直接應用了online redo:
Sun Apr 19 07:27:50 2015
ALTER DATABASE RECOVER database until time '20150417 02:00:00'
Media Recovery Start
started logmerger process
Parallel Media Recovery started with 16 slaves
ORA-279 signalled during: ALTER DATABASE RECOVER database until time '20150417 02:00:00' ...
ALTER DATABASE RECOVER CONTINUE DEFAULT
Media Recovery Log /oradata06/fra/TSTDB1/archivelog/2015_04_16/o1_mf_1_597_1j6QDIw3d_.arc
Sun Apr 19 07:27:59 2015
Recovery of Online Redo Log: Thread 1 Group 3 Seq 598 Reading mem 0
Mem# 0: /oradata06/testaaaaa/redo03a.log
Mem# 1: /oradata06/testaaaaa/redo03b.log
Recovery of Online Redo Log: Thread 1 Group 2 Seq 599 Reading mem 0
Mem# 0: /oradata06/testaaaaa/redo02a.log
Mem# 1: /oradata06/testaaaaa/redo02b.log
Incomplete Recovery applied until change 12723360457448 time 04/17/2015 02:00:00
Sun Apr 19 07:28:03 2015
Media Recovery Complete (tstdb1)
Completed: ALTER DATABASE RECOVER CONTINUE DEFAULT
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/sysaux01.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/undotbs01.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/users01.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/ts0329_1.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/xdbts1.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
8 rows selected.
SYS@tstdb1-SQL> select name,checkpoint_change#,CHECKPOINT_TIME from v$datafile_header;
NAME CHECKPOINT_CHANGE# CHECKPOINT_TIME
-------------------------------------------------- ------------------ -----------------
/oradata06/testaaaaa/system01.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/sysaux01.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/undotbs01.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/users01.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/ts0329_1.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/xdbts1.dbf 12723360457448 20150417 02:00:00
/oradata06/testaaaaa/ts0212.dbf 12723357761339 20150315 09:56:23
/oradata06/testaaaaa/ts0212_1.dbf 12723357761339 20150315 09:56:23
//////////////////
//該給flashback log預留多少空間
//////////////////
--查詢select * from v$flashback_database_log
SYS@tstdb1-SQL> select * from v$flashback_database_log;
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_ RETENTION_TARGET FLASHBACK_SIZE ESTIMATED_FLASHBACK_SIZE
-------------------- ----------------- ---------------- ---------------- ------------------------
12723360406546 20150416 20:35:53 6000 939524096 6677094400
FLASHBACK_SIZE:是當前flashback log的大小
ESTIMATED_FLASHBACK_SIZE:根據當前的系統Activity以及retention_target估算出的flashback log可能使用到的最大空間
--改小db_flashback_retention_target後,ESTIMATED_FLASHBACK_SIZE立馬降低到4439108266
SYS@tstdb1-SQL> alter system set db_flashback_retention_target=4000 scope=both;
System altered.
SYS@tstdb1-SQL> select * from v$flashback_database_log
2 ;
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_ RETENTION_TARGET FLASHBACK_SIZE ESTIMATED_FLASHBACK_SIZE
-------------------- ----------------- ---------------- ---------------- ------------------------
12723360406546 20150416 20:35:53 4000 939524096 4439108266
通常是設定好db_flashback_retention_target,讓資料庫執行一段時間後根據ESTIMATED_FLASHBACK_SIZE的值再加上一定的冗餘度來合理的設計Fast Recovery Area的大小
--也可以透過v$FLASH_RECOVERY_AREA_USAGE獲得flashback log在FRA裡的佔比
SYS@tstdb1-SQL> select * from V$FLASH_RECOVERY_AREA_USAGE;
FILE_TYPE PERCENT_SPACE_USED PERCENT_SPACE_RECLAIMABLE NUMBER_OF_FILES
-------------------- ------------------ ------------------------- ----------------
CONTROL FILE 0 0 0
REDO LOG 0 0 0
ARCHIVED LOG 54.82 0 141
BACKUP PIECE 1.01 0 14
IMAGE COPY .23 0 1
FLASHBACK LOG 6.88 0 11
FOREIGN ARCHIVED LOG 0 0 0
//////////////////
//flashback log所產生的IO量有多大
//////////////////
set linesize 120
SYS@tstdb1-SQL> select n.name,s.value from v$statname n,v$sysstat s where s.statistic#=n.statistic# and n.name in ('flashback log writes','flashback log write bytes','physical write bytes','physical writes');
2 ;
NAME VALUE
---------------------------------------------------------------- ----------
physical writes 145525
physical write bytes 1192140800
flashback log writes 2941
flashback log write bytes 1313931264
SYS@tstdb1-SQL> select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- -------------- ---------- ---------- ------------------------
20150419 17:06:12 20150419 17:17:29 1313931264 1191690240 1837481984 0
可以透過v$sysstat和v$flashback_database_stat兩個檢視瞭解flashback log上的IO開銷及其與資料庫總的寫入IO之間的比例關係
其中
flashback log write bytes:Total size in bytes of flashback database data written by RVWR to flashback database logs
physical write bytes:Total size in bytes of all disk writes from the database application activity
//////////////////
//單個flashback log的大小如何決定
//////////////////
oracle並沒有提供設定flashback log大小的引數,flashback log的建立和維護完全是自動的,我們只能透過隱含引數來控制flashback log的大小,和flashback log相關的隱含引數如下
col ksppinm format a50
col ksppstvl format a20
set linesize 100
select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_size_based_on_redo','_db_flashback_log_min_size','_flashback_log_size','_flashback_log_min_size','_ksmg_granule_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_ksmg_granule_size 16777216
_flashback_log_size 1000
_flashback_log_min_size 100
_db_flashback_log_min_size 16777216
_flashback_size_based_on_redo TRUE
預設情況下_flashback_size_based_on_redo引數值為TRUE,表示flashback log的大小參照redolog大小的平均值,簡單的測試驗證一下
---當前資料庫有三組redolog group,每組兩個member,每個member大小為134217728
col member format a50
set linesize 120
SYS@tstdb1-SQL> select l.group#,f.member,l.bytes from v$log l,v$logfile f where l.group#=f.group#;
GROUP# MEMBER BYTES
---------- -------------------------------------------------- ----------
1 /oradata06/testaaaaa/redo01a.log 134217728
1 /oradata06/testaaaaa/redo01b.log 134217728
2 /oradata06/testaaaaa/redo02a.log 134217728
2 /oradata06/testaaaaa/redo02b.log 134217728
3 /oradata06/testaaaaa/redo03a.log 134217728
3 /oradata06/testaaaaa/redo03b.log 134217728
---當前flashback log大小是134217728
SYS@tstdb1-SQL> select distinct bytes from v$flashback_database_logfile;
BYTES
----------------
134217728
---增加兩組redolog,每個member的大小是256M
alter database add logfile group 4 ('/oradata06/testaaaaa/redo04a.log','/oradata06/testaaaaa/redo04b.log') size 256m;
alter database add logfile group 5 ('/oradata06/testaaaaa/redo05a.log','/oradata06/testaaaaa/redo05b.log') size 256m;
SYS@tstdb1-SQL> select l.group#,f.member,l.bytes from v$log l,v$logfile f where l.group#=f.group#;
GROUP# MEMBER BYTES
---------------- -------------------------------------------------- ----------------
1 /oradata06/testaaaaa/redo01a.log 134217728
1 /oradata06/testaaaaa/redo01b.log 134217728
2 /oradata06/testaaaaa/redo02a.log 134217728
2 /oradata06/testaaaaa/redo02b.log 134217728
3 /oradata06/testaaaaa/redo03a.log 134217728
3 /oradata06/testaaaaa/redo03b.log 134217728
4 /oradata06/testaaaaa/redo04a.log 268435456
4 /oradata06/testaaaaa/redo04b.log 268435456
5 /oradata06/testaaaaa/redo05a.log 268435456
5 /oradata06/testaaaaa/redo05b.log 268435456
---為使新的flashback log size生效,需要重新關閉並開啟flashback功能
alter database flashback off; <---off後原有的flashback log會被自動清除
alter database flashback on;
---新的size是187899904,透過(134217728x3+268435456x2)/5 計算得到
SYS@tstdb1-SQL> select distinct bytes from v$flashback_database_logfile;
BYTES
----------------
187899904
當_flashback_size_based_on_redo=FALSE時flashback log size如何決定?
alter system set "_flashback_size_based_on_redo"=FALSE scope=memory;
alter database flashback off;
alter database flashback on;
SYS@tstdb1-SQL> select distinct bytes from v$flashback_database_logfile;
BYTES
----------------
16777216
16777216正好是_db_flashback_log_min_size的引數值
alter system set "_db_flashback_log_min_size"=20m scope=memory;
alter database flashback off;
alter database flashback on;
SYS@tstdb1-SQL> select distinct bytes from v$flashback_database_logfile;
BYTES
----------------
20971520
alter system set "_db_flashback_log_min_size"=4m scope=memory;
alter database flashback off;
alter database flashback on;
SYS@tstdb1-SQL> select distinct bytes from v$flashback_database_logfile;
BYTES
----------------
15941632
因為當前SGA裡的最小記憶體分配單位是由_ksmg_granule_size指定的,當前為16777216,flashback log file大小不能小於_ksmg_granule_size值,所以儘管我們將_db_flashback_log_min_size設定為4m,生成出來的flashback log還是接近16M,我們把_ksmg_granule_size改為4m後,是否生成flashback log size就會是4M一個了
alter system set "_flashback_size_based_on_redo"=FALSE scope=spfile;
alter system set "_ksmg_granule_size"=4194304 scope=spfile;
alter system set "_db_flashback_log_min_size"=4m scope=spfile;
startup force
col ksppinm format a50
col ksppstvl format a20
set linesize 100
SYS@tstdb1-SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_size_based_on_redo','_db_flashback_log_min_size','_flashback_log_size','_flashback_log_min_size','_ksmg_granule_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_ksmg_granule_size 4194304
_flashback_log_size 1000
_flashback_log_min_size 100
_db_flashback_log_min_size 4194304
_flashback_size_based_on_redo FALSE
alter database flashback off;
alter database flashback on;
SYS@tstdb1-SQL> select distinct bytes from v$flashback_database_logfile;
BYTES
----------
8192000
修改_ksmg_granule_size=4194304後,發現flashback log size變成了8M,因為_flashback_log_size引數生效了,_flashback_log_size=1000表示一個flashback log的大小是1000個block size,當資料庫block_size=8192是,flashback log size就是8M一個,再將_flashback_log_size設定為500
alter system set "_flashback_log_size"=500 scope=spfile;
startup force
SYS@tstdb1-SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_size_based_on_redo','_db_flashback_log_min_size','_flashback_log_size','_flashback_log_min_size','_ksmg_granule_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_ksmg_granule_size 4194304
_flashback_log_size 500
_flashback_log_min_size 100
_db_flashback_log_min_size 4194304
_flashback_size_based_on_redo FALSE
alter database flashback off;
alter database flashback on;
SYS@tstdb1-SQL> select distinct bytes from v$flashback_database_logfile;
BYTES
----------
4194304
至此,終於將flashback log size調整為4M大小了,但是別忘了還有一個引數_flashback_log_min_size尚未發揮過作用,_flashback_log_min_size=100表示的是flashback log的最小size是100個block,對於block_size=8k來說就是800k,我們把_flashback_log_min_size調大
alter system set "_flashback_log_min_size"=768 scope=spfile;
startup force
col ksppinm format a50
col ksppstvl format a20
set linesize 100
SYS@tstdb1-SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_size_based_on_redo','_db_flashback_log_min_size','_flashback_log_size','_flashback_log_min_size','_ksmg_granule_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_ksmg_granule_size 4194304
_flashback_log_size 500
_flashback_log_min_size 768
_db_flashback_log_min_size 4194304
_flashback_size_based_on_redo FALSE
alter database flashback off;
alter database flashback on;
SYS@tstdb1-SQL> select distinct bytes from v$flashback_database_logfile;
BYTES
----------
6291456
這下變成了6M
對於控制flashback log size的幾個隱含引數總結如下:
_flashback_log_min_size和_db_flashback_log_min_size都能用來指定flashback log size的最小值,_flashback_log_min_size的單位是blocks,_db_flashback_log_min_size的單位是位元組,_db_flashback_log_min_size的值不能小於_ksmg_granule_size,因為_ksmg_granule_size是SGA裡分配的最小單位;
_flashback_log_size是以blocks為單為來指定flashback log size的大小。這幾個引數的生效邏輯如下:
1、_flashback_size_based_on_redo=TRUE時
由redolog的平均大小決定flashback log size,其它隱含引數的值不予考慮
2、_flashback_size_based_on_redo=FALSE時
flashback log size最小值=min(_ksmg_granule_size,block_size*_flashback_log_min_size,_db_flashback_log_min_size)
若_flashback_log_size*block_size > flashback log size最小值則採用_flashback_log_size*block_size為flashback log size
若_flashback_log_size*block_size < flashback log size最小值則由flashback log size最小值決定flashback log size
//////////////////
// flashback generation buffer大小是如何設定的
//////////////////
flashback generation buffer是shared pool裡一塊分配給flashback使用的記憶體空間,存放從buffer cache複製過來的data block before image,RVWR程式會將flashback generation buffer的內容寫入flashback log。oracle同樣也沒有提供能設定flashback generation buffer大小的方法,只有名為_flashback_generation_buffer_size的隱含引數:
col ksppinm format a50
col ksppstvl format a20
set linesize 100
SYS@tstdb1-SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_generation_buffer_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_flashback_generation_buffer_size 67108864
--
SYS@tstdb1-SQL> select * from v$sgastat where pool='shared pool' and name like '%flash%';
POOL NAME BYTES
------------ -------------------------- ----------
shared pool flashback_marker_cache_si 9200
shared pool flashback generation buff 15937344
--修改_flashback_generation_buffer_size=33554432,flashback generation buffer實際佔用空間還是15937344
alter system set "_flashback_generation_buffer_size"=33554432 scope=spfile;
startup force
SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_generation_buffer_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_flashback_generation_buffer_size 33554432
SQL> select * from v$sgastat where pool='shared pool' and name like '%flash%';
POOL NAME BYTES
------------ -------------------------- ----------
shared pool flashback_marker_cache_si 9200
shared pool flashback generation buff 15937344
--修改_ksmg_granule_size=33554432,恢復_flashback_generation_buffer_size至預設值=67108864,flashback generation buffer實際佔用空間變為了一個granule的大小31874880
alter system set "_flashback_generation_buffer_size"=67108864 scope=spfile;
alter system set "_ksmg_granule_size"=33554432 scope=spfile;
startup force
SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_generation_buffer_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_flashback_generation_buffer_size 67108864
SYS@tstdb1-SQL> select * from v$sgastat where pool='shared pool' and name like '%flash%';
POOL NAME BYTES
------------ -------------------------- ----------
shared pool flashback_marker_cache_si 9200
shared pool flashback generation buff 31874880
--設定_ksmg_granule_size=83886080,flashback generation buffer還是保持_flashback_generation_buffer_size的設定值67108864
alter system set "_ksmg_granule_size"=83886080 scope=spfile;
startup force
SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_generation_buffer_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_flashback_generation_buffer_size 67108864
SYS@tstdb1-SQL> select * from v$sgastat where pool='shared pool' and name like '%flash%';
POOL NAME BYTES
------------ -------------------------- ----------
shared pool flashback_marker_cache_si 9200
shared pool flashback generation buff 67108864
--將_flashback_generation_buffer_size調大至104857600,flashback generation buffer略微上升至71991760
alter system set "_flashback_generation_buffer_size"=104857600 scope=spfile;
startup force
col ksppinm format a50
col ksppstvl format a20
set linesize 100
SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_generation_buffer_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_flashback_generation_buffer_size 104857600
SQL> select * from v$sgastat where pool='shared pool' and name like '%flash%';
POOL NAME BYTES
------------ -------------------------- ----------
shared pool flashback_marker_cache_si 9200
shared pool flashback generation buff 71991760
--將_flashback_generation_buffer_size調大至204857600,flashback generation buffer升高至127504192
alter system set "_flashback_generation_buffer_size"=204857600 scope=spfile;
startup force
SQL> select ksppinm,ksppstvl from x$ksppi x, x$ksppcv y where (x.indx = y.indx) and ksppinm in ('_flashback_generation_buffer_size');
KSPPINM KSPPSTVL
-------------------------------------------------- --------------------
_flashback_generation_buffer_size 204861440
SQL> select * from v$sgastat where pool='shared pool' and name like '%flash%';
POOL NAME BYTES
------------ -------------------------- ----------
shared pool flashback_marker_cache_si 9200
shared pool flashback generation buff 127504192
關於_flashback_generation_buffer_size引數在控制flashback generation buffer大小方面似乎沒有太多的規律可循,我們暫且只能得出如下結論:
當_ksmg_granule_size >= _flashback_generation_buffer_size時,_flashback_generation_buffer_size引數生效
當_ksmg_granule_size < _flashback_generation_buffer_size時,flashback_generation_buffer的實際大小可能>_ksmg_granule_size也可能<_ksmg_granule_size,但不會超過_flashback_generation_buffer_size
//////////////////
// v$session_longops能觀察到flashback的進度
//////////////////
SYS@tstdb1-SQL> select opname,target,sofar,totalwork,message from v$session_longops;
OPNAME TARGET SOFAR TOTALWORK MESSAGE
-------------------- -------------------- ---------- ---------- --------------------------------------------------
Flashback Database 1241 1256 Flashback Database: Flashback Data Applied : 1241
out of 1256 Megabytes done
//////////////////
//flashback log何時會被清理
//////////////////
早於DB_FLASHBACK_RETENTION_TARGET時間的flashback log會被自動清理出Fast Recovery Area。如果FRA空間不夠用時會覆蓋掉較早生成的flashback log,儘管這個被覆蓋的flashback log處於DB_FLASHBACK_RETENTION_TARGET指定的保留期之內
當有新的flashback log需要生成而Fast Recovery Area又無可用空間的情況下,會從較早生成的flashback log開始重用(不管其是否在DB_FLASHBACK_RETENTION_TARGET定義的保留時間內)
當Fast Recovery Area空間用滿,清理其中已經備份過的archived log時會連帶清理掉使用該archived log的Flashback log
////////////
// 常用的監控flashback Database的檢視有哪些
////////////
##1、v$flashback_database_logfile:flashback log的大小、位置、SCN等資訊
col name format a50
set linesize 160 numwidth 16 pagesize 60
set numformat 99999999999999999
select * from V$FLASHBACK_DATABASE_LOGFILE;
NAME LOG# THREAD# SEQUENCE# BYTES FIRST_CHANGE#
-------------------------------------------------- ------------------ ------------------ ------------------ ------------------ ------------------
FIRST_TIME TYPE
----------------- ---------
/oradata06/fra/TSTDB1/flashback/o1_mf_1l8k5mVou_.f 1 1 1 134217728 12723365349159
lb
20150729 12:53:29 NORMAL
/oradata06/fra/TSTDB1/flashback/o1_mf_1l8k6047n_.f 2 1 1 134217728 0
lb
RESERVED
type=normal:處於db_flashback_retention_target保留期限內的log
type=RESERVED:下一個即將使用的flashback log,這個flashback log file可以是以前曾經使用過的檔案,但目前已經過期;也可以是新建立出來的檔案,該檔案當前僅有一個flashback log的基本結構,沒有實質內容,status=RESERVED的flashback log它的sequence#號為1
##2、V$FLASHBACK_DATABASE_LOG:db_flashback_retention_target設定值、實際能夠閃回到的時間點、flashback logfile實際以及預估的空間佔用量資訊
select * from V$FLASHBACK_DATABASE_LOG;
OLDEST_FLASHBACK_SCN OLDEST_FLASHBACK_ RETENTION_TARGET FLASHBACK_SIZE ESTIMATED_FLASHBACK_SIZE
-------------------- ----------------- ------------------ ------------------ ------------------------
12723365349159 20150729 12:53:29 2000 268435456 0
##3、select * from V$FLASHBACK_DATABASE_STAT:間隔時間內flashback data、redolog以及datafile讀寫所產生的位元組數的對比,用來衡量flashback database在IO上產生的開銷
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ------------------ ------------------ ------------------ ------------------------
20150729 12:53:29 20150729 13:04:21 4808704 1130496 1977856 0
////////////
// flashback log能否被dump
////////////
與online redolog類似,flashback logfile也能夠被dump,常用命令如下:
###dump一個特定例項下的所有flashback logfile
ALTER SYSTEM DUMP FLASHBACK THREAD 【thread_number】
###dump某個特定的flashback logfile,【log_file_number】可以透過V$FLASHBACK_DATABASE_LOGFILE.log#獲得
ALTER SYSTEM DUMP FLASHBACK LOGFILE 【log_file_number】
###從某個特定的flashback logfile裡dump某一個資料塊的所有記錄
ALTER SYSTEM DUMP FLASHBACK LOGFILE 【log_file_number】DBA 【absolute_file_number】【block_number】;
例如:alter system dump flashback logfile 1 dba 9 40587; 表示dump出logfile 1裡編號為9的資料檔案裡第40587個block的所有記錄
###dump某個特定flashback logfile裡的概要資訊:
ALTER SYSTEM DUMP FLASHBACK LOGFILE 【log_file_number】 LOGICAL;
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/53956/viewspace-1755289/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 汽車基礎知識問答
- ERP基礎知識問答
- 區塊鏈基礎知識問答區塊鏈
- [基礎入門]網路安全知識問答(二)!
- Flashback Database特性常見問題的問與答Database
- 閃回資料庫(flashback database)知識分享資料庫Database
- 基礎問答
- FI顧問基礎知識
- 融合外部知識的常識問答
- XHTML基礎問答(轉)HTML
- 基礎知識
- 本地部署AI問答知識庫AI
- oracle基礎知識和常見問題Oracle
- AI 基礎知識AI
- Webpack 基礎知識Web
- Dart基礎知識Dart
- RabbitMQ基礎知識MQ
- webpack基礎知識Web
- javascript基礎知識JavaScript
- ThinkPHP基礎知識PHP
- Laravel基礎知識Laravel
- Redis基礎知識Redis
- Docker基礎知識Docker
- 程式基礎知識
- Envoy基礎知識
- DockerFile基礎知識Docker
- Nginx基礎知識Nginx
- CSS基礎知識CSS
- Java基礎知識Java
- PRML 基礎知識
- BGP基礎知識
- PHP基礎知識PHP
- React基礎知識React
- httpclient基礎知識HTTPclient
- HBase基礎知識
- Jquery基礎知識jQuery
- js基礎知識JS
- PGA基礎知識