Oracle 11gR2中的STANDBY_MAX_DATA_DELAY,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。
創(chuàng)新互聯(lián)專注于網(wǎng)站建設(shè)|網(wǎng)站維護(hù)|優(yōu)化|托管以及網(wǎng)絡(luò)推廣,積累了大量的網(wǎng)站設(shè)計(jì)與制作經(jīng)驗(yàn),為許多企業(yè)提供了網(wǎng)站定制設(shè)計(jì)服務(wù),案例作品覆蓋效果圖設(shè)計(jì)等行業(yè)。能根據(jù)企業(yè)所處的行業(yè)與銷售的產(chǎn)品,結(jié)合品牌形象的塑造,量身制作品質(zhì)網(wǎng)站。
Active Data Guard 是 Oracle 11g 的亮點(diǎn)特性之一,而在11G release 2中對(duì)Active Data Guard引入了更多誘人的新特性,這些特性將Active Data Guard打造成Oracle 讀寫分離或報(bào)表查詢的理想方案之一。
STANDBY_MAX_DATA_DELAY是11gr2中對(duì)Active Data Guard的最大增強(qiáng)(buffer)之一,這是一個(gè)可以在會(huì)話級(jí)別指定的參數(shù)(session parameter),該參數(shù)指定了在Primary Database已commit提交的變化與standby Database數(shù)據(jù)庫(kù)上涉及相關(guān)變化的查詢之間所允許的時(shí)間延遲,單位為second 秒。
使用該STANDBY_MAX_DATA_DELAY參數(shù)的語(yǔ)法如下:
ALTER SESSION SET STANDBY_MAX_DATA_DELAY ={ NONE | INTEGER }
注意事項(xiàng)
該參數(shù)無(wú)法為SYS用戶所用,在SYS用戶的SESSION下設(shè)置該參數(shù)將被忽略
若沒有指定STANDBY_MAX_DATA_DELAY,即使用其默認(rèn)值NONE,那么無(wú)論主備庫(kù)之間有多大的延遲,在Physical Standby上的查詢都會(huì)被執(zhí)行
若查詢延遲超過STANDBY_MAX_DATA_DELAY所指定的值那么,將報(bào)ORA-03172錯(cuò)誤:
03172, 00000, "STANDBY_MAX_DATA_DELAY of %s seconds exceeded" // *Cause: Standby recovery fell behind the STANDBY_MAX_DATA_DELAY // requirement. // *Action: Tune recovery and retry the query later, or switch to another // standby database within the data delay requirement.
在實(shí)際運(yùn)用中STANDBY_MAX_DATA_DELAY保證了在Standby數(shù)據(jù)庫(kù)上所作的報(bào)表查詢不會(huì)得到過于陳舊的結(jié)果(stale result),通過該參數(shù)我們可以指定一個(gè)報(bào)表應(yīng)用所容許的數(shù)據(jù)時(shí)間延遲。
當(dāng)然也可以指定不容許任何數(shù)據(jù)延遲,即設(shè)置STANDBY_MAX_DATA_DELAY為零,以便做到實(shí)時(shí)數(shù)據(jù)查詢。
配置Primary 與 Standby 數(shù)據(jù)庫(kù)之間的實(shí)時(shí)查詢或者說(shuō)零延遲查詢有以下注意事項(xiàng):
只有特定的應(yīng)用程序才會(huì)對(duì)數(shù)據(jù)延遲有零容忍的需求,注意你的應(yīng)用程序是否有如此苛刻的要求
在Standby數(shù)據(jù)庫(kù)上執(zhí)行的查詢語(yǔ)句必須返回和主庫(kù)上查詢的完全一致的結(jié)果
必須設(shè)置STANDBY_MAX_DATA_DELAY 為0
在查詢開始的那一刻,Standby數(shù)據(jù)庫(kù)必須同步到與Primary數(shù)據(jù)庫(kù)一致的Current Scn
若結(jié)果沒有在200ms內(nèi)返回,則查詢會(huì)因ORA-03172而終止
Primary數(shù)據(jù)庫(kù)必須采用最大可用(max availability)或最大保護(hù)(maximum protection)模式
redo 傳輸必須使用SYNC 選項(xiàng)
必須啟用 Real-Time Query 特性
實(shí)際使用
以下我們通過演示來(lái)了解該STANDBY_MAX_DATA_DELAY的效果:
SQL> select * from v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production PL/SQL Release 11.2.0.2.0 - Production CORE 11.2.0.2.0 Production TNS for Linux: Version 11.2.0.2.0 - Production NLSRTL Version 11.2.0.2.0 - Production SQL> select * from global_name; GLOBAL_NAME -------------------------------------------------------------------------------- www.askmaclean.com & www.askmaclean.com Primary Database SQL> conn maclean/maclean Connected. Primary Database SQL> select database_role,protection_mode from v$database; DATABASE_ROLE PROTECTION_MODE ---------------- -------------------- PRIMARY MAXIMUM AVAILABILITY Primary Database SQL> create table TSMDD tablespace users as select * From dba_objects; Table created. Standby Database SQL> conn maclean/maclean Connected. Standby Database SQL> select database_role,protection_mode from v$database; DATABASE_ROLE PROTECTION_MODE ---------------- -------------------- PHYSICAL STANDBY MAXIMUM AVAILABILITY 注意STANDBY_MAX_DATA_DELAY是一個(gè)會(huì)話參數(shù)session parameter,而非實(shí)例參數(shù)instance parameter Standby Database SQL> select name from v$system_parameter where name='standby_max_data_delay'; no rows selected Standby Database SQL> alter session set STANDBY_MAX_DATA_DELAY=0; Session altered. Standby Database SQL> select count(*) from TSMDD; COUNT(*) ---------- 13378
實(shí)際測(cè)試可以發(fā)現(xiàn)當(dāng)STANDBY_MAX_DATA_DELAY=0時(shí),并不是查詢語(yǔ)句執(zhí)行時(shí)間超過200ms就返回ORA-03172錯(cuò)誤,而是指從查詢開始的200ms內(nèi),若備庫(kù)沒有追上主庫(kù)的Current SCN時(shí)出現(xiàn)ORA-03172。
Standby Database SQL> alter session set STANDBY_MAX_DATA_DELAY=0; Session altered. Standby Database SQL> set timing on; Standby Database SQL> select count(1) from TSMDD a, TSMDD b; COUNT(1) ---------- 178970884 Elapsed: 00:00:05.34 Standby Database SQL> alter session set events '10046 trace name context forever,level 12'; Session altered. 在主庫(kù)上執(zhí)行大數(shù)據(jù)量的insert操作,但是不提交commit; Primary Database SQL> insert into /*+ append */ tsmdd select * from tsmdd; 此時(shí)在Standby 數(shù)據(jù)庫(kù) 上執(zhí)行查詢語(yǔ)句將觸發(fā)ORA-3172錯(cuò)誤 Standby Database SQL> select count(*) from tsmdd * ERROR at line 1: ORA-03172: STANDBY_MAX_DATA_DELAY of 0 seconds exceeded Standby Database SQL> / select count(*) from tsmdd * ERROR at line 1: ORA-03172: STANDBY_MAX_DATA_DELAY of 0 seconds exceeded
以上查詢語(yǔ)句執(zhí)行過程中的10046 trace如下:
PARSING IN CURSOR #47828795969456 len=26 dep=0 uid=34 oct=3 lid=34 tim=1316692536000853 hv=2314050071 ad='7115e798' sqlid='3smn48y4yv6hr' select count(*) from tsmdd END OF STMT PARSE #47828795969456:c=0,e=61,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1739041831,tim=1316692536000852 WAIT #47828795969456: nam='standby query scn advance' ela= 201440 p1=770798 p2=0 p3=20 obj#=13873 tim=1316692536202337 WAIT #47828795969456: nam='SQL*Net break/reset to client' ela= 25 driver id=1650815232 break?=1 p3=0 obj#=13873 tim=1316692536202528 WAIT #47828795969456: nam='SQL*Net break/reset to client' ela= 144 driver id=1650815232 break?=0 p3=0 obj#=13873 tim=1316692536202694 WAIT #47828795969456: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=13873 tim=1316692536202715 *** 2011-09-22 19:55:37.983 WAIT #47828795969456: nam='SQL*Net message from client' ela= 1781108 driver id=1650815232 #bytes=1 p3=0 obj#=13873 tim=1316692537983884 CLOSE #47828795969456:c=0,e=24,dep=0,type=0,tim=1316692537984068 =============================================================================================== PARSING IN CURSOR #47828795969456 len=26 dep=0 uid=34 oct=3 lid=34 tim=1316692537984172 hv=2314050071 ad='7115e798' sqlid='3smn48y4yv6hr' select count(*) from tsmdd END OF STMT PARSE #47828795969456:c=0,e=53,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1739041831,tim=1316692537984171 WAIT #47828795969456: nam='standby query scn advance' ela= 200546 p1=770914 p2=0 p3=20 obj#=13873 tim=1316692538184822 WAIT #47828795969456: nam='SQL*Net break/reset to client' ela= 10 driver id=1650815232 break?=1 p3=0 obj#=13873 tim=1316692538184998 WAIT #47828795969456: nam='SQL*Net break/reset to client' ela= 103 driver id=1650815232 break?=0 p3=0 obj#=13873 tim=1316692538185154 WAIT #47828795969456: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=13873 tim=1316692538185182
注意這里出現(xiàn)的standby query scn advance等待事件,顯然該等待事件是為了確認(rèn)Primary與Standby之間的Scn差距,但這又是一個(gè)Internal的undocumented 等待事件。我猜測(cè)是P1是Standby數(shù)據(jù)庫(kù)的Current Scn,而p3可能是Primary 與 Standby之間的Scn 差距。OBJ#是查詢對(duì)象的object_id:
SQL> col owner for a20 SQL> col object_name for a20 SQL> select owner,object_name from dba_objects where object_id=13873; OWNER OBJECT_NAME -------------------- -------------------- MACLEAN TSMDD
使用技巧
在實(shí)際的使用過程中我們沒有必要每次登錄會(huì)話查詢都去指定STANDBY_MAX_DATA_DELAY參數(shù),可以通過創(chuàng)建AFTER LOGON觸發(fā)器來(lái)簡(jiǎn)化工作。
在11 g Release 2中引入了USERENV Context的一種新屬性DATABASE_ROLE,使用該屬性可以便捷地定位用戶所登錄數(shù)據(jù)庫(kù)的角色是Primary 還是 Standby,11g的SQL 和 PL/SQL客戶端程序均可以通過 SYS_CONTEXT 函數(shù)獲取該數(shù)據(jù)庫(kù)角色信息。
通過創(chuàng)建以下登陸后觸發(fā)器可以做到當(dāng)應(yīng)用程序登錄到啟用實(shí)時(shí)查詢的Standby數(shù)據(jù)庫(kù)上后即自動(dòng)設(shè)置合適的STANDBY_MAX_DATA_DELAY參數(shù)。這樣即避免了修改應(yīng)用程序的代碼,有做到了配置合理的最大數(shù)據(jù)延遲。
CREATE OR REPLACE TRIGGER AUTO_SMDD AFTER LOGON ON USER.SCHEMA BEGIN IF (SYS_CONTEXT('USERENV', 'DATABASE_ROLE') IN ('PHYSICAL STANDBY')) THEN execute immediate 'alter session set standby_max_data_delay=5'; END IF; END;
注意以上trigger 只需要在Primary Database上以應(yīng)用相關(guān)用戶身份建立即可,會(huì)同步到Standby上:
Primary Database SQL> conn maclean/maclean Connected. Primary Database SQL> CREATE OR REPLACE TRIGGER AUTO_SMDD 2 AFTER LOGON ON MACLEAN.SCHEMA 3 BEGIN 4 IF (SYS_CONTEXT('USERENV', 'DATABASE_ROLE') IN ('PHYSICAL STANDBY')) THEN 5 execute immediate 'alter session set standby_max_data_delay=0'; 6 END IF; 7 END; 8 / Trigger created.
關(guān)于Oracle 11gR2中的STANDBY_MAX_DATA_DELAY問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。