編輯手記:對于資料庫的閃回功能,可能大家都不陌生,那麼如何在多租戶環境下使用該功能,如果關閉了表空間的閃回功能,會給資料庫帶來哪些影響?我們一起來學習。
本文來自周四大講堂内容整理。
我們先說一下flashback這個單詞,我們大家常稱它為閃回,可能有的人稱它為回閃。flashback 是oracle 9i 版本開始提供的一項特性,利用oracle查詢多版本一緻的特點,實作從復原段中讀取一定的時間内在表中操作過的資料。 flashback database是oracle10g的新增功能,在啟動flashback database之後,它定期将已發生變化的塊寫入閃回日志的日志檔案中。這些日志不是由傳統的log writer (lgwr) 程序寫入,而是由一種稱作recovery writer (rvwr)的新程序寫入。這是oracle10g的新增程序。 閃回日志是存儲在閃回恢複區(flash recovery area),閃回恢複區簡稱fra。配置閃回恢複區,有兩個參數:db_recovery_file_dest和db_recovery_file_dest_size。
db_recovery_file_dest是用來指定fra的存儲路徑,可以指定一個檔案系統下的路徑,也可以指定asm磁盤組,但是不能将該路徑指向一個裸裝置。rac資料庫要指定共享存儲上。
db_recovery_file_dest_size這個參數是指定fra最大可用空間。建議配置設定大一些,如果剩餘空間不足15%的時候,它将會在alert中增加告警,提示空間不足。但此時不會影響資料庫正常運作。
可以通過視圖v$flashback_database_log、v$flashback_database_stat檢視閃回日志及資料庫狀态。當需要flashback database時,通過flashback log中儲存的資料,就可以快速将oracle資料庫恢複到指定時間點塊的狀态,然後通過應用重做日志,将資料庫恢複到一緻狀态。
閃回資料庫:
使用閃回資料庫,通過還原自先前某個時間點以來發生的所有更改,可快速将資料庫恢複到那個時間的狀态。因為不需要還原備份,是以此操作速度很快。可以使用此功能還原導緻邏輯資料損壞的更改。
使用閃回資料庫時,oracle db 可使用過去的塊映像回退對資料庫的更改。在正常資料庫操作期間,oracle db 會不定期地将這些塊映像記錄在閃回日志中。閃回日志将按順序寫入并且不進行歸檔。oracle db 會自動在快速恢複區中建立、删除閃回日志和調整它的大小。您僅需出于監視性能目的而關注閃回日志,并确定為快速恢複區配置設定了多少磁盤空間以存放閃回日志。
使用閃回資料庫倒回資料庫所需的時間與需回退到多久以前以及目标時間之後發生的資料庫活動量成比例。還原和恢複整個資料庫所需的時間會長得多。閃回日志中的前像僅用于将資料庫還原至過去的某一時間點,而前滾恢複則用于将資料庫恢複到與過去某個時間一緻的狀态。oracle db 可将資料檔案恢複至以前的時間點,但輔助檔案除外,如初始化參數檔案。
啟用閃回資料庫功能時,會啟動rvwr(閃回寫程序)背景程序。此背景程序按順序将閃回資料庫資料從閃回緩沖區寫入閃回資料庫日志,這些日志會被循環使用。随後,當發出flashback database 指令時,系統使用閃回日志還原塊的前像,然後使用重做資料前滾到所需的閃回時間。
啟用閃回資料庫的開銷取決于資料庫的讀/寫混合工作量。因為查詢不需要記錄任何閃回資料,是以工作量的寫操作量越大,啟用閃回資料庫的開銷就越高。可以從v$flashback_database_stat檢視在一個時間段内資料庫閃回日志記錄的資訊。
在一個end_time -begin_time時間段内:
flashback_data記錄寫閃回日志大小;(機關:位元組) db_data記錄資料庫讀寫大小;(機關:位元組) redo_data記錄redo日志的大小;(機關:位元組) estimated_flashback_size記錄預估滿足保留時間所需要的空間大小。(機關:位元組) con_id代表的是容器id。
字段含義如下:
oldest_flashback_scn 保留的最低系統改變号; oldest_flashback_time 最低系統改變号的時間; retention_target 閃回日志保留時間(機關:時間); flashback_size 目前閃回日志的大小(機關:位元組); estimated_flashback_size 預估滿足保留時間所需要的空間大小(機關:位元組);
閃回日志可以通過參數指定保留時間,db_flashback_retention_target。預設值為:1440 minutes。
實驗步驟:
1、首先,我們開啟資料庫閃回功能:
mkdir -p /u01/app/oracle/fast_recovery_area alter system setdb_recovery_file_dest_size=10g; alter system setdb_recovery_file_dest='/u01/app/oracle/fast_recovery_area' scope=both;
shutdown immediate; startup mount; alter database archivelog; alter database flashback on; alter database open;
檢視目前資料庫執行個體狀态:
set lines 200 col name for a30 select con_id,name,open_mode from v$pdbs;
開啟pdb執行個體:
alter session set container=perfeader; alter pluggable database perfeader open;
我們來建立測試表空間,測試使用者:
檢視表所在預設表空間:
col table_name for a20 select table_name,tablespace_name fromuser_tables;
檢視表的資料量:
select count(*) from perfeader.test; select count(*) from perfeader.test1;
查詢目前資料庫scn:
select current_scn from v$database;
删掉表test中20000行資料:
delete from perfeader.test where rownum<=20000; commit;
查詢目前test表中資料量:
再向表中插入20行資料,然後commit查詢表perfeader.test表的資料量。
insert into perfeader.test select * fromdba_objects where rownum <= 20;
等一下,測試将資料閃回到scn= 1469627,delete資料之後,insert之前。
操作
scn
表(test)資料量
表(test1)資料量
create table
72612
38
delete test 資料
52612
commit
1469627
insert test 資料
52632
查詢開啟閃回的表空間:
select * from v$tablespace;
接下來檢視資料庫是否開啟閃回:
select flashback_on from v$database;
關閉表空間test的閃回:
alter tablespacetest flashback off;
關閉資料庫,閃回資料庫到scn=1469627:
conn / as sysdba shutdown immediate startup mount flashback database to scn 1469627;
這個時候,我們能夠看到閃回報錯為無法閃回資料檔案13,沒有閃回日志。
開啟資料庫,開啟表空間test閃回,需要在pdb執行個體開啟:
alter tablespace test flashback on;
要切換到perfeader執行個體,才可以開啟表空間test01的閃回:
我們再建立一個表空間test01,測試關閉該表空間的閃回功能,是否會有不一樣的報錯?
開啟pdb執行個體,建立表空間test01:
create tablespace test01 datafile'/u01/app/oracle/oradata/prod/test01_01.dbf' size 100m autoextend on; alter tablespace test01 flashback off;
閃回到表空間test的delete資料的時間點scn=1469627
flashback database to scn 1469470;
可以發現,表空間test01是關閉閃回功能的,我們閃回到test01表空間建立之前的時間點也是無法閃回的。我們可以看出閃回日志中的表空間必須是連續,而且沒有表空間是關閉閃回的。
問題1:關閉表空間的閃回功能,會給出什麼告警資訊?
結論:如果資料庫中有表空間沒有開啟閃回,将告警顯示沒有該表空間的閃回日志可以閃回。無論是在開啟資料庫閃回之前,還是之後,都将會報沒有閃回日志。說明,如果在一個連續的資料庫閃回日志,該閃回日志過程中某一個表空間關閉了閃回,都将無法将資料庫閃回到之前的某一時間點。
開啟資料庫,還是相同的步驟重新建立使用者,表空間及表:
create tablespace test02 datafile '/u01/app/oracle/oradata/prod/test02_01.dbf'size 100m autoextend on; create user allen identified by allendefault tablespace test02 account unlock; grant dba to allen; conn allen/allen@perfeader create table allen.test as select * fromdba_objects; create table allen.test1 tablespace usersas select * from dba_users;
檢視表所在表空間:
檢視該表空間中表的資料:
select count(*) from allen.test; select count(*) from allen.test1;
先關閉表空間test02閃回功能,稍後閃回的時候我們将不閃回該表空間:
alter tablespacetest02 flashback off;
檢視perfeader 使用者,users表空間下表test1的資料:
從perfeader使用者表test1中删除一條資料:
delete from perfeader.test1 whereusername='system';
commit後檢視目前資料庫scn:
删除1行之後commit,查詢scn号,這個時候perfeader.test1表有37行,test沒有改變.
delete test1 資料
37
1470592
這時,我們又向allen使用者下的表test,test1都插入資料,使其狀态改變。
查詢allen使用者下表test,test1的資料量:
第一步插入表test1:
insert into allen.test1 select * from allen.test1;
commit查詢test,test1表的資料:
查詢目前scn:
第二步插入表test2:
insert into allen.test select * from allen.test;
第三步插入表test1,test2:
變化之後的資料,我們可以看一下下面的表格:
perfeader使用者:
39
allen使用者:
72631
insert test1 資料後
78
1470812
insert test 資料後
145262
1470885
insert test,test1 資料後
290524
156
1470968
insert test插入資料後這個時候allen使用者下的表的資料是test(145262),test1(78),而perfeader使用者下的資料是test(52632),test1(37)。
等一下,測試将資料閃回到scn=1470812。
我們再測試一下,test02表空間沒有開啟閃回功能,會報什麼錯誤。
關閉資料庫,啟動資料庫到mount,閃回資料庫,scn= 1470812:
flashback database to scn 1470812;
閃回資料庫表空間allen使用者insert test資料後commit時間點,還是會報無test02_1.dbf閃回日志:
flashback database to scn 1470885;
嘗試一下在pdb做閃回,告訴我們不允許在插入的資料庫做閃回:
檢視目前閃回日志中的資訊發現,閃回最老的時間點是開啟閃回資料庫功能的時間:
alter session set nls_date_format='yyyy-mm-ddhh24:mi:ss'; select * from v$flashback_database_log; select * from v$flashback_database_stat;
下面我們驗證,将關閉閃回功能的表空間offline,是否能夠閃回資料庫?
alter tablespace test02 offline;
查詢表空間online狀态:
select tablespace_name,status,online_statusfrom dba_data_files;
切換到cdb$root執行個體,關閉資料庫并閃回資料資料庫到scn=1470812。
當open資料庫時,會提示是resetlogs開啟,還是noresetlogs方式:
如果以resetlogs方式打開資料庫:
alter database open resetlogs;
切換到pdb執行個體perfeader,并open:
select open_mode from v$database;
下面是從alert日志來看,資料庫是使用歸檔日志、redo日志恢複到scn= 1470812+1:
打開redo日志前滾:
12c會依次打開undo表空間:cdb$root->pdb$seed-> perfeader
打開資料庫perfeader,報ora-01110錯誤:
當檢視表空間test02的資料檔案狀态時,還是offline,并且閃回功能還是關閉的:
set lines 200 pages 200 col name for a53 selectfile#,name,status,checkpoint_change#,last_change# from v$datafile;
當查詢test02表空間下的資料會報無法讀取資料檔案test02_01.dbf,報錯如下:
如果以noresetlogs方式open資料庫,會報如下錯誤:
sql> alterdatabase open noresetlogs; alter databaseopen noresetlogs * error at line 1: ora-01610:recovery using the backup controlfile option must be done
當recovery資料庫後,這時可以open資料庫了:
sql> recoverdatabase; media recovery complete. sql> alterdatabase open;
database altered.
接下來我們驗證問題2.
問題2:關閉“表空間”的閃回,是否還可以閃回資料庫?
以open noresetlogs或者open noresetlog方式打開後,如果想要恢複被offline的表空間需要進行以下recover 資料檔案步驟:
alter database create datafile 15 as'/u01/app/oracle/oradata/prod/test02_01.dbf'; recover datafile 15; alter database datafile 15 online;
最後檢視一下資料檔案,表空間的狀态:
select file#,name,status,checkpoint_change#,last_change#from v$datafile; select file#,status,recover,checkpoint_change#from v$datafile_header;
可以看到15号資料檔案test02_01.dbf的檢查點是比其他的資料檔案檢查點大。
查詢test02表空間下的資料已經閃回到scn=1482450時間點:
檢視閃回後的資料,allen.test表的資料是72631,test1的資料是78。正是scn=1470812時間點的資料。
結論:是可以做到表空間關閉了閃回功能,而其他的表空間沒有關閉閃回功能,将關閉閃回的表空間offline後,可以将資料庫閃回到指定的時間點,而資料庫閃回後需要将關閉閃回的表空間資料檔案recover,并online該表空間,資料就可以恢複到指定的時間點。
總結:
序号
問題
結果
1
關閉表空間的閃回功能,閃回資料庫會給出什麼告警資訊?
如果資料庫中有表空間沒有開啟閃回,将告警顯示沒有該表空間的閃回日志可以閃回。無論是在開啟資料庫閃回之前,還是之後,都将會報沒有閃回日志。說明,如果在一個連續的資料庫閃回日志,該閃回日志過程中某一個表空間關閉了閃回,都将無法将資料庫閃回到之前的某一時間點。
2
關閉“表空間”的閃回,是否還可以閃回資料庫?
是可以做到表空間關閉了閃回功能,而其他的表空間沒有關閉閃回功能,将關閉閃回的表空間offline後,可以将資料庫閃回到指定的時間點,而資料庫閃回後需要将關閉閃回的表空間資料檔案recover,并online該表空間,資料就可以恢複到指定的時間點。