580
汽車大全
如何在多租戶環境下使用數據庫的閃回功能
編輯手記:對於數據庫的閃回功能,可能大家都不陌生,那麼如何在多租戶環境下使用該功能,如果關閉了表空間的閃回功能,會給數據庫帶來哪些影響?我們一起來學習。
本文來自周四大講堂內容整理。
我們先說一下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 預估滿足保留時間所需要的空間大小(單位:字節);CON_ID代表的是容器ID。
閃回日誌可以通過參數指定保留時間,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;
我們來創建測試表空間,測試用戶:
查看表所在默認表空間:
set lines 200
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;
查詢當前數據庫scn:
select current_scn from v$database;
查詢當前test表中數據量:
select count(*) from perfeader.test;
再向表中插入20行數據,然後commit查詢表perfeader.test表的數據量。
insert into perfeader.test select * fromdba_objects where rownum <= 20;
commit;
等一下,測試將數據閃回到scn= 1469627,delete數據之後,insert之前。
操作 |
Scn |
表(TEST)數據量 |
表(TEST1)數據量 |
Create table |
72612 |
38 |
|
Delete test 數據 |
52612 |
38 |
|
commit |
1469627 |
||
Insert test 數據 |
52632 |
38 |
|
Commit |
查詢開啟閃回的表空間:
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 session set container=PERFEADER;
alter tablespace TEST flashback on;
conn / as sysdba
alter database open;
alter session set container=PERFEADER;
select * from v$tablespace;
要切換到perfeader實例,才可以開啟表空間test01的閃回:
我們再創建一個表空間test01,測試關閉該表空間的閃回功能,是否會有不一樣的報錯?
開啟pdb實例,創建表空間test01:
alter pluggable database PERFEADER open;
create tablespace TEST01 datafile'/u01/app/oracle/oradata/PROD/test01_01.dbf' size 100M autoextend on;
alter tablespace TEST01 flashback off;
select * from v$tablespace;
閃回到表空間test的delete數據的時間點scn=1469627
conn / as sysdba
shutdown immediate
startup mount
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 table_name,tablespace_name fromuser_tables;
查看該表空間中表的數據:
select count(*) from allen.test;
select count(*) from allen.test1;
先關閉表空間TEST02閃回功能,稍後閃回的時候我們將不閃回該表空間:
alter tablespaceTEST02 flashback off;
查看perfeader 用戶,users表空間下表TEST1的數據:
select count(*) from perfeader.TEST1;
從perfeader用戶表TEST1中刪除一條數據:
delete from perfeader.TEST1 whereUSERNAME='SYSTEM';
COMMIT後查看當前數據庫SCN:
COMMIT;
刪除1行之後commit,查詢SCN號,這個時候perfeader.test1表有37行,TEST沒有改變.
操作 |
Scn |
表(TEST)數據量 |
表(TEST1)數據量 |
Create table |
72612 |
38 |
|
Delete test 數據 |
52612 |
38 |
|
commit |
1469627 |
||
Insert test 數據 |
52632 |
38 |
|
Commit |
|||
Delete test1 數據 |
52632 |
37 |
|
Commit |
1470592 |
這時,我們又向allen用戶下的表TEST,TEST1都插入數據,使其狀態改變。
查詢allen用戶下表test,test1的數據量:
select count(*) from allen.test;
select count(*) from allen.test1;
第一步插入表test1:
insert into allen.TEST1 select * from allen.TEST1;
commit查詢test,test1表的數據:
commit;
select count(*) from allen.TEST;
select count(*) from allen.TEST1;
查詢當前scn:
select current_scn from v$database;
第二步插入表test2:
insert into allen.TEST select * from allen.TEST;
commit查詢test,test1表的數據:
commit;
select count(*) from allen.TEST;
select count(*) from allen.TEST1;
select current_scn from v$database;
第三步插入表test1,test2:
insert into allen.TEST select * from allen.TEST;
insert into allen.TEST1 select * from allen.TEST1;
commit查詢test,test1表的數據:
commit;
select count(*) from allen.TEST;
select count(*) from allen.TEST1;
select current_scn from v$database;
變化之後的數據,我們可以看一下下麵的表格:
perfeader用戶:
操作 |
Scn |
表(TEST)數據量 |
表(TEST1)數據量 |
Create table |
72612 |
39 |
|
Delete test 數據 |
52612 |
38 |
|
commit |
1469627 |
||
Insert test 數據 |
52632 |
38 |
|
Commit |
|||
Delete test1 數據 |
52632 |
37 |
|
Commit |
1470592 |
allen用戶:
操作 |
Scn |
表(TEST)數據量 |
表(TEST1)數據量 |
Create table |
72631 |
39 |
|
Insert test1 數據後 |
72631 |
78 |
|
commit |
1470812 |
||
Insert test 數據後 |
145262 |
78 |
|
Commit |
1470885 |
||
Insert test,test1 數據後 |
290524 |
156 |
|
Commit |
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 database open;
alter session set container=PERFEADER;
alter pluggable database PERFEADER open;
alter tablespace TEST02 offline;
查詢表空間online狀態:
select TABLESPACE_NAME,status,ONLINE_STATUSfrom dba_data_files;
切換到CDB$ROOT實例,關閉數據庫並閃回數據數據庫到scn=1470812。
conn / as sysdba
shutdown immediate
startup mount
flashback database to scn 1470812;
當open數據庫時,會提示是RESETLOGS開啟,還是NORESETLOGS方式:
alter database open;
如果以RESETLOGS方式打開數據庫:
alter database open RESETLOGS;
切換到PDB實例perfeader,並open:
alter session set container=PERFEADER;
select open_mode from v$database;
alter pluggable database PERFEADER open;
下麵是從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 * from v$tablespace;
select file#,status,recover,CHECKPOINT_CHANGE#from v$datafile_header;
可以看到15號數據文件test02_01.dbf的檢查點是比其他的數據文件檢查點大。
查詢test02表空間下的數據已經閃回到scn=1482450時間點:
select count(*) from allen.test;
select count(*) from allen.test1;
查看閃回後的數據,allen.TEST表的數據是72631,TEST1的數據是78。正是scn=1470812時間點的數據。
結論:是可以做到表空間關閉了閃回功能,而其他的表空間沒有關閉閃回功能,將關閉閃回的表空間offline後,可以將數據庫閃回到指定的時間點,而數據庫閃回後需要將關閉閃回的表空間數據文件recover,並online該表空間,數據就可以恢複到指定的時間點。
總結:
序號 |
問題 |
結果 |
1 |
關閉表空間的閃回功能,閃回數據庫會給出什麼告警信息? |
如果數據庫中有表空間沒有開啟閃回,將告警顯示沒有該表空間的閃回日誌可以閃回。無論是在開啟數據庫閃回之前,還是之後,都將會報沒有閃回日誌。說明,如果在一個連續的數據庫閃回日誌,該閃回日誌過程中某一個表空間關閉了閃回,都將無法將數據庫閃回到之前的某一時間點。 |
2 |
關閉“表空間”的閃回,是否還可以閃回數據庫? |
是可以做到表空間關閉了閃回功能,而其他的表空間沒有關閉閃回功能,將關閉閃回的表空間offline後,可以將數據庫閃回到指定的時間點,而數據庫閃回後需要將關閉閃回的表空間數據文件recover,並online該表空間,數據就可以恢複到指定的時間點。 |
文章轉自數據和雲公眾號,原文鏈接
最後更新:2017-07-18 12:03:33