システム変更番号(SCN:システムチェンジナンバ)
- トランザクションの毎に、シーケンシャルに割り振られる番号 (System Commit Number と表記される場合もある)
コントロールファイル、データファイル、REDO ログファイルなどに保存してある。
この番号を元に障害の有無を判別し、リカバリも行ったりする非常に重要な番号。
データベースにおいては、実世界の時間的な存在といえる。(システム日付は信用できないため)
SCN は以下の SCN_TO_TIMESTAMP 関数 を使用することで大まかな時間を得ることができる。
SELECT TIMESTAMP_TO_SCN(date_time_value) FROM DUAL ;
SELECT SCN_TO_TIMESTAMP(number) FROM DUAL ;
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 以降であれば 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;
(注意) マニュアルに説明のない関数の使い方である。
関連事項