四、switchover主備切換
DG的主要用途是HA高可用性,既然已經搭建好了主備環境,那現實環境中可能存在以下幾種情況。
由於某種原因我們需要切換主備身份,即主備切換(Switchover)
主庫故障,需要啟用備庫為主庫,即故障轉移(Failover)
客戶端實現自動的故障轉移-客戶端故障轉移(Client Failover)
下面就這幾種情況以及使用閃回數據庫重建庫,活動數據衛士(Active Data Guard),進行討論。
1.查看庫所在的保護模式和身份
sql>select protection_mode,protection_level from v$database; --默認是最大性能模式(maximum performance)
sql>select database_role from v$database; --主庫是primary備庫是physical standby
SQL > alter database set standby database to maximize protection; --最大保護
SQL > alter database set standby database to maximize availability; --最高可用性
SQL > alter database set standby database to maximize performance; --最高性能
這里簡要說明下這幾種保護模式的區別:
最大保護:這種模式能夠確保絕無數據丟失。要實現這一步當然是有代價的,它要求所有的事務在提交前其 redo 不僅
被寫入到本地的 online redo log,還要同時提交到 standby 數據庫的 standbyredo log,並確認 redo 數據至少在一
個 standby 數據庫可用(如果有多個的話),然后才會在 primary 數據庫上提交。如果出現了什么故障導致 standby
數據庫不可用的話,primary 數據庫會被 shutdown。
最高性能:這種模式提供在不影響 primary 數據庫性能前提下最高級別的數據保護策略。事務可以隨時提交,當前
primary 數據庫的 redo 數據也需要至少寫入一個 standby 數據庫,不過這種寫入可以是不同步的。
如果網絡條件理想的話, 這種模式能夠提供類似最高可用性的數據保護而僅對 primary 數據庫有輕微的性能影響。
最高可用性:這種模式提供在不影響 primary 數據庫可用前提下最高級別的數據保護策略。 其實現方式與最大保護模式類
似,也是要求所有事務在提交前必須保障 redo 數據至少在一個 standby 數據庫可用,不過與之不同的是,如果
出現故障導入無法同時寫入 standby 數據庫 redo log,primary 數據庫並不會 shutdown,而是自動轉為最高性能
模式,等 standby 數據庫恢復正常之后,它又會再自動轉換成最高可用性模式。
2.故障轉移配置
現在你已經配好了一個物理備庫,你可能想試試主備切換(switchover),甚至故障轉移(failover),但你先得確定客戶端會跟着切換和轉移。
我們需要配置數據庫和客戶端來支持這些功能。要確定你的客戶端能連接到正確的數據庫,你要在數據庫里配置一個支持故障轉移的服務,
並配置客戶端的 TNS,讓它知道如何在一個 Data Guard 集群里找到主庫。
(1)主庫創建自動轉移服務:
此服務在數據庫出現故障時會發送通知給客戶端,允許查詢語句在故障轉移發生后繼續運行。
我使用命名 SID_RW 顯示這時一個可讀寫的數據庫(主庫)。
begin
DBMS_SERVICE.CREATE_SERVICE (
service_name => 'orcl_RW',
network_name => 'orcl_RW',
aq_ha_notifications => TRUE,
failover_method => 'BASIC',
failover_type => 'SELECT',
failover_retries => 30,
failover_delay => 5);
end; /
(2)創建存儲過程確保只在主庫運行
我們創建一個存儲過程來實現此目的,如果當前數據庫是主庫它就啟動此服務,如果是備庫就停止。
create or replace procedure cmc_taf_service_proc
is
v_role VARCHAR(30);
begin
select DATABASE_ROLE into v_role from V$DATABASE;
if v_role = 'PRIMARY' then
DBMS_SERVICE.START_SERVICE('orcl_RW');
else
DBMS_SERVICE.STOP_SERVICE('orcl_RW');
end if;
end;
/
(3)創建觸發器(2個)來確保服務可以運行
創建兩個觸發器,讓數據庫在啟動和角色轉換時運行此存儲過程。注意有的文檔說是建立一個,那可能會導致你
在重啟你的數據庫時,它不會重啟故障轉移服務
create or replace TRIGGER cmc_taf_service_trg_startup
after startup on database
begin
cmc_taf_service_proc;
end;
/
create or replace TRIGGER cmc_taf_manage_trg_rolechange
after db_role_change on database
begin
cmc_taf_service_proc;
end;
/
(4)啟動服務
我們執行一次存儲過程,確定服務正在運行,並歸檔當前日志,讓以上更改同步到備庫。
SQL> exec cmc_taf_service_proc;
SQL> alter system archive log current;
查看服務信息
SQL> show parameter service_names
(5)客戶端配置TNS
服務名存在還不夠,你必須配置客戶端的 TNS 名去連接它。客戶端的 TNS 名應該類似如下:
orcl_RW =
(DESCRIPTION =
(ADDRESS_LIST=
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.101)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.102)(PORT = 1521))
)
(CONNECT_DATA = (SERVICE_NAME = orcl_RW)
(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=30)(DELAY=5))
)
)
當你的客戶端使用新 TNS 名后,它們能在主備切換和故障轉移操作后找到主庫。如果客戶端在運行一個查詢,
並且沒有 DML 是在一個交易中,那在發生切換操作后,只要主備轉換和故障轉移在超過最大重試次數前完成,
這個查詢會繼續工作,只是會有延遲。你應該多做幾次切換實驗,以確定 RETRIES 和 DELAY 參數如何設置合適。
如果有一個正在進行中的交易,當客戶端連接到新的主庫后,
查詢將報錯(`ORA-25403: transaction must roll back),並回滾。
3.主備切換switchover
(1)主庫確認沒有日志缺口
SQL> select STATUS, GAP_STATUS from V$ARCHIVE_DEST_STATUS where DEST_ID = 2;
應該返回 VALID 和 NO GAP。
(2)查詢v$tempfile視圖確認備庫的臨時文件和主庫一樣。
(3)確認所有重做日志都已在備庫應用,查詢備庫
SQL> select NAME, VALUE, DATUM_TIME from V$DATAGUARD_STATS;
不應該返回 transport lag 或 apply lag, finish time 應該為0.
關於V$DATAGUARD_STATS是這樣描述的:
該動態性能視圖顯示出在主庫上產生了多少重做日志數據,但是還沒有被備庫所應用。
所以,通過查詢該視圖可以基本確定如果萬一主庫出現崩潰的話,備庫上將丟失多少重做日志數據。
我們可以在一套Dataguard環境下的任一備庫的實例上從該視圖里獲取相關信息,
然而,在主庫的實例上查詢該視圖返回的信息都將是空。也就是說,只可以從備庫的實例上查詢V$DATAGUARD_STATS,
從主庫實例上是看不到任何有用信息的。
NAME:
apply lag,該值表示在通過在備庫上應用主庫傳遞過來的重做日志與主庫同步所延遲的時間。
transport lag,該值表示在單位時間內主庫上產生的重做日志還沒有傳輸到備庫上,或者主庫上產生的重做日志還沒有被備庫所應用。
apply finish time,該值表示在備庫上完成應用重做日志所需要的時間。
estimated startup time,該值表示啟動和打開物理備庫所需要的時間,該字段不是適用於邏輯備庫。
standby has been open,該值表示物理備庫自從上次啟動以來,是否以OPEN READ ONLY方式打開過?
該參數值如果是Y,現在需要做FAILOVER,那么就需要先將該物理備庫shutdown然后以OPEN READ WRITE方式打開。
11g的dataguard可以一邊OPEN READ ONLY,一邊執行redo apply,也就是11g 的ACTIVE Dataguard。
VALUE:給出各個參數的值。如第1個查詢中的,apply finish time值為+00 00:00:00.1,說明該物理備庫需要0.1秒的時間來完成應用剩余的重做日志數據。
UNIT:各個參數的時間單元。
TIME_COMPUTED:物理備庫上估算各個參數的本地時間。
DATUM_TIME:在物理備庫上獲取元數據來估算 APPLY LAG 和 TRANSPORT LAG 這兩個參數值的本地時間。如果從多次查詢中看到該時間值對應的APPLY LAG 和 TRANSPORT LAG 這兩個參數值保持不變的話,那么就說明該物理備庫已經停止從主庫接收到重做數據!該字段是11g中新出現的。
(4)確認主庫可以進行角色切換,查詢主庫
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果返回 TO STANDBY 或 SESSIONS ACTIVE,那么主庫就可以進行切換
(5)切換
<1>切換主庫為備庫命令為:
如果執行為TO STANDB執行
SQL> alter database commit to switchover to physical standby ;
SQL> shutdown immediate;
SQL> startup mount;
如果為SESSIONS ACTIVE執行
SQL> alter database commit to switchover to physical standby with session shutdown;
SQL> shutdown immediate;
SQL> startup mount;
<2>查詢備庫是否可以切換為主庫,查詢備庫:
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果返回 TO PRIMARY 或 SESSIONS ACTIVE,就可以切換。如果返回 SWITCHOVER LATENT 或 SWITCHOVER PENDING,就要去檢查告警日志,
看有什么問題,一般是需要應用一些日志。如果是需要應用日志的話,在備庫執行如下命令:
SQL> recover standby database using backup controlfile;
完成應用后,會變成 TO PRIMARY 或 SESSIONS ACTIVE狀態。
或者alter database recover managed standby database disconnect from session;
alter database recover managed standby database cancel;
切換備庫為主庫了:
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果是TO_PRIMARY 執行下面的
sql> alter database commit to switchover to primary;
SQL> alter database open;
如果是SESSIONS ACTIVE,執行下面的:
SQL> alter database commit to switchover to primary with session shutdown;
SQL> alter database open;
備庫(現在的備庫即101)上啟用日志應用:
SQL> alter database recover managed standby database using current logfile disconnect from session;
此時在現在的備庫101上執行:
sql>select SWITCHOVER_STATUS,DATABASE_ROLE from V$DATABASE; --not allowed PHYSICAL STANDBY
ora-16014錯誤,刪除standby logfile然后alter database clear logfile清理數據庫
從現在102主庫上alter system switch logfile手工觸發去傳輸standby logfile
注意的是:如果現在把101在切換回主庫,102成從庫。按照正常操作,先切換現在的主庫102成從庫,當操作完成的時候,101的 SWITCHOVER_STATUS就成
to_primary也就是說可以切換成主庫了。
現在的主庫102上執行:
sql> select SWITCHOVER_STATUS,DATABASE_ROLE from V$DATABASE; --RESOLVABLE GAP PRIMARY
檢查alert日志發現ora-00312錯誤,刪除錯誤的log日志,后狀態為TO STANDBY,PRIMARY
sql>startup mount;
sql>alter database clear logfile '*****.LOG';
sql>alter database open
(6)問題
如果主備庫的sequence#不同,而且主庫切換switch logfile也不能傳送到備庫,可用下面的辦法
手工同步歸檔日志文件到備庫,然后在備庫執行
sql>alter database register logfile '/opt/oracle/oradata/orcl/archive1/'
會報錯,不需要管,會提示可以注冊的已經注冊進去了
sql>select sequence#,first_change#,next_change#,applied,activation# from v$archived_log;
檢查主備庫sequence#,然后主庫切換logfile可以看到已經可以同步了