Sequence 是 Oracle 高併發唯一值生成的核心。基礎用法請參考姊妹篇;本文聚焦**進階場景**:大快取調優、RAC 環境 ORDER/NOORDER 抉擇、Data Guard 同步、備份恢復後序號倒退修正、審計追蹤與命名規範。
CACHE n 讓實例在 SGA 保留 n 個序號,用完再向數據字典申請下一批 (SEQ$ 表更新)。
建議 CACHE 值 ≈ (峰值 TPS × 容忍跳號秒數) / 實例數
-- 例:峰值 5000 TPS,單實例,容忍 1 秒跳號 → CACHE 5000
-- RAC 4 節點,同條件 → 每節點 CACHE 1250
-- 查看序號申請頻率 (每次申請觸發 SEQ$ 更新)
SELECT sequence_name, cache_size, last_number
FROM dba_sequences
WHERE sequence_owner = 'APP_OWNER';
-- 觀察 "sequence cache" 等待事件
SELECT * FROM v$system_event WHERE event LIKE '%sequence%';
| 模式 | 全局順序 | 效能 | 適用場景 |
|---|---|---|---|
ORDER | 嚴格遞增 (跨實例協調) | 高延遲 (GCS 鎖同步) | 發票號、審計流水號、法規要求連續 |
NOORDER (預設) | 實例內遞增,實例間交錯 | 極低延遲、線性擴展 | 主鍵、內部 ID、無業務連續要求 |
NOORDER CACHE 1000**ORDER CACHE 20**,接受較低並發YYYYMMDD + 序號) 規避 RAC 協調Primary 產生的 Sequence 值透過 Redo Apply 同步到 Standby,但 Standby 唯讀開放時 NEXTVAL 會報 ORA-16000。
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DELAY 60; 緩衝主庫故障,但不解決 NEXTVAL 問題最佳實踐:架構上**嚴禁 Standby 執行 NEXTVAL**,所有取號在 Primary 完成。
冷備份/邏輯導入恢復後,LAST_NUMBER 回到備份時刻,新 NEXTVAL 產生重複值 → 唯一索引報錯。
將 Sequence 推進至 MAX(主鍵值) + 安全間隙。
CREATE OR REPLACE PROCEDURE sync_sequences_post_restore AS
v_sql VARCHAR2(1000);
BEGIN
FOR rec IN (
SELECT s.sequence_owner, s.sequence_name,
t.table_name, c.column_name
FROM dba_sequences s
JOIN dba_dependencies d ON d.referenced_name = s.sequence_name AND d.referenced_type = 'SEQUENCE'
JOIN dba_tab_columns c ON c.table_name = d.name AND c.data_type = 'NUMBER'
JOIN dba_tables t ON t.table_name = c.table_name
WHERE s.sequence_owner = 'APP_OWNER'
AND c.column_name LIKE '%ID%' -- 簡單啟發式,建議維護映射表
) LOOP
-- 取得表中最大值
EXECUTE IMMEDIATE 'SELECT NVL(MAX('||rec.column_name||'),0) FROM '||rec.table_name
INTO v_max_id;
-- 計算目標值
v_target := v_max_id + 10000;
-- ALTER SEQUENCE ... INCREMENT BY 大值 → NEXTVAL → 改回
v_sql := 'ALTER SEQUENCE '||rec.sequence_owner||'.'||rec.sequence_name||
' INCREMENT BY '||v_target;
EXECUTE IMMEDIATE v_sql;
EXECUTE IMMEDIATE 'SELECT '||rec.sequence_owner||'.'||rec.sequence_name||'.NEXTVAL FROM DUAL';
v_sql := 'ALTER SEQUENCE '||rec.sequence_owner||'.'||rec.sequence_name||
' INCREMENT BY 1';
EXECUTE IMMEDIATE v_sql;
DBMS_OUTPUT.PUT_LINE('Synced '||rec.sequence_name||' to >'||v_target);
END LOOP;
END;
/
注意:需在維護窗口、單用戶模式執行,避免並發衝突。
SEQ_<表名>_<用途> -- 例: SEQ_ORDERS_PK, SEQ_INVOICE_NO
AUDIT CREATE SEQUENCE, ALTER SEQUENCE, DROP SEQUENCE BY ACCESS;
-- 定期查詢
SELECT timestamp, os_username, obj_name, action_name
FROM dba_audit_trail
WHERE action_name IN ('CREATE SEQUENCE','ALTER SEQUENCE','DROP SEQUENCE')
ORDER BY timestamp DESC;
Sequence 進階掌控三要素:**大快取高併發、RAC 分類用 ORDER、恢復後自動校準**。建立「Sequence 映射表」(表名、欄位、Sequence 名、快取值、ORDER 標記),納入 CMDB,讓每次架構變更、演練恢復都有章可循。