ORACLE RAC環境下讀取序列亂序問題

2021-07-28 06:24:11 字數 2978 閱讀 1788

在資料庫部署了rac環境之後,偶爾會出現從oracle sequence所取出來的數是混亂的,比如第二次比第一次所取的數要小。這樣當程式的邏輯依賴於id的大小來排序時,就會產生系統混亂。

其實問題是出在資料庫是個rac環境,序列是被共享的,序列預設是有快取的。假設rac上的兩個節點上序列快取設為20,第乙個節點上快取1-20,第二個節點快取了21-40,當從不同節點來進行對sequence取值的時候,從第二個節點上取的值就會比從第乙個節點上取的要大。而且預設序列都是noorder的。因為很有可能出現這種情況。

具體方法有兩個:

1. 設定cache為空

2. 建立序列的時候設定為order,即採用cache + order

sequence建立方法:

create sequence [schema.]sequence  

[increment by integer]  

[start with integer]  

[maxvalue integer | nomaxvalue]  

[minvalue integer | nominvalue]  

[cycle | nocycle]  

[cache integer | nocache]  

[order | noorder]  

oracle下關於sequence的使用有三種情況:

1. cache + noorder

2. nocache

3. cache + order

oracle

為了管理

sequence

使用了以下三中鎖(1

)row cache lock

在呼叫sequence.nextval過程中,將資料字典資訊進行物理修改時獲取,賦予了nocache屬性的sequence上發生。(2

)sq鎖-- enq: sq

在記憶體上快取(cache)範圍內,呼叫sequence.nextval期間擁有此鎖,賦予了cache+noorder 屬性的sequence上發生。(3

)sv鎖-- dfs lock handle  

rac上節點之間順序得到保障的情況下,呼叫sequence.nextval期間獲得,賦予了cache+order屬性的sequence上發生。

賦予了cache屬性的sequence呼叫nextval期間,應該以ssx模式獲得sq鎖,許多會話同時為了獲取

sq鎖而發生爭用過程中,若發生爭用,則等待

enq:sq-contention.

enq:sq-contention事件的p2值是sequence的object id,因此,若利用p2值與dba_objects的結合,就可以知道對哪個、 sequence發生了等待物件。

建立sequence賦予的cache值較小時,有enq:sq-contention等待增加的趨勢,cache值較小,記憶體上事先cache的值很快被耗盡,這時需要將資料字典資訊物理修改,再次執行

cache

的工作,在此期間,因為一直要擁有sq鎖,相應的enq:sq-contention事件的等待時間也會延長,很不幸的是,在建立sequence時,將cache值的預設值設定為較小20,因此建立使用量最多的

sequence

時,cache

值應該取

1000

以上的較大值。

偶而一次性同時建立許多會話,有時會發生

enq:sq-contention

等待事件,其理由是v$session.audsid(auditing sessionid) 列值是利用sequence建立的,oracle在建立新的會話後,利用名為sys.audsess$的sequence的nextval建立audsid的值,sys.audsess$ sequence的cache大小的預設值設定為 20,許多會話同時連線,可以將sys.audsess$ sequence的cache大小擴大至1000,以此可以解決 enq:sq-contention等待問題。

rac上建立

sequence

時,在賦予了

cache

屬性的狀態下

:(1)若沒有賦予order屬性,則各節點將會把不同範圍的sequence值cache到記憶體上,比如擁有兩個節點的rac環境下,建立cache值為100的 sequence時,1節點會使用1-100,2節點會使用101-200。 使用時從各自節點取sequence。

(2)若兩個節點之間會通過遞增的使用sequence,必須賦予如下order屬性。

sql>create sequence ordered_sequence cache 100 order;

在order 的情況下,2個節點取的sequence是遞增的。 下文會有示例來說明這兩種情況。

如果已賦予

cache+order

屬性的sequence, oracle

使用sv

鎖進行行同步,即,對賦予了order屬性的sequence呼叫nextval時,應該以ssx模式擁有sv鎖,在獲取

sv鎖過程中,若發生了爭用,不是等待row cache或者是enq:sq-contention,而是等待名為

dfs lock handle

事件,正因如此v$event_name檢視上不存在類似與"enq:sv-contention"

dfs lock handle事件是在ops或者rac環境下,除了 高速緩衝區 同步之外,還有 行高速緩衝區 或者 庫高速緩衝區 同步獲取鎖的過程中的等待事件。     若保證全域性範圍內獲得鎖,在此過程中會發生

dfs look handle

等待,在獲取sv鎖的過程中發生的dfs lock handle等待事件的p1,p2值與enq:sq-contention等待事件相同(p1=mode+namespace,p2=object#).因此會從p1值能確認是否是sv鎖,通過p2可以確認哪些是sequence發生過等待.

sv鎖爭用問題發生時的解決辦法與

sq鎖的情況相同,就是

cache

值進行適當的調整,這也是唯一的方法。

本文**:

ORACLE rac環境配置

load balance yes 負載均衡 failover on 失敗自動切換 這個引數預設就是on,所以一般都不加的。設定本地服務命名相應的引數 load balance on 和failover on failover mode引數 來啟用客戶端負載均衡和taf功能。客戶端負載均衡並不衡量ra...

Oracle Rac集群環境下刪除歸檔日誌

歸檔日誌存放形式主要存放方式有以下方式 一 asm方式 oracle 10g oracle11g oracle 12c版本如果作業系統是aix hpux linux下,一般都會採取asm建庫方式,特別是oracle 11g和oracle12c,因為oracle已經不支援裸裝置建庫 手工建庫還是可以裸...

ORACLE RAC環境下的外部表實驗

size large 一 結論 在virtualbox虛擬機器環境下,搭建oracle rac環境,結合nfs network file system rac各節點都能夠正常訪問外部表。即重點是要有各個節點都能夠訪問的共享儲存 目錄 其它共享機制或方式的實現沒有嘗試,也不太了解。二 環境說明 兩台r...