flashback log的寫入機制研究
Flashback log裡存放的是data block修改前的image,當我們修改一個data block時,data block before image會首先從buffer cache被複制到flashback generation buffer,然後再由RVWR(Recovery writer)程式將before image從flashback generation buffer讀取出來寫入到flashback log。Flashback database時會使用flashback log裡的data block before image覆蓋對應資料檔案中的data block,這個過程稱為Flashback restore。
三種情況下會生成Flashback log:
1、開啟資料庫級的flashback功能:
alter database flashback on;
select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
2、資料庫級的flashback功能處於關閉狀態,但建立了guaranteed restore point:
alter database flashback off;
create restore point grp1 guarantee flashback database;
select flashback_on from v$database;
FLASHBACK_ON
------------------
RESTORE POINT ONLY
3、資料庫級的flashback功能處於開啟狀態,且又建立了guaranteed restore point
alter database flashback on;
create restore point grp1 guarantee flashback database;
select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
第1種情況:資料庫級別開啟flashback功能,但沒有建立guaranteed restore point,flashback database能夠回溯到的時間點取決於db_flashback_retention_target,但這並不是一個硬性指標,當遇到Fast Recovery Area用滿的時候較早生成的Flashback log會被清理掉以留出足夠的空間給新生成的flashback log,所以無法保證一定能將資料庫flashback到db_flashback_retention_target指定的時間點。data block被修改之前其before image被寫入flashback log,對於活躍度較高的data block並不是每次更改都會觸發before image寫入flashback log,這樣做的目的是有效降低Flashback log write對資料庫IO效能的影響
第2種情況:建立了guaranteed restore point,但沒有在資料庫級別開啟flashback功能,也稱為Guaranteed restore point without flashback logging,這種情況確保資料庫一定能flashback到guaranteed restore point建立時的狀態,如果出現Fast Recovery Area用滿且又沒有obsolete file可以刪除的時候甚至會引起資料庫Hang。guaranteed restore point的功能有點類似儲存上的snapshot概念,提供了完整保留某一個時間點資料的功能,建立了guaranteed restore point之後,某個data block被更改,且一定是首次更改的時候,data block before image才會被寫入Flashback log,即Copy-on-first-write,即使該data block之後再次被修改,其before image也不會再次被寫入flashback log,對同一個data block來說其before-image永遠只會寫入一次flashback log
第3種情況,也稱為Guaranteed restore point with flashback logging,集1、2之大成,確保資料庫能flashback到從guaranteed restore point時間點開始的任何時間點
因為第3種情況包含了第1種,我們僅針對上面的第2、3種情況研究一下flashback log的生成機制。
先引入一個隱含引數_flashback_barrier_interval,我們前面提到過在資料庫級別的flashback功能開啟時,同一個block被更改多次的情況下,不會每次都將before image寫入flashback log,data block被更改的時候需要計算距離上一次更改的時間,當這個時間間隔大於等於_flashback_barrier_interval時才會將before image寫入flashback log,_flashback_barrier_interval的預設值是1800秒,為了方便測試我們調整為60秒,修改此引數需要重啟例項
alter system set "_flashback_barrier_interval"=60 scope=spfile;
startup force
show parameter _flashback_barrier_interval
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
_flashback_barrier_interval integer 60
================Part 1. Guaranteed restore point without flashback logging================
--清理掉所有存在的配置
&& connect SYS
alter database flashback off;
drop restore point grp0425_1;
--建立測試表
&& connect scott
drop table t0425_1;
create table t0425_1 (c1 varchar2(10),c2 number) tablespace ts0422_1;
insert into t0425_1 values('AAAAA',0);
commit;
select * from t0425_1;
C1 C2
---------- ----------
AAAAA 0
--記錄資料塊的地址
select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from t0425_1;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
------------------------------------ ------------------------------------
45459 9
--建立guarantee restore point並開啟database flashback
&& connect sys
create restore point grp0425_1 guarantee flashback database;
select flashback_on from v$database;
FLASHBACK_ON
------------------
RESTORE POINT ONLY
--執行前觀察flashback log的生成量
col restore_point_time format a5
col time format a50
col name format a30
set numwidth 16
set linesize 180
select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ---------------- ---------------- ---------------- ------------------------
20150425 21:00:08 20150425 21:00:22 425984 32768 46080 0
--執行前觀察flashback log write的生成量
col name format a50
set linesize 150
select n.name,s.value from v$sysstat s,v$statname n where n.statistic#=s.statistic# and n.name=s.name and n.name like 'flashback log write%';
NAME VALUE
-------------------------------------------------- ----------------
flashback log writes 212
flashback log write bytes 14737408
--下列的過程持續執行300秒,update語句執行15次,每次執行距離上一次間隔20秒
declare
v_cnt number:=1;
begin
while ( v_cnt < 16 ) loop
update t0425_1 set c2=v_cnt;
commit;
dbms_lock.sleep(20);
v_cnt:=v_cnt+1;
end loop;
end;
/
SCOTT@tstdb1-SQL> select * from t0425_1;
C1 C2
---------- ----------
AAAAA 15
--執行後觀察flashback log的生成量
col restore_point_time format a5
col time format a50
col name format a30
set numwidth 16
set linesize 180
select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ---------------- ---------------- ---------------- ------------------------
20150425 21:07:03 20150425 21:07:17 8192 0 7168 0
20150425 21:03:39 20150425 21:07:03 155648 1564672 146432 0
20150425 21:00:08 20150425 21:03:39 0 0 0 0
--執行後觀察flashback log write的生成量
col name format a50
set linesize 150
select n.name,s.value from v$sysstat s,v$statname n where n.statistic#=s.statistic# and n.name=s.name and n.name like 'flashback log write%';
NAME VALUE
------------------------------ ----------------
flashback log writes 225
flashback log write bytes 16171008
--獲取flashback log的最大和最小序號
select min(log#),max(log#) from v$flashback_database_logfile;
MIN(LOG#) MAX(LOG#)
---------- ----------
1 2
--從所有的flashback log裡dump出記錄block 9/40587的內容
select * from v$diag_info; --tstdb1_ora_37159746.trc
alter system dump flashback logfile 1 dba 9 45459;
alter system dump flashback logfile 2 dba 9 45459;
--將9/40587轉換成rdba,到.trc檔案中搜尋
select to_char(dbms_utility.make_data_block_address(9,45459),'xxxxxxxx') from dual;
TO_CHAR(D
---------
240b193
--rdba: 0x0240b193只儲存了一個版本
cat tstdb1_ora_37159746.trc |grep "file#: 9 rdba: 0x0240b193"
file#: 9 rdba: 0x0240b193
--從flashback log裡dump出block 9/45459,以驗證是否為原始值
alter system dump flashback logfile 1 dba 9 45459;
--dump內容如下
Block header dump: 0x0240b193
Object id on Block? Y
seg/obj: 0x8ce8 csc: 0xb92.63701f44 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x240b190 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.00d.0000f0fa 0x00c2bc9c.28a4.1f --U- 1 fsc 0x0000.63701f45
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
bdba: 0x0240b193
data_block_dump,data header at 0x112ec0a64
===============
tsiz: 0x1f98
hsiz: 0x14
pbl: 0x112ec0a64
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f8d
avsp=0x1f79
tosp=0x1f79
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f8d
block_row_dump:
tab 0, row 0, @0x1f8d
tl: 11 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 5] 41 41 41 41 41
col 1: [ 1] 80
end_of_block_dump
End-Of-Thread reached
---------- Flashback Read Statistics ----------
Total Elapsed time 0.94s
Number of sequential reads: 131 => 1020Kb per read
Sequential read speed: 133744Kb in 0.94s => 138.15 Mb/sec
Total waited on sequential reads to complete 0.92s
No random reads.
Number of async reads: 1
--儲存的是t0425_1的初始值c1='AAAAA',c2=0
select utl_raw.cast_to_number(80) from dual;
UTL_RAW.CAST_TO_NUMBER('80')
----------------------------
0
select utl_raw.cast_to_varchar2(replace('41 41 41 41 41',' ')) from dual;
UTL_RAW.CAST_TO_VARCHAR2(REPLACE('4141414141',''))
----------------------------------------------------------------------------------------------------
AAAAA
Guaranteed restore point without flashback logging的情況下,可以看出被修改的data block before image僅在block被首次修改時才會寫入flashback log,後續的修改不會再寫入,期間的flashback log生成量為1433600 bytes,flashback log writes為13次
====================Part 2. Guaranteed restore point with flashback logging==================
--清理掉所有存在的配置
&& connect SYS
alter database flashback off;
drop restore point grp0425_1;
--建立測試表
&& connect scott
drop table t0425_1;
create table t0425_1 (c1 varchar2(10),c2 number) tablespace ts0422_1;
insert into t0425_1 values('AAAAA',0);
commit;
select * from t0425_1;
C1 C2
---------- ----------
AAAAA 0
--記錄資料塊的地址
select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from t0425_1;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
------------------------------------ ------------------------------------
40587 9
--建立guarantee restore point並開啟database flashback
&& connect sys
create restore point grp0425_1 guarantee flashback database;
alter database flashback on;
select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
--執行前觀察flashback log的生成量
col restore_point_time format a5
col time format a50
col name format a30
set numwidth 16
set linesize 180
select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ---------------- ---------------- ---------------- ------------------------
20150425 17:30:27 20150425 17:30:41 147456 0 9216 0
--執行前觀察flashback log write的生成量
col name format a50
set linesize 150
select n.name,s.value from v$sysstat s,v$statname n where n.statistic#=s.statistic# and n.name=s.name and n.name like 'flashback log write%';
NAME VALUE
-------------------------------------------------- ----------------
flashback log writes 5
flashback log write bytes 245760
--下列的過程持續執行300秒,update語句執行15次,每次執行距離上一次間隔20秒
declare
v_cnt number:=1;
begin
while ( v_cnt < 16 ) loop
update t0425_1 set c2=v_cnt;
commit;
dbms_lock.sleep(20);
v_cnt:=v_cnt+1;
end loop;
end;
/
SCOTT@tstdb1-SQL> select * from t0425_1;
C1 C2
---------- ----------
AAAAA 15
--執行後觀察flashback log的生成量
col restore_point_time format a5
col time format a50
col name format a30
set numwidth 16
set linesize 180
select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ---------------- ---------------- ---------------- ------------------------
20150425 17:39:47 20150425 17:40:34 139264 32768 14336 0
20150425 17:37:44 20150425 17:39:47 442368 819200 37888 0
20150425 17:34:43 20150425 17:37:44 720896 188416 80384 0
20150425 17:32:40 20150425 17:34:43 1097728 942080 174592 0
20150425 17:30:27 20150425 17:32:40 614400 0 44032 0
--執行後觀察flashback log write的生成量
col name format a50
set linesize 150
select n.name,s.value from v$sysstat s,v$statname n where n.statistic#=s.statistic# and n.name=s.name and n.name like 'flashback log write%';
NAME VALUE
-------------------------------------------------- ----------------
flashback log writes 57
flashback log write bytes 3031040
--獲取flashback log的編號範圍
select min(log#),max(log#) from v$flashback_database_logfile;
MIN(LOG#) MAX(LOG#)
---------- ----------
1 2
--從所有的flashback log裡dump出記錄block 9/40587的內容
select * from v$diag_info; --tstdb1_ora_40371176.trc
alter system dump flashback logfile 1 dba 9 40587;
alter system dump flashback logfile 2 dba 9 40587;
--將9/40587轉換成rdba,到.trc檔案中搜尋
select to_char(dbms_utility.make_data_block_address(9,40587),'xxxxxxxx') from dual;
TO_CHAR(D
---------
2409e8b
--0x02409e8b一共存在6個版本
cat tstdb1_ora_40371176.trc |grep "file#: 9 rdba: 0x02409e8b"
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
cat tstdb1_ora_40371176.trc |grep "file#: 9 rdba: 0x02409e8b" | wc -l
6
以上結果可以看出300秒的時間內block 9/40587雖然被update了15次(每次update距離上一次的時間間隔是20秒),但只有6次被記錄到了flashback log,因為_flashback_barrier_interval=60,所以基本是每三次update裡有一次會寫入flashback。300秒的時間內生成的flashback log約為2867200 bytes,產生的flashback log writes為52次,比Guaranteed restore point without flashback logging的情況都要大得多。當我們將_flashback_barrier_interval設定為100秒(過程略)時,300秒內觀察到4次寫入flashback的操作,期間生成的flashback log約為3710976 bytes,flashback log writes為50次。
_flashback_barrier_interval設定為60秒時flashback log寫入次數是6次,產生的flashback log為2867200 bytes
_flashback_barrier_interval設定為100秒時flashback log寫入次數下降為3次,產生的flashback log為3710976 bytes,為何次數下降了一半,但flashback log的生產量卻和原來差不多?
因為大部分的flashback log都是由undo block產生的,我們對錶t0425_1所進行了15次update,每次update都會涉及到對undo block的修改,每次使用的undo block都有可能不相同,undo block的before image也要寫入flashback log,undo表空間是資料庫裡最活躍的表空間之一,前臺應用及其所觸發的recursive操作都有可能修改undo block,background process自身會發起對系統表的更改操作,也牽涉到undo,所以在flashback log裡所儲存的大部分before image都來自undo block,
使用下面的命令可以知道序號為1的flashback log裡儲存了哪些data block以及這些block所對應的file#,例如alter system dump logfile 1 logical能夠輸出以下內容:
**** Record at fba: (lno 2 thr 1 seq 2 bno 16384 bof 1464) ****
RECORD HEADER:
Type: 1 (Block Image) Size: 28
RECORD DATA (Block Image):
file#: 3 rdba: 0x00c3be36
Next scn: 0x0000.00000000 [0.0]
Flag: 0x0
Block Size: 8192
**** Record at fba: (lno 2 thr 1 seq 2 bno 16383 bof 1412) ****
RECORD HEADER:
Type: 1 (Block Image) Size: 28
RECORD DATA (Block Image):
file#: 3 rdba: 0x00c3be35
Next scn: 0x0000.00000000 [0.0]
Flag: 0x0
Block Size: 8192
**** Record at fba: (lno 2 thr 1 seq 2 bno 16382 bof 1360) ****
RECORD HEADER:
Type: 1 (Block Image) Size: 28
RECORD DATA (Block Image):
file#: 3 rdba: 0x00c3be34
Next scn: 0x0000.00000000 [0.0]
Flag: 0x0
Block Size: 8192
在我的測試資料庫裡,將log#=1、2的兩個flashback log匯出到.trc檔案
alter system dump logfile 1 logical;
alter system dump logfile 2 logical;
透過以下shell命令,過濾出部分有用的資訊:
---flashback log包含了來自哪些datafile的block
cat tstdb1_ora_39977214.trc | grep file# | awk '{print $1 " "$2}' |sort -u
file#: 1
file#: 2
file#: 3
file#: 9
---很明顯,flashback log裡記錄的大部分都是system、sysaux、undo裡的data block,真正使用者表空間只佔了4個block
cat tstdb1_ora_39977214.trc | grep "file#: 1" | awk '{print $1 " "$2}' | wc -l
129
cat tstdb1_ora_39977214.trc | grep "file#: 2" | awk '{print $1 " "$2}' | wc -l
414
cat tstdb1_ora_39977214.trc | grep "file#: 3" | awk '{print $1 " "$2}' | wc -l
267
cat tstdb1_ora_39977214.trc | grep "file#: 9" | awk '{print $1 " "$2}' | wc -l
4
三種情況下會生成Flashback log:
1、開啟資料庫級的flashback功能:
alter database flashback on;
select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
2、資料庫級的flashback功能處於關閉狀態,但建立了guaranteed restore point:
alter database flashback off;
create restore point grp1 guarantee flashback database;
select flashback_on from v$database;
FLASHBACK_ON
------------------
RESTORE POINT ONLY
3、資料庫級的flashback功能處於開啟狀態,且又建立了guaranteed restore point
alter database flashback on;
create restore point grp1 guarantee flashback database;
select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
第1種情況:資料庫級別開啟flashback功能,但沒有建立guaranteed restore point,flashback database能夠回溯到的時間點取決於db_flashback_retention_target,但這並不是一個硬性指標,當遇到Fast Recovery Area用滿的時候較早生成的Flashback log會被清理掉以留出足夠的空間給新生成的flashback log,所以無法保證一定能將資料庫flashback到db_flashback_retention_target指定的時間點。data block被修改之前其before image被寫入flashback log,對於活躍度較高的data block並不是每次更改都會觸發before image寫入flashback log,這樣做的目的是有效降低Flashback log write對資料庫IO效能的影響
第2種情況:建立了guaranteed restore point,但沒有在資料庫級別開啟flashback功能,也稱為Guaranteed restore point without flashback logging,這種情況確保資料庫一定能flashback到guaranteed restore point建立時的狀態,如果出現Fast Recovery Area用滿且又沒有obsolete file可以刪除的時候甚至會引起資料庫Hang。guaranteed restore point的功能有點類似儲存上的snapshot概念,提供了完整保留某一個時間點資料的功能,建立了guaranteed restore point之後,某個data block被更改,且一定是首次更改的時候,data block before image才會被寫入Flashback log,即Copy-on-first-write,即使該data block之後再次被修改,其before image也不會再次被寫入flashback log,對同一個data block來說其before-image永遠只會寫入一次flashback log
第3種情況,也稱為Guaranteed restore point with flashback logging,集1、2之大成,確保資料庫能flashback到從guaranteed restore point時間點開始的任何時間點
因為第3種情況包含了第1種,我們僅針對上面的第2、3種情況研究一下flashback log的生成機制。
先引入一個隱含引數_flashback_barrier_interval,我們前面提到過在資料庫級別的flashback功能開啟時,同一個block被更改多次的情況下,不會每次都將before image寫入flashback log,data block被更改的時候需要計算距離上一次更改的時間,當這個時間間隔大於等於_flashback_barrier_interval時才會將before image寫入flashback log,_flashback_barrier_interval的預設值是1800秒,為了方便測試我們調整為60秒,修改此引數需要重啟例項
alter system set "_flashback_barrier_interval"=60 scope=spfile;
startup force
show parameter _flashback_barrier_interval
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
_flashback_barrier_interval integer 60
================Part 1. Guaranteed restore point without flashback logging================
--清理掉所有存在的配置
&& connect SYS
alter database flashback off;
drop restore point grp0425_1;
--建立測試表
&& connect scott
drop table t0425_1;
create table t0425_1 (c1 varchar2(10),c2 number) tablespace ts0422_1;
insert into t0425_1 values('AAAAA',0);
commit;
select * from t0425_1;
C1 C2
---------- ----------
AAAAA 0
--記錄資料塊的地址
select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from t0425_1;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
------------------------------------ ------------------------------------
45459 9
--建立guarantee restore point並開啟database flashback
&& connect sys
create restore point grp0425_1 guarantee flashback database;
select flashback_on from v$database;
FLASHBACK_ON
------------------
RESTORE POINT ONLY
--執行前觀察flashback log的生成量
col restore_point_time format a5
col time format a50
col name format a30
set numwidth 16
set linesize 180
select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ---------------- ---------------- ---------------- ------------------------
20150425 21:00:08 20150425 21:00:22 425984 32768 46080 0
--執行前觀察flashback log write的生成量
col name format a50
set linesize 150
select n.name,s.value from v$sysstat s,v$statname n where n.statistic#=s.statistic# and n.name=s.name and n.name like 'flashback log write%';
NAME VALUE
-------------------------------------------------- ----------------
flashback log writes 212
flashback log write bytes 14737408
--下列的過程持續執行300秒,update語句執行15次,每次執行距離上一次間隔20秒
declare
v_cnt number:=1;
begin
while ( v_cnt < 16 ) loop
update t0425_1 set c2=v_cnt;
commit;
dbms_lock.sleep(20);
v_cnt:=v_cnt+1;
end loop;
end;
/
SCOTT@tstdb1-SQL> select * from t0425_1;
C1 C2
---------- ----------
AAAAA 15
--執行後觀察flashback log的生成量
col restore_point_time format a5
col time format a50
col name format a30
set numwidth 16
set linesize 180
select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ---------------- ---------------- ---------------- ------------------------
20150425 21:07:03 20150425 21:07:17 8192 0 7168 0
20150425 21:03:39 20150425 21:07:03 155648 1564672 146432 0
20150425 21:00:08 20150425 21:03:39 0 0 0 0
--執行後觀察flashback log write的生成量
col name format a50
set linesize 150
select n.name,s.value from v$sysstat s,v$statname n where n.statistic#=s.statistic# and n.name=s.name and n.name like 'flashback log write%';
NAME VALUE
------------------------------ ----------------
flashback log writes 225
flashback log write bytes 16171008
--獲取flashback log的最大和最小序號
select min(log#),max(log#) from v$flashback_database_logfile;
MIN(LOG#) MAX(LOG#)
---------- ----------
1 2
--從所有的flashback log裡dump出記錄block 9/40587的內容
select * from v$diag_info; --tstdb1_ora_37159746.trc
alter system dump flashback logfile 1 dba 9 45459;
alter system dump flashback logfile 2 dba 9 45459;
--將9/40587轉換成rdba,到.trc檔案中搜尋
select to_char(dbms_utility.make_data_block_address(9,45459),'xxxxxxxx') from dual;
TO_CHAR(D
---------
240b193
--rdba: 0x0240b193只儲存了一個版本
cat tstdb1_ora_37159746.trc |grep "file#: 9 rdba: 0x0240b193"
file#: 9 rdba: 0x0240b193
--從flashback log裡dump出block 9/45459,以驗證是否為原始值
alter system dump flashback logfile 1 dba 9 45459;
--dump內容如下
Block header dump: 0x0240b193
Object id on Block? Y
seg/obj: 0x8ce8 csc: 0xb92.63701f44 itc: 2 flg: E typ: 1 - DATA
brn: 0 bdba: 0x240b190 ver: 0x01 opc: 0
inc: 0 exflg: 0
Itl Xid Uba Flag Lck Scn/Fsc
0x01 0x000a.00d.0000f0fa 0x00c2bc9c.28a4.1f --U- 1 fsc 0x0000.63701f45
0x02 0x0000.000.00000000 0x00000000.0000.00 ---- 0 fsc 0x0000.00000000
bdba: 0x0240b193
data_block_dump,data header at 0x112ec0a64
===============
tsiz: 0x1f98
hsiz: 0x14
pbl: 0x112ec0a64
76543210
flag=--------
ntab=1
nrow=1
frre=-1
fsbo=0x14
fseo=0x1f8d
avsp=0x1f79
tosp=0x1f79
0xe:pti[0] nrow=1 offs=0
0x12:pri[0] offs=0x1f8d
block_row_dump:
tab 0, row 0, @0x1f8d
tl: 11 fb: --H-FL-- lb: 0x1 cc: 2
col 0: [ 5] 41 41 41 41 41
col 1: [ 1] 80
end_of_block_dump
End-Of-Thread reached
---------- Flashback Read Statistics ----------
Total Elapsed time 0.94s
Number of sequential reads: 131 => 1020Kb per read
Sequential read speed: 133744Kb in 0.94s => 138.15 Mb/sec
Total waited on sequential reads to complete 0.92s
No random reads.
Number of async reads: 1
--儲存的是t0425_1的初始值c1='AAAAA',c2=0
select utl_raw.cast_to_number(80) from dual;
UTL_RAW.CAST_TO_NUMBER('80')
----------------------------
0
select utl_raw.cast_to_varchar2(replace('41 41 41 41 41',' ')) from dual;
UTL_RAW.CAST_TO_VARCHAR2(REPLACE('4141414141',''))
----------------------------------------------------------------------------------------------------
AAAAA
Guaranteed restore point without flashback logging的情況下,可以看出被修改的data block before image僅在block被首次修改時才會寫入flashback log,後續的修改不會再寫入,期間的flashback log生成量為1433600 bytes,flashback log writes為13次
====================Part 2. Guaranteed restore point with flashback logging==================
--清理掉所有存在的配置
&& connect SYS
alter database flashback off;
drop restore point grp0425_1;
--建立測試表
&& connect scott
drop table t0425_1;
create table t0425_1 (c1 varchar2(10),c2 number) tablespace ts0422_1;
insert into t0425_1 values('AAAAA',0);
commit;
select * from t0425_1;
C1 C2
---------- ----------
AAAAA 0
--記錄資料塊的地址
select dbms_rowid.rowid_block_number(rowid),dbms_rowid.rowid_relative_fno(rowid) from t0425_1;
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID) DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID)
------------------------------------ ------------------------------------
40587 9
--建立guarantee restore point並開啟database flashback
&& connect sys
create restore point grp0425_1 guarantee flashback database;
alter database flashback on;
select flashback_on from v$database;
FLASHBACK_ON
------------------
YES
--執行前觀察flashback log的生成量
col restore_point_time format a5
col time format a50
col name format a30
set numwidth 16
set linesize 180
select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ---------------- ---------------- ---------------- ------------------------
20150425 17:30:27 20150425 17:30:41 147456 0 9216 0
--執行前觀察flashback log write的生成量
col name format a50
set linesize 150
select n.name,s.value from v$sysstat s,v$statname n where n.statistic#=s.statistic# and n.name=s.name and n.name like 'flashback log write%';
NAME VALUE
-------------------------------------------------- ----------------
flashback log writes 5
flashback log write bytes 245760
--下列的過程持續執行300秒,update語句執行15次,每次執行距離上一次間隔20秒
declare
v_cnt number:=1;
begin
while ( v_cnt < 16 ) loop
update t0425_1 set c2=v_cnt;
commit;
dbms_lock.sleep(20);
v_cnt:=v_cnt+1;
end loop;
end;
/
SCOTT@tstdb1-SQL> select * from t0425_1;
C1 C2
---------- ----------
AAAAA 15
--執行後觀察flashback log的生成量
col restore_point_time format a5
col time format a50
col name format a30
set numwidth 16
set linesize 180
select * from v$flashback_database_stat;
BEGIN_TIME END_TIME FLASHBACK_DATA DB_DATA REDO_DATA ESTIMATED_FLASHBACK_SIZE
----------------- ----------------- ---------------- ---------------- ---------------- ------------------------
20150425 17:39:47 20150425 17:40:34 139264 32768 14336 0
20150425 17:37:44 20150425 17:39:47 442368 819200 37888 0
20150425 17:34:43 20150425 17:37:44 720896 188416 80384 0
20150425 17:32:40 20150425 17:34:43 1097728 942080 174592 0
20150425 17:30:27 20150425 17:32:40 614400 0 44032 0
--執行後觀察flashback log write的生成量
col name format a50
set linesize 150
select n.name,s.value from v$sysstat s,v$statname n where n.statistic#=s.statistic# and n.name=s.name and n.name like 'flashback log write%';
NAME VALUE
-------------------------------------------------- ----------------
flashback log writes 57
flashback log write bytes 3031040
--獲取flashback log的編號範圍
select min(log#),max(log#) from v$flashback_database_logfile;
MIN(LOG#) MAX(LOG#)
---------- ----------
1 2
--從所有的flashback log裡dump出記錄block 9/40587的內容
select * from v$diag_info; --tstdb1_ora_40371176.trc
alter system dump flashback logfile 1 dba 9 40587;
alter system dump flashback logfile 2 dba 9 40587;
--將9/40587轉換成rdba,到.trc檔案中搜尋
select to_char(dbms_utility.make_data_block_address(9,40587),'xxxxxxxx') from dual;
TO_CHAR(D
---------
2409e8b
--0x02409e8b一共存在6個版本
cat tstdb1_ora_40371176.trc |grep "file#: 9 rdba: 0x02409e8b"
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
file#: 9 rdba: 0x02409e8b
cat tstdb1_ora_40371176.trc |grep "file#: 9 rdba: 0x02409e8b" | wc -l
6
以上結果可以看出300秒的時間內block 9/40587雖然被update了15次(每次update距離上一次的時間間隔是20秒),但只有6次被記錄到了flashback log,因為_flashback_barrier_interval=60,所以基本是每三次update裡有一次會寫入flashback。300秒的時間內生成的flashback log約為2867200 bytes,產生的flashback log writes為52次,比Guaranteed restore point without flashback logging的情況都要大得多。當我們將_flashback_barrier_interval設定為100秒(過程略)時,300秒內觀察到4次寫入flashback的操作,期間生成的flashback log約為3710976 bytes,flashback log writes為50次。
_flashback_barrier_interval設定為60秒時flashback log寫入次數是6次,產生的flashback log為2867200 bytes
_flashback_barrier_interval設定為100秒時flashback log寫入次數下降為3次,產生的flashback log為3710976 bytes,為何次數下降了一半,但flashback log的生產量卻和原來差不多?
因為大部分的flashback log都是由undo block產生的,我們對錶t0425_1所進行了15次update,每次update都會涉及到對undo block的修改,每次使用的undo block都有可能不相同,undo block的before image也要寫入flashback log,undo表空間是資料庫裡最活躍的表空間之一,前臺應用及其所觸發的recursive操作都有可能修改undo block,background process自身會發起對系統表的更改操作,也牽涉到undo,所以在flashback log裡所儲存的大部分before image都來自undo block,
使用下面的命令可以知道序號為1的flashback log裡儲存了哪些data block以及這些block所對應的file#,例如alter system dump logfile 1 logical能夠輸出以下內容:
**** Record at fba: (lno 2 thr 1 seq 2 bno 16384 bof 1464) ****
RECORD HEADER:
Type: 1 (Block Image) Size: 28
RECORD DATA (Block Image):
file#: 3 rdba: 0x00c3be36
Next scn: 0x0000.00000000 [0.0]
Flag: 0x0
Block Size: 8192
**** Record at fba: (lno 2 thr 1 seq 2 bno 16383 bof 1412) ****
RECORD HEADER:
Type: 1 (Block Image) Size: 28
RECORD DATA (Block Image):
file#: 3 rdba: 0x00c3be35
Next scn: 0x0000.00000000 [0.0]
Flag: 0x0
Block Size: 8192
**** Record at fba: (lno 2 thr 1 seq 2 bno 16382 bof 1360) ****
RECORD HEADER:
Type: 1 (Block Image) Size: 28
RECORD DATA (Block Image):
file#: 3 rdba: 0x00c3be34
Next scn: 0x0000.00000000 [0.0]
Flag: 0x0
Block Size: 8192
在我的測試資料庫裡,將log#=1、2的兩個flashback log匯出到.trc檔案
alter system dump logfile 1 logical;
alter system dump logfile 2 logical;
透過以下shell命令,過濾出部分有用的資訊:
---flashback log包含了來自哪些datafile的block
cat tstdb1_ora_39977214.trc | grep file# | awk '{print $1 " "$2}' |sort -u
file#: 1
file#: 2
file#: 3
file#: 9
---很明顯,flashback log裡記錄的大部分都是system、sysaux、undo裡的data block,真正使用者表空間只佔了4個block
cat tstdb1_ora_39977214.trc | grep "file#: 1" | awk '{print $1 " "$2}' | wc -l
129
cat tstdb1_ora_39977214.trc | grep "file#: 2" | awk '{print $1 " "$2}' | wc -l
414
cat tstdb1_ora_39977214.trc | grep "file#: 3" | awk '{print $1 " "$2}' | wc -l
267
cat tstdb1_ora_39977214.trc | grep "file#: 9" | awk '{print $1 " "$2}' | wc -l
4
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/53956/viewspace-1602019/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 談談MySQL bin log的寫入機制、以及線上的引數是如何配置的MySql
- console.log非同步機制?非同步
- ORACLE 閃回檢視v$flashback_database_log/statOracleDatabase
- 關於log file switch and checkpoint機制
- iOS自定義log並寫入檔案iOS
- Python中使用語句匯入模組或包的機制研究Python
- 類的載入機制
- 深入Node.js的模組載入機制,手寫require函式Node.jsUI函式
- 【FLASHBACK】Oracle flashback data archive 介紹OracleHive
- 類載入機制
- session與登入機制Session
- JVM:類載入機制JVM
- JVM類載入機制JVM
- java類載入機制Java
- Android 的 so 檔案載入機制Android
- 讀入寫出,轉二進位制
- 虛擬機器類載入機制_類載入的過程虛擬機
- AWS的Corretto團隊對log4j RCE漏洞的熱修補機制
- 【Flashback】Flashback Drop閃回刪除功能實驗
- 虛擬機器類載入機制虛擬機
- 虛擬機器類載入機制:類載入時機虛擬機
- 類載入機制總結
- JVM垃圾回收機制入門JVM
- ABP - 模組載入機制
- 類載入機制與反射反射
- JVM-類載入機制JVM
- Tomcat類載入機制探析Tomcat
- 由淺入深理解Dubbo的SPI機制
- JVM載入Class檔案的原理機制JVM
- 大白話談JVM的類載入機制JVM
- 如何將 winston log 庫記錄的日誌寫入 mongo DB 資料庫Go資料庫
- Flashback Query(轉)
- Flutter 瀑布流如何仿寫原生的複用機制?Flutter
- 使用Chrome開發者工具研究JavaScript的垃圾回收機制ChromeJavaScript
- Oracle多粒度封鎖機制研究二(zt)Oracle
- Oracle回收站表閃回機制研究Oracle
- 【Flashback】Flashback Database閃回資料庫功能實驗Database資料庫
- HDFS 02 - HDFS 的機制:副本機制、機架感知機制、負載均衡機制負載
- java虛擬機器類載入機制Java虛擬機