Ora-01555と対応方法

Ora-01555と対応方法

スナップショットが古すぎます: ロールバック・セグメント番号string、名前"string"が小さすぎます

原因: 一貫した読込みに必要なロールバック・レコードが他のユーザーによって上書きされています。
処置: 自動UNDO管理モードになっている場合は、UNDO_RETENTIONの設定値を大きくしてください。それ以外の場合は、ロールバック・セグメントを大きくしてください。

自動と従来のUNDO管理はUNDO_MANAGEMENT Init Prameterで確認できる。
show parameter UNDO_MANAGEMENT;
AUTOの場合は自動、MANUALの場合は手動(従来)の管理方法である。

1. 自動UNDO管理の場合、UNDO_RETENTIONを大きくする
確認方法:

show parameter UNDO_RETENTION;

または
select * from v$parameter where name = 'undo_retention';

対応方法:
大き目にUNDO_RETENTIONを設定する。ただし、UNDO TABLESPACEが自動拡張の場合、ディスク容量の不足と監視が必要である。また、UNDO TABLESPACE作成のときにRETENTION GUARANTEE文をつけた場合、大き目のUNDO_RETENTIONはシステム停止させるリスクがある。このようなケースで、NOGUARANTEEにするか、適切なUNDO_RETENTIONにする必要がある。

alter system set UNDO_RETENTION=<...(秒数)>;

また、execute immediate文でバッチの最初と最後に上記のDDLをつけておけば、特定のバッチに対してだけORA-01555を回避することができる。

2. 手動の場合の解決方法

ALTER ROLLBACK SEGMENT rbs_one 
   STORAGE (NEXT 1000 MAXEXTENTS 20);

従来の手動管理の場合、OLTPとOLAP/バッチの共存が難しい。OLTPはRBSの数を要求する、OLAP/バッチはRBSのサイズを要求する。全ての要求を満たすのが難しい。
SET TRANSACTION USE ROLLBACK SEGMENTまたはDBMS_TRANSACTION.USE_ROLLBACK_SEGMENT文でトランスアクションの最初につけることで、特定のバッチを大きいRBSに指定することで、ORA-01555を回避することができる。

SET TRANSACTION USE ROLLBACK SEGMENT rbs_one; 
DBMS_TRANSACTION.USE_ROLLBACK_SEGMENT('RBS_ONE');

また、あまりよくないが、バッチを修正できない場合、バッチの実行している間、OLTP用小さいRBSをすべてオフラインして、終わってからまたオンラインすれば、同じ効果を実現できる。

ALTER ROLLBACK SEGMENT rbs_one OFFLINE; 
ALTER ROLLBACK SEGMENT rbs_two OFFLINE; 
...
ALTER ROLLBACK SEGMENT rbs_large ONLINE; 
--バッチの実行
...
--バッチの完了
ALTER ROLLBACK SEGMENT rbs_one ONLINE; 
ALTER ROLLBACK SEGMENT rbs_two ONLINE; 
...
ALTER ROLLBACK SEGMENT rbs_large OFFLINE;

最後、RBS自動拡張の場合、バッチで無駄に拡大したことがある。下記のコマンドで解消できる。

ALTER ROLLBACK SEGMENT rbs_one 
   SHRINK TO 100 M;