資料來自官方網站:
https://docs.oracle.com/en/database/oracle/oracle-database/19/sbydb/managing-oracle-data-guard-physical-standby-databases.html#GUID-B1C66720-3EA6-45A3-986E-6E510381EC79
在19c之前,oracle Data Guard備用數據庫上不能執行DML操作,但是,從19c開始備庫就可以進行DML操作了;個人覺得象征意思確實很大,相當於未來的oracle是更智能,高效,高可用,甚至是更好的讀寫分離。
Active Data Guard備用數據庫上運行DML操作,可以在備用數據庫上運行只讀應用程序,偶爾執行DML(太頻繁影響主庫性能),備庫上的DML操作可以透明地重定向到主數據庫並在主數據庫上運行。也包括PL/SQL塊中的DML語句。Active Data Guard會話將等待,直到將相應的更改發送到Active Data Guard備用數據庫並將其應用於Active Data Guard備用數據庫為止。在DML操作期間將保持讀取一致性,並且運行DML的備用數據庫可以查看其未提交的更改。但是,所有其他備用數據庫實例只有在提交事務后才能查看這些更改。
整體的步驟如下:
1.備庫的客戶端發起DML操作。
2.DML操作被重定向到主庫。
3.DML在主庫被實施。
4.生成更改的redo傳到備庫。
5.完成DML重定向,客戶端顯示修改后的數據信息。
DML操作自動重定向到主要對象可以在系統級別或會話級別進行配置。會話級別設置將覆蓋系統級別設置。要為Active Data Guard環境中的所有備用會話配置DML操作的自動重定向,請執行以下操作:
- 將
ADG_REDIRECT_DML
初始化參數設置為TRUE
。
要為當前會話配置DML操作的自動重定向,請使用以下命令:
ALTER SESSION ENABLE ADG_REDIRECT_DML;
先決條件:
1.配置好dg_broker
2.sys用戶不支持備庫DML操作的自動重定向。
一.配置dg_broker
來自官方文檔:https://docs.oracle.com/cd/B28359_01/server.111/b28295/cli.htm#i1005666
我的dg最開始沒有配置,所以先要配置 dg_broker。
1.1入門先決條件(參數修改)
使用DGMGRL的先決條件是主庫和備庫必須已經安裝好,DG_BROKER_START
必須TRUE
為配置中的所有數據庫將初始化參數設置為。
alter system set dg_broker_start=true scope=both; --主備開啟dg_broker_start
1.2.主備庫配置db_broker
備庫上連接到主庫操作
主庫數據庫唯一名以及tns連接串名都是:orcl
備庫數據庫唯一名以及tns連接串名都是:orcldg
dg_broker 配置 orcl_brk_config
dgmgrl
connect sys/密碼@orcl
--把主庫添加到dg_broker,備庫上連接到主庫操作
備庫執行:
alter system set log_archive_dest_2=''; --備庫我關閉了log_archive_dest_2由於服務名字符串一樣。
CREATE CONFIGURATION 'orcl_brk_config' AS PRIMARY DATABASE IS 'orcl' CONNECT IDENTIFIER IS orcl;
show CONFIGURATION
--把備庫添加到dg_broker,仍然是連接到備庫上
ADD DATABASE orcldg AS CONNECT IDENTIFIER IS orcldg MAINTAINED AS PHYSICAL;
啟用
show configuration;
ENABLE CONFIGURATION;
show database orcl;
show database orcldg
二.Data Guard備用數據庫上執行DML重定向操作
操作如下:
select database_role from v$database;
show parameter ADG_REDIRECT_DML;
alter system set adg_redirect_dml=true scope=both;
重啟備庫
select database_role from v$database;
select open_mode from v$database;
show parameter ADG_REDIRECT_DML;
ALTER SESSION ENABLE ADG_REDIRECT_DML;
insert into dg_test select rownum from dual connect by rownum <=100;
在測試當主,我測試了sys用戶不支持備庫DML操作的自動重定向。
select database_role from v$database;
select open_mode from v$database;
show parameter ADG_REDIRECT_DML;
ALTER SESSION ENABLE ADG_REDIRECT_DML;
insert into test select rownum from dual connect by rownum <=100;
結論:
避免在Active Data Guard備用數據庫上也運行DML操作。因為操作實際上是在主數據庫上執行的,所以太多的DML可能會影響主數據庫的性能。
三.錯誤提示ORA-16397

[oracle@19cdg ~]$ oerr ora 16397
16397, 00000, "statement redirection from Oracle Active Data Guard standby database to primary database failed"
// *Cause: The statement redirection failed because of one of the following reasons:
// 1. The primary database connect string was not established.
// 2. The primary database could not be reached.
// 3. The undo-mode or incarnation were not the same.
// 4. The current user and logged-in user were not the same.
// 5. Redirecting CREATE TABLE AS SELECT (CTAS) of the global temporary
// table was not supported.
// 6. Redirecting PL/SQL execution having bind variable was not supported.
// *Action: Run the statement after fixing the condition that caused the failure.
四.查看DML的過程
我在備庫執行update 語句,但是不提交,查看整個會話過程。
可以做個10046 trace看看,我是直接進行會話查詢。
sqlplus racttfc/oracle@orcldg
show user;
select database_role from v$database;
select open_mode from v$database;
ALTER SESSION ENABLE ADG_REDIRECT_DML;
update dg_test set id=1 where id>50;
SELECT username, final_blocking_session, final_blocking_instance, event lockwait, status, machine, service_name , sql_id FROM gv$session WHERE username IS NOT NULL;
insert into dg_test select rownum from dual connect by rownum <=100000;
commit;
update dg_test set id=1 where id>50;
select sql_text from v$sql where sql_id in ('8xn0mav2kq662','0f35avqs2973b');
整個備庫執行DML語句都是被重定向到主庫,DML在主庫被實施,然后再返回備庫,但是要是備庫執行大量的DML語句,肯定會影響到主庫的性能,所以只適合適量的dml,可以把此場景用到備庫主要做大量查詢,偶爾進行修改的業務場景。