1.環境介紹
hostname ip db_name db_unique_name net service name
db11 172.16.8.11 orcl orcl11 orcl11
db12 172.16.8.12 orcl orcl12 orcl12
2.DG部署
2.1.建立主庫orcl
DBCA建立主庫,修改online redo 大小爲500M
2.2.主庫開啓歸檔
主庫開啓歸檔並設置強制日誌 force logging
--乾淨的關閉數據庫
SQL> shutdown immediate
--以mount模式啓動
SQL> startup mount
--切換到歸檔模式
SQL> alter database archivelog;
--開啓強制日誌
SQL> alter database force logging;
--打開數據庫
SQL> alter database open;
--查看歸檔
SQL> archive log list;
--查看是否爲強制日誌
SQL> select force_logging from v$database;
2.3.主庫添加Standby Redo Log
--查看Redo和Standby Redo
SQL> select * from v$logfile;
--僅僅顯示Online Redo,不顯示Standby Redo
SQL> select * from v$log;
--新增一組大小爲500M的Standby Redo,這裏的group號不得與Online redo重複
SQL> alter database add standby logfile group 21 '/u01/app/oracle/oradata/orcl/standby21.log' size 500M;
SQL> alter database add standby logfile group 22 '/u01/app/oracle/oradata/orcl/standby22.log' size 500M;
SQL> alter database add standby logfile group 23 '/u01/app/oracle/oradata/orcl/standby23.log' size 500M;
SQL> alter database add standby logfile group 24 '/u01/app/oracle/oradata/orcl/standby24.log' size 500M;
2.4.從主庫創建pfile文件
創建pfile文件, 默認路徑爲$ORACLE_HOME/dbs,此處爲/u01/app/oracle/product/11.2.0/dbhome_1/dbs/,在sqlplus裏執行以下命令
SQL> create pfile from spfile;
將主庫的pfile複製到備庫/u01/app/oracle/product/11.2.0/dbhome_1/dbs/下
cd /u01/app/oracle/product/11.2.0/dbhome_1/dbs/
scp initorcl.ora db12:/u01/app/oracle/product/11.2.0/dbhome_1/dbs/
2.5.設置主庫初始化參數
編輯/u01/app/oracle/product/11.2.0/dbhome_1/dbs/initorcl.ora文件,追加
cat >> /u01/app/oracle/product/11.2.0/dbhome_1/dbs/initorcl.ora << "EOF"
*.db_unique_name='orcl11'
*.fal_server='orcl12'
*.log_archive_config='dg_config=(orcl11,orcl12)'
*.log_archive_dest_1='location=use_db_recovery_file_dest valid_for=(all_logfiles, all_roles) db_unique_name=orcl11'
*.log_archive_dest_2='service=orcl12 lgwr async valid_for=(online_logfile,primary_role) db_unique_name=orcl12'
*.log_archive_dest_state_1=ENABLE
*.log_archive_dest_state_2=ENABLE
*.standby_file_management='AUTO'
*.db_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orcl'
*.log_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orcl'
EOF
創建新的主庫spfile文件,並重新啓動主庫
SQL> shutdown immediate
SQL> create spfile from pfile;
SQL> startup
2.6.設置備庫初始化參數
編輯/u01/app/oracle/product/11.2.0/dbhome_1/dbs/initorcl.ora文件,修改備庫初始化參數
cat >> /u01/app/oracle/product/11.2.0/dbhome_1/dbs/initorcl.ora << "EOF"
*.db_unique_name='orcl12'
*.fal_server='orcl11'
*.log_archive_config='dg_config=(orcl11,orcl12)'
*.log_archive_dest_1='location=use_db_recovery_file_dest valid_for=(all_logfiles, all_roles) db_unique_name=orcl12'
*.log_archive_dest_2='service=orcl11 lgwr async valid_for=(online_logfile,primary_role) db_unique_name=orcl11'
*.log_archive_dest_state_1=ENABLE
*.log_archive_dest_state_2=ENABLE
*.standby_file_management='AUTO'
*.db_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orcl'
*.log_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orcl'
EOF
2.7.複製主庫的密碼文件到備庫
將密碼文件orapworcl複製到備庫的/u01/app/oracle/product/11.2.0/dbhome_1/dbs/下
cd /u01/app/oracle/product/11.2.0/dbhome_1/dbs/
scp orapworcl db12:/u01/app/oracle/product/11.2.0/dbhome_1/dbs/
2.8.創建備庫相應的目錄結構
使用oracle用戶創建以下目錄,避免權限問題
mkdir -p /u01/app/oracle/oradata/orcl/
mkdir -p /u01/app/oracle/admin/orcl/adump/
mkdir -p /u01/app/oracle/fast_recovery_area/orcl/
2.9.配置主庫和備庫的監聽
使用圖形界面配置,採用靜態監聽
netmgr
2.10.配置主庫和備庫的網絡服務名
使用圖形界面配置,在主備庫上均需配置orcl11、orcl12兩個服務名
netmgr
2.11.創建備庫並啓動
創建備庫的spfile文件,啓動備庫到nomount模式
SQL> create spfile from pfile;
SQL> startup nomount
2.12.RMAN複製主庫到備庫
首先RMAN連接到目標數據庫和輔助數據庫
rman target sys/password@orcl11 auxiliary sys/password@orcl12
使用RMAN的duplicate命令進行復制,兩邊目錄結構相同,需要添加nofilenamecheck參數
RMAN> duplicate target database for standby from active database nofilenamecheck;
複製成功後,備庫自動被加載爲mount模式,進入sqlplus查看
SQL> select status from v$instance;
2.13.在備庫開啓實時日誌應用
SQL> alter database recover managed standby database using current logfile disconnect from session;
2.14.主備庫角色狀態查詢
SQL> select switchover_status,database_role from v$database;
--主庫顯示:TO STANDBY/PRIMARY,如果顯示SESSION ACTIVE表示還有活動的會話,需要關閉活動的會話再檢查
--備庫顯示:NOT ALLOWED/PHYSICAL STANDBY
3.測試DG
3.1.執行日誌切換測試
在主庫端切換歸檔,在備庫檢查是否也發生了切換
主庫上執行日誌切換
SQL> archive log list;
SQL> alter system switch logfile;
SQL> archive log list;
備庫上查看,日誌的sequence號也跟着變了
SQL> archive log list;
3.2.查看備庫啓動的DG進程
SQL> select process,client_process,sequence#,status from v$managed_standby;
PROCESS CLIENT_P SEQUENCE# STATUS
--------- -------- ---------- ------------
ARCH ARCH 23 CLOSING
ARCH ARCH 0 CONNECTED //歸檔進程
ARCH ARCH 21 CLOSING
ARCH ARCH 0 CONNECTED
RFS ARCH 0 IDLE
RFS UNKNOWN 0 IDLE
RFS LGWR 24 IDLE //歸檔傳輸進程
RFS UNKNOWN 0 IDLE
MRP0 N/A 24 APPLYING_LOG //日誌應用進程
9 rows selected.
3.3.查看數據庫的保護模式
SQL> select database_role,protection_mode,protection_level,open_mode from v$database;
DATABASE_ROLE PROTECTION_MODE PROTECTION_LEVEL OPEN_MODE
---------------- -------------------- -------------------- --------------------
PRIMARY MAXIMUM PERFORMANCE MAXIMUM PERFORMANCE READ WRITE
3.4.查看DG的日誌信息
SQL> select * from v$dataguard_status;
3.5.Open Read Only Standby數據庫
以只讀方式打開備庫,並開啓實時日誌應用
SQL> shutdown immediate
SQL> startup
SQL> select database_role,protection_mode,protection_level,open_mode from v$database;
SQL> select process,client_process,sequence#,status from v$managed_standby;
SQL> alter database recover managed standby database using current logfile disconnect from session;
3.6.解鎖scott用戶並添加數據,驗證是否同步
在主庫解鎖scott用戶並創建測試表,插入10000行數據。
操作如下
SQL> set line 200
SQL> select username,default_tablespace,account_status from dba_users where username='SCOTT';
SQL> alter user scott account unlock;
SQL> conn scott/tiger;
SQL> show user
SQL> create table test001 (id number(10),name varchar2(20));
SQL> begin
for i in 1..10000 loop
insert into test001 values (1,'ww');
end loop;
end;
/
SQL> commit;
standby端查詢scott用戶是否解鎖,以及test001表是否創建並且插入了10000行數據
SQL> conn scott/tiger;
SQL> select * from tab;
SQL> select count(*) from test001;
4.DG三種模式
4.1.最大性能模式max performance-默認
這種保護模式(默認)提供了可能的最高級別的數據保護,而不影響主數據庫的性能。這是通過允許事務在恢復該事務所需重做數據在寫到本地聯機重做日誌後立即提交而實現的。主數據庫的重做數據流也寫到至少一個備數據庫,但是那個重做流相對於創建重做數據的事務是異步寫的。
當所用的網絡連接有足夠的帶寬,這種模式提供了近似於最大可用性模式的數據保護級別,並且對主數據庫性能的影響最小。
4.2.最大可用性模式max availability
這種保護模式提供了可能的最高級別的數據保護,而不用與主數據庫的可用性相折衷。與最大保護模式相同,在恢復事務所需的重做寫到本地聯機重做日誌和至少一個事務一致性備數據庫上的備重做日誌之前,事務將不會提交。與最大保護模式不同的是,如果故障導致主數據庫無法寫重做流到異地備重做日誌時,主數據庫不會關閉。替代地,主數據庫以最大性能模式運行直到故障消除,並且解決所有重做日誌文件中的中斷。當所有中斷解決之後,主數據庫自動繼續以最大可用性模式運行。
這種模式確保如果主數據庫故障,但是隻有當第二次故障沒有阻止完整的重做數據集從主數據庫發送到至少一個備數據庫時,不發生數據丟失。
4.3.最大保護模式max protection
這種保護模式確保如果主數據庫故障不會發生數據丟失。要提供這種級別的保護,恢復每個事務所需的重做數據必須在事務提交之前同時寫到本地聯機重做日誌和至少一個備數據庫上的備重做日誌。要確保不發生數據丟失,如果故障導致主數據庫無法寫重做流到至少一個事務一致性備數據庫的備重做日誌時,主數據庫會關閉。
4.4.查詢當前模式
SQL> select protection_mode,protection_level from v$database;
5.DG切換測試
5.1.DG switchover 切換測試
db11-orcl:主庫------>備庫
db12-orcl:備庫------>主庫
主備庫角色狀態查詢
SQL> select switchover_status,database_role,open_mode from v$database;
--db11-orcl顯示:TO STANDBY/PRIMARY,如果顯示SESSION ACTIVE表示還有活動的會話,需要關閉會話再檢查
--db12-orcl顯示:NOT ALLOWED/PHYSICAL STANDBY
db11-orcl切換到備庫
SQL> alter database commit to switchover to physical standby;
SQL> alter database commit to switchover to physical standby with session shutdown;
--如果狀態顯示SESSION ACTIVE,在切換的時候可以指定with session shutdown 子句強制關閉活動的會話。
SQL> shutdown immediate
SQL> startup mount
db12-orcl切換到主庫
SQL> alter database commit to switchover to primary;
SQL> alter database open;
db11-orcl執行APPLY LOG命令
--啓用mount狀態下的APPLY LOG
SQL> alter database recover managed standby database disconnect from session;
--啓用open狀態(READ ONLY WITH APPLY)下的APPLY LOG
SQL> alter database recover managed standby database cancel;
SQL> alter database open;
SQL> alter database recover managed standby database disconnect from session;
SQL> select switchover_status,database_role,open_mode from v$database;
5.2.DG failover 切換測試
db11-orcl:主庫------>崩潰
db12-orcl:備庫------>主庫
主備庫角色狀態查詢
SQL> select switchover_status,database_role,open_mode from v$database;
db11-orcl通過shutdown abort方式人工模擬主庫崩潰,直接關閉
SQL> select open_mode from v$database;
SQL> shutdown abort
SQL> startup mount
SQL> alter system flush redo to 'orcl12';
db12-orcl執行如下操作切換爲主庫
SQL> select thread#, low_sequence#, high_sequence# from v$archive_gap;
--如果沒有發現明顯的gap現象,說明此次的failover不會有數據損失情況。在備庫,要進行關閉apply和結束應用動作。
SQL> alter database recover managed standby database cancel;
SQL> alter database recover managed standby database finish;
SQL> alter database commit to switchover to primary;
SQL> alter database open;
SQL> select open_mode, switchover_status from v$database;
5.3.DG failover後重建DG
db11-orcl:崩潰------>備庫
db12-orcl:主庫------>主庫(保持主庫狀態不變)
db12-orcl主庫角色狀態查詢
SQL> select switchover_status,database_role,open_mode from v$database;
db12-orcl主庫創建備庫控制文件
mkdir -p /u01/bak/
SQL> alter database create standby controlfile as '/u01/bak/control01.ctl';
將備庫控制文件拷貝至db11
scp ezdb12:/u01/bak/control01.ctl /u01/app/oracle/oradata/orcl/control01.ctl
cp /u01/app/oracle/oradata/orcl/control01.ctl /u01/app/oracle/fast_recovery_area/orcl/
mv /u01/app/oracle/fast_recovery_area/orcl/control01.ctl /u01/app/oracle/fast_recovery_area/orcl/control02.ctl
恢復對應數據文件至db11,並啓動db11-orcl到mount狀態,應用APPLY模式
SQL> startup mount;
SQL> alter database recover managed standby database disconnect from session;
啓動db11-orcl至OPEN狀態,並應用APPLY REDO模式
SQL> alter database recover managed standby database cancel;
SQL> alter database open;
SQL> alter database recover managed standby database disconnect from session;
6.開啓和關閉DataGuard的流程
6.1.關閉
關閉主庫
SQL> shutdown immediate
關閉主庫監聽
lsnrctl stop
查詢備庫是否正在執行重做應用或實時應用。如果MRP0或MRP進程存在,則備庫正在應用重做。
SQL> select process, status from v$managed_standby;
如果重做應用程序正在運行,停止備庫的Redo日誌的應用
SQL> alter database recover managed standby database cancel;
關閉備庫
SQL> shutdown immediate
關閉備庫監聽
lsnrctl stop
6.2.開啓
啓動備庫監聽
lsnrctl start
啓動備庫到mount狀態
SQL> startup mount;
開啓備庫的Redo日誌應用
SQL> alter database recover managed standby database using current logfile disconnect from session;
啓動主庫監聽
lsnrctl start
啓動主庫
SQL> startup;
檢查日誌情況的SQL語句
select al.thrd "Thread", almax "Last Seq Received", lhmax "Last Seq Applied"
from (select thread# thrd, max(sequence#) almax
from v$archived_log
where resetlogs_change#=(select resetlogs_change# from v$database)
group by thread#) al,
(select thread# thrd, max(sequence#) lhmax
from v$log_history
where first_time=(select max(first_time) from v$log_history)
group by thread#) lh
where al.thrd = lh.thrd;