日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

oracle获取序列跳号,Oracle sequence跳号知多少

發布時間:2023/12/19 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 oracle获取序列跳号,Oracle sequence跳号知多少 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Sequence是oracle中的一個非常常用的功能,開發經常會頻繁使用。但是在生產環境中經常有應用反饋通過sequence生成的自增主鍵會出現不連續跳號的現象,而且是幾十個幾十個地跳,為了弄清楚sequence跳號的原因和機制,進行了一些研究和實驗。

事務回滾引起的跳號

不管序列有沒有CACHE、事務回滾這種情況下,都會引起序列的跳號。如下實驗所示:

SQL> create sequence test_seq

start with 1

increment by 1

Maxvalue 9999999999

Cache 30

Order;

Sequence created.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

1

SYS@orcl>insert into test_tab select test_seq.nextval from dual;

1 row created.

SYS@orcl>rollback;

Rollback complete.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

3

并發訪問序列引起的跳號

并發訪問序列引起的跳號,其實不算真正的跳號,而只是邏輯跳號,只是序列值被其它并發會話使用了。我們來構造一起并發訪問序列引起的跳號,我們開啟兩個會話窗口,循環獲取序列的值,模擬并發出現的場景。

Session 1:

SYS@orcl>begin

for i in 1..50000 loop

Insert into ta select test_seq.nextval from dual;

end loop;

end;

/

PL/SQL procedure successfully completed.

Session 2:

SYS@orcl>begin

for i in 1..50000 loop

insert into tb select test_seq.nextval from dual;

end loop;

end;

/

PL/SQL procedure successfully completed.

SYS@orcl>select * from ta where rownum<10;

ID

----------

466322

466324

466326

466327

466329

466330

466332

466333

466335

9 rows selected.

發現序號并不連續,高并發情況下存在sequence爭用。

FLUSH SHARED_POOL會導致CACHE的序列跳號

實驗測試如下所示(序列的CACHE值必須大于0),當然正常情況下,很難遇到這種情況。

SYS@orcl>alter sequence test_seq cache 30;

Sequence altered.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560432

SYS@orcl>alter system flush shared_pool;

System altered.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560462

數據庫實例異常關閉導致跳號

如下實驗所示,當數據庫使用shutdown abort命令關閉后,重新啟動實例,序列緩存在shared pool里面沒有用過的值都沒有了。一下子從17045跳到17085

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560464

SYS@orcl>select object_id from dba_objects where object_name='TEST_SEQ';

OBJECT_ID

----------

20306

SYS@orcl>select increment$,minvalue,maxvalue,highwater,cache from seq$ where obj#=20306;

INCREMENT$ ??MINVALUE ??MAXVALUE ?HIGHWATER ?????CACHE

---------- ---------- ---------- ---------- ----------

1 ??????????1 ??9999999999 ????560492 ????????30

SYS@orcl>shutdown abort;

ORACLE instance shut down.

SYS@orcl>startup;

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560492

而在正常關閉數據庫的情況下,sequence沒有發生跳號

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560526

SYS@orcl>shutdown immediate;

Database closed.

Database dismounted.

ORACLE instance shut down.

SYS@orcl>startup;

ORACLE instance started.

Total System Global Area 4375998464 bytes

Fixed Size ?????????????????2260328 bytes

Variable Size ???????????1946157720 bytes

Database Buffers ????????2415919104 bytes

Redo Buffers ??????????????11661312 bytes

Database mounted.

Database opened.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560527

設置test_seq為nocache,然后異常宕機

SYS@orcl>alter sequence test_seq nocache;

Sequence altered.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560528

SYS@orcl>shutdown abort;

ORACLE instance shut down.

SYS@orcl>startup;

ORACLE instance started.

Total System Global Area 4375998464 bytes

Fixed Size ?????????????????2260328 bytes

Variable Size ???????????1946157720 bytes

Database Buffers ????????2415919104 bytes

Redo Buffers ??????????????11661312 bytes

