システム変更番号(SCN:システムチェンジナンバ)

  • トランザクションの毎に、シーケンシャルに割り振られる番号 (System Commit Number と表記される場合もある)

コントロールファイル、データファイル、REDO ログファイルなどに保存してある。 この番号を元に障害の有無を判別し、リカバリも行ったりする非常に重要な番号。
データベースにおいては、実世界の時間的な存在といえる。(システム日付は信用できないため)

SCN は以下の SCN_TO_TIMESTAMP 関数 を使用することで大まかな時間を得ることができる。Oracle 10g

SELECT TIMESTAMP_TO_SCN(date_time_value) FROM DUAL ;
SELECT SCN_TO_TIMESTAMP(number) FROM DUAL ;

SMON_SCN_TIME ディクショナリ表

  • SMON_SCN_TIME ディクショナリ表
SELECT * FROM SYS.SMON_SCN_TIME ORDER BY SCN DESC;

5分単位の SCN と TIMESTAMPの対比表を管理している ディクショナリ表 (約 1600レコードを保持)
( 1600 レコード * 5(m) ≒ 133(h) ≒ 5.5 (d) ) 最低でも 連続稼動時間 逆算で 5日分までは変換可能

現在の SCN の取得 Oracle 9i

Oracle 9i 以降であれば DBMS_FLASHBACK パッケージに GET_SYSTEM_CHANGE_NUMBER という関数が用意されており SELECT 文で現在の SCN を取得することができる。

SQL> SELECT SYSDATE,
  2   SCN_TO_TIMESTAMP(DBMS_FLASHBACK.GET_SYSTEM_CHANGE_NUMBER()) SCN_TIME
  3  FROM DUAL ;
 
SYSDATE             SCN_TIME
------------------- ---------------------------
2006/10/30 20:53:05 06-10-30 20:53:05.000000000
 
SQL>

現在の SCN の取得 (〜 Oracle 8i)

USERENV('COMMITSCN')を INSERT、UPDATE で使用する。SYS_CONTEXT では使えない。
SELECT では使用できない。 USERENV('COMMITSCN') は COMMIT 時に確定するため INSERT して SELECT したときと COMMIT した後で 再度 SELECT したときで比較すると値が増えている場合がある。まさに COMMIT するまでは現在進行形の関数である。 (このような関数は他に見たことがない)

-- DROP TABLE RIVUS.SCN_LOG;
CREATE TABLE RIVUS.SCN_LOG (A_SCN NUMBER);
INSERT INTO SCN_LOG (A_SCN) VALUES (USERENV('COMMITSCN'));
SELECT A_SCN FROM SCN_LOG;
CALL DBMS_LOCK.SLEEP(10); -- PUBLIC 権限では実行不可、実行権限の別途設定が必要
COMMIT;
SELECT A_SCN FROM SCN_LOG;

(注意) マニュアルに説明のない関数の使い方である。



関連事項

日本オラクル
■ 日本オラクル 株式会社
■ オラクルマスター資格 (オラクルマスターとは
■ 会員制(無料)の公式技術サイト