從SEQUENCE跳號說起
一個應用上線後發現一個使用SEQUENCE值來生成的主鍵經常出現斷號,而且斷號不是一兩個,而是每次幾十個幾十個的跳。而一般能想到的導致這種跳號的 基本就是事務ROLLBAK了導致取出的SEQUENCE沒有被插入到表中去,或者就是資料庫關閉或者宕掉,導致已經CACHE的SEQUENCE的值丟 失,導致的跳號。而在這個場景下,這兩種情況都被一一排除了。那麼到底什麼原因導致的SEQUENCE跳號呢?[@more@]
一般為了提高從SEQUENCE取值的效率,我們都會對SEQUENCE設定CACHE,而且取值越頻繁的,CACHE值設定的越大。那麼這個CACHE的值是儲存在SHARED POOL中的,而且這塊記憶體是可以被其他程式共享的,也就是說SEQUENCE的CACHE是會在一定的情況下被刷出SHARED POOL的,那麼就相當於已經CACHE的SEQUENCE的值就丟失了,這就是導致跳號的原因。下面我們透過一個示例來證明並展開來看看。
SQL> create sequence seq_bear cache 100;
Sequence created
首先建立一個CACHE值為100的SEQUENCE
SQL> select seq_bear.nextval from dual;
NEXTVAL
----------
1
查詢SEQUENCE的值為1,再次查詢的話,SEQUENCE取下一個值,為2
SQL> /
NEXTVAL
----------
2
SQL> alter system flush shared_pool;
System altered
SQL> select seq_bear.nextval from dual;
NEXTVAL
----------
101
而當我們重新整理SHARED_POOL並再次查詢的時候,SEQUENCE的值直接跳到了101,說明已經CACHE的值除了被使用的1和2之外,其他的98個全部丟失了。
那麼我們如何避免這種情況呢?ORACLE給我們提供了把SEQUENCE KEEP到SHARED POOL中的方法,這樣就保證了SEQUENCE的CACHE不會被交換出去,從而避免了這種情況的發生。來看下面的示例:
SQL> select seq_bear.nextval from dual;
NEXTVAL
----------
102
再次查詢的時候,值為102
SQL> exec dbms_shared_pool.keep(name => 'SEQ_BEAR',flag => 'Q');
PL/SQL procedure successfully completed
使用DBMS_SHARED_POOL來KEEP SEQUENCE的CACHE
SQL> SELECT SEQ_BEAR.NEXTVAL FROM DUAL;
NEXTVAL
----------
103
再次查詢,值為103
SQL> ALTER SYSTEM FLUSH SHARED_POOL;
System altered
SQL> SELECT SEQ_BEAR.NEXTVAL FROM DUAL;
NEXTVAL
----------
104
而這時當我們再次重新整理SHARED POOL並從SEQUENCE取值的時候,發現SEQUENCE已經不再跳號了。
那麼,如何能知道哪些SEQUENCE已經被KEEP了呢?
SQL> select KEPT from v$db_object_cache where name='SEQ_BEAR';
KEPT
----
YES
透過查詢V$DB_OBJECT_CACHE可以看到物件是否已經被KEEP在SHARED POOL,同時,這個檢視中還提供了其他的一些資訊,比如物件被LOAD了多少次、佔用多少記憶體空間等等資訊
DBMS_SHARED_POOL不僅可以KEEP SEQUENCE的CACHE,還可以KEEP住儲存過程、包、SQL等等,保證這些不會被交換出SHARED POOL。而KEEP方法使用也很簡單,只需要傳入要KEEP的物件的名稱,如果是其他使用者的,則使用USERNAME.OBJECT_NAME作為傳入引數;後面一個參數列示要KEEP的物件的型別,比如是包、SEQUENCE、SQL還是其他。具體的取值可以參考ORACLE的文件,上面寫的很詳細。
同時,DBMS_SHARED_POOL還提供了其他幾個方法:
ABORTED_REQUEST_THRESHOLD(threshold_size NUMBER):這個方法可以設定一個界限,保證如果要進入SHARED POOL的物件太大,那麼可以設定一個閥值,超過這個閥值的直接報錯,而不是經過LRU查詢和記憶體交換之後發現SHARED POOL不夠了再報錯,可以防止超大物件過度佔用SHARED POOL空間。
UNKEEP就是KEEP的反操作
SIZES (minsize NUMBER):這個是列出SHARED POOL中所有大於minsize的物件,對於查詢SHARED POOL中大物件並設定合理的ABORTED_REQUEST_THRESHOLD很有用。
總結:
SEQUENCE跳號可能是事務ROLLBAK或者例項被宕過或者是SEQUENCE的CACHE被交換出去過,對於有特殊要求的SEQUENCE或者包、儲存過程、觸發器等等,可以使用DBMS_SHARED_POOL.KEEP方法,把他們永久保留在SHARED POOL中,從而可以實現一些特定的用途。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/25016/viewspace-1030920/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 從 JSON 說起JSON
- iOS逆向——從RSA說起iOS
- 從測試說起(二)
- 從 RouterModule.forRoot 方法說起
- 從 CALayer 的 Position、AnchorPoint 說起
- 曹工說Tomcat1:從XML解析說起TomcatXML
- 從《死亡擱淺》6.8分說起
- 從 gRPC 的重試策略說起RPC
- AR,我們從設計說起
- 叢集通訊:從心跳說起
- 從用SwiftUI搭建專案說起SwiftUI
- 從兩道面試題說起面試題
- 從Kotlin的類開始說起Kotlin
- FinOps實踐,從降本增效說起
- 從淘寶首頁登入說起
- 從救貓還是救畫說起
- 決策樹詳解,從熵說起熵
- 從容器映象的選擇-alpine 說起
- JavaScript 事件迴圈(1) —— 從 setTimeout 說起JavaScript事件
- 從滅霸的無限手套說起
- 夯實Java:從物件導向說起Java物件
- 從concurrent下的Atomic原子類說起
- 從未卜先知的訊號燈說起,阿里城市大腦的智慧交通實踐阿里
- 從放棄到入門-Yaf(從控制器說起)
- Flutter異常監控 - 壹 | 從Zone說起Flutter
- 故障分析 | 從 data_free 異常說起
- 從 Redux 說起,到手寫,再到狀態管理Redux
- 從Xcode10不再支援libstdc++說起XCodeC++
- 磨針記1——從*外殺馬說起
- 從一道筆試題題說起筆試
- Java乾貨整理,從入門說起(7.11)Java
- 從MySQL大量資料清洗到TiBD說起MySql
- Everything is Serverless,從開源框架對比說起Server框架
- 從函數語言程式設計說起函數程式設計
- 從JavaScript中的類陣列物件說起JavaScript陣列物件
- 從FMDB執行緒安全問題說起執行緒
- Python乾貨整理,從入門說起(7.4)Python
- 從一次Kafka當機說起(JVM hang)KafkaJVM