Database mounted.

Database opened.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560529

查閱資料發現數據庫正常關閉的情況下,會觸發一個update seq$的操作,把當前的sequence.nextval的值更新到seq$.highwater中,從而使得sequence在有cache的情況下,數據庫正常關閉未出現nextval跳躍(currval也同樣不跳躍);而在數據庫異常關閉之時,數據庫不能及時將sequence.nextval更新到eq$.highwater從而引起sequence cache中的值丟失,從而可能出現了sequence使用cache導致跳躍的情況

MOS(文檔ID:470784.1)上提到了使用dbms_shared_pool.keep將對象在鎖定在shared pool 中,永遠不釋放。這樣可以防止FLUSH SHARED POOL導致序列跳號,但是這個無法避免數據庫異常關閉或CRASH引起的跳號

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560530

SYS@orcl>exec dbms_shared_pool.keep('test_seq','q');

PL/SQL procedure successfully completed.

SYS@orcl>alter system flush shared_pool;

System altered.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560531

SYS@orcl>alter sequence test_seq cache 30;

Sequence altered.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560532

SYS@orcl>shutdown abort

ORACLE instance shut down.

SYS@orcl>startup;

ORACLE instance started.

Total System Global Area 4375998464 bytes

Fixed Size ?????????????????2260328 bytes

Variable Size ???????????1946157720 bytes

Database Buffers ????????2415919104 bytes

Redo Buffers ??????????????11661312 bytes

Database mounted.

Database opened.

SYS@orcl>select test_seq.nextval from dual;

NEXTVAL

----------

560562

其實如果業務允許,單號出現跳號也無所謂的情形最好,如果碰到業務要求絕對不能出現單號出現跳號的情況,那么就不能使用序列號了。

RAC環境中的sequence

如果是cache下的order,單實例下沒有影響,而rac下多實例緩存相同的sequence,如果order的取大量sequence則會出現短暫的資源競爭(由于資源需要在多實例間傳遞),性能要比noorder差很多。尤其注意nocache order的sequence,即對于sequence大量爭用,還需要在實例間傳遞競爭資源,嚴重的甚至導致系統直接hang住,對于rac的環境需要通過cache fusion和序列的機制認真分析來找到性能瓶頸的根本原因。

oracle為了在rac環境下為了sequence的一致性,使用了三種鎖:row cache lock、SQ鎖、SV鎖。row cache lock的目的是在sequence指定nocache的情況下調用sequence.nextval過程中保證序列的順序性;SQ鎖是應用于指定了cache+noorder的情況下調用sequence.nextval過程中。SV 鎖(dfs lock handel) 是調用sequence.nextval期間擁有的鎖。前提是創建sequence時指定了cache 和order屬性 (cache+order)。order參數的目的是為了在RAC上節點之間生成sequence的順序得到保障。

創建sequence賦予的cache值較小時,有enq:sq-contention等待增加的趨勢。cache的缺省值是20.因此創建并發訪問多的sequence時,cacheh值應取大一些。否則會發生enq:sq-contention等待事件。

rac上創建sequence時,如果指定了cache大小而賦予noorder屬性,則各節點將會把不同范圍的sequence值cache到內 存上。若兩個節點之間都必須通過依次遞增方式使用sequence,必須賦予如下的order屬性(一般不需要這樣做)”sql> create sequence seq_b cache 100 order”。如果是已賦予了cache+order屬性的sequence,oracle使用SV鎖進行同步。SV鎖爭用問題發生時的解決方法與sq鎖 的情況相同,就是將cache 值進行適當調整。

在RAC多節點環境下,Sequence的Cache屬性對性能的影響很大。應該盡量賦予cache+noorder屬性,并要給予足夠的 cache值。如果需要保障順序,必須賦予cache+order屬性。但這時為了保障順序,實例之間需要不斷的交換數據。因此性能稍差。

總結

以上是生活随笔為你收集整理的oracle获取序列跳号,Oracle sequence跳号知多少的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。