
- 導入製品:Oracle AI Database 26ai Enterprise Edition Release 23.26.1.0.0
Oracle AI Database/Oracle Databaseを運用していると、次のような状況に直面することがあります。
「REDOログのサイズを変更したいけど、本番DBで止められない…」
ログスイッチが頻繁に発生し、アーカイブログファイルが大量に生成されるため早急に対処したいものの、データベースを停止する選択肢はないというケースは珍しくないです。
本記事では、DB起動中のままREDOログサイズを変更する手順を、実際のSQL実行結果を交えながら解説します。
- REDOログのサイズを増加させる必要性
- DB起動中のままREDOログのサイズを変更する手順
- 手順を実施する際の前提条件と注意点
REDOログとは
REDOログ(オンラインREDOログ)は、Oracle AI Database/Oracle Database上でのデータ変更履歴(INSERT/UPDATE/DELETE)を記録・保存するファイルです。
REDOログは、グループとメンバーで構成されています。1グループ(2メンバーの冗長化構成)を複数用意し、1グループ内の書き込み量が溜まると、ログスイッチで次のグループに保存の役割を引き継ぎます。
グループA(メンバー1とメンバー2)ー(ログスイッチ)ー→
グループB(メンバー1とメンバー2)ー(ログスイッチ)ー→
グループC(メンバー1とメンバー2)ー(ログスイッチ)ー→
グループA(メンバー1とメンバー2)ー(ログスイッチ)ー→繰り返す
REDOログのサイズを増加させる必要性
REDOログのサイズが小さいと、パフォーマンスの低下や運用上のトラブルにつながることがあります。
以下のような状況に当てはまる場合は、サイズの増加を検討してみてください。
ログスイッチが頻発して、ディスクI/O負荷が高い
REDOログが小さいと、データ変更履歴が大量に書き込まれた際にログスイッチが頻繁に発生します。
ログスイッチが頻繁に起きると、キャッシュ中のデータをデータファイルへ即座に書き込む必要が生じるため、ディスクへのI/O負荷が増大し、DBのキャッシュ機能を十分に活かせなくなります。
アーカイブログが大量に生成される
ログスイッチが発生するたびに、アーカイブログファイルが1つ作成されます。
REDOログが小さいほどログスイッチが頻繁に発生し、それに比例してアーカイブログファイル数も増加します。
結果として、ディスクI/Oの増加に加えて管理するファイル数も膨らみ、運用負荷が高まります。
REDOログのサイズ変更手順
REDOログのサイズをOracle AI Databaseが停止することなく、オンラインで変更する手順は以下になります。
- 現在のREDOログのサイズ確認
- 手動ログスイッチ
- REDOログのグループの削除・作成
- REDOログのグループ数だけ繰り返す
この手順は下記の条件を満たした場合にのみ適用されます
- 作業はSYSDBA権限を持つユーザで実行すること。
- REDOロググループが3グループ以上存在すること。
現在のREDOログのサイズ確認
V$LOGとV$LOGFILEを結合し、グループ番号・メンバー数・ステータス・サイズ・ファイルパスを一度に確認します。
SQL> set pages 500
SQL> set lines 500
SQL> col group# for 999
SQL> col members for 999
SQL> col status for a15
SQL> col bytes for 99999999
SQL> col member for a50
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------
1 1 CURRENT 200 /opt/oracle/oradata/FREE/redo01.log
2 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo02.log
3 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo03.logSTATUS列の値の意味は以下のとおりです。
| ステータス | 意味 | 削除 |
|---|---|---|
| CURRENT | 現在書き込み中 | 不可 |
| ACTIVE | スイッチ済みだが、未だデータファイルに書き込まれていない情報がある | 不可 |
| INACTIVE | ログスイッチ待ちで、現在は書き込みされていない | 可能 |
| UNUSED | 追加直後で新品未使用 | 可能 |
上記の実行結果の場合は、グループ1が CURRENT(書き込み中)で、それ以外のグループ2、3がINACTIVE(現在は書き込まれていない状態)になります。
手動でログスイッチ
手動でログスイッチを行い、溜まったREDOログを一度リセットします。あわせて、チェックポイントが未完了な状態のため手動でチェックポイントも実行します。
もし手動でログスイッチをせずに削除コマンドを実行しようとすると、その直前にREDOログが溜まって自動ログスイッチが発生し、削除しようとしていたグループがCURRENTに切り替わってしまう可能性があります。
CURRENTのグループは削除できないため、このタイミングが重なるとDROP LOGFILE GROUPが失敗してしまいます。
そのため、作業の直前に手動でログスイッチとチェックポイントを行い、削除対象のグループを確実にINACTIVE(削除可能な状態)にしてから次のステップに進みます。
SQL> alter system switch logfile;
System altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 ACTIVE 200 /opt/oracle/oradata/FREE/redo01.log
2 1 CURRENT 200 /opt/oracle/oradata/FREE/redo02.log
3 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo03.log
SQL> alter system checkpoint;
System altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo01.log
2 1 CURRENT 200 /opt/oracle/oradata/FREE/redo02.log
3 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo03.log
REDOログのグループの削除・作成
CURRENT(現在)のREDOロググループの一つ手前のREDOロググループから削除、再作成していきます。
今回はCURRENTがREDOロググループ2なため、REDOロググループ1から行っていきます。
SQL> ALTER DATABASE DROP LOGFILE GROUP 1;
Database altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
2 1 CURRENT 200 /opt/oracle/oradata/FREE/redo02.log
3 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo03.log
SQL> ALTER DATABASE ADD LOGFILE GROUP 1 ('/opt/oracle/oradata/FREE/redo-01.log') SIZE 300M;
Database altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 UNUSED 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 CURRENT 200 /opt/oracle/oradata/FREE/redo02.log
3 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo03.log作成直後はUNUSEDになりますが、ログスイッチするとUNUSEDをCURRENTになり正常に動作します。
また、本来は順番にローテーションしていきますが、UNUSEDがあるとログスイッチ時に優先的に書き込み先として選択されます。
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 UNUSED 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 CURRENT 200 /opt/oracle/oradata/FREE/redo02.log
3 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo03.log
SQL> alter system switch logfile;
System altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 CURRENT 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 ACTIVE 200 /opt/oracle/oradata/FREE/redo02.log
3 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo03.log
SQL> alter system checkpoint;
System altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 CURRENT 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo02.log
3 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo03.logREDOログのグループ数だけ繰り返す
あとはこれを順番に繰り返していくだけです。
SQL> ALTER DATABASE DROP LOGFILE GROUP 3;
Database altered.
SQL> ALTER DATABASE ADD LOGFILE GROUP 3 ('/opt/oracle/oradata/FREE/redo-03.log') SIZE 300M;
Database altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 CURRENT 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo02.log
3 1 UNUSED 300 /opt/oracle/oradata/FREE/redo-03.log
SQL> alter system switch logfile;
System altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 ACTIVE 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo02.log
3 1 CURRENT 300 /opt/oracle/oradata/FREE/redo-03.log
SQL> alter system checkpoint;
System altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 INACTIVE 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 INACTIVE 200 /opt/oracle/oradata/FREE/redo02.log
3 1 CURRENT 300 /opt/oracle/oradata/FREE/redo-03.logSQL> ALTER DATABASE DROP LOGFILE GROUP 2;
Database altered.
SQL> ALTER DATABASE ADD LOGFILE GROUP 2 ('/opt/oracle/oradata/FREE/redo-02.log') SIZE 300M;
Database altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 INACTIVE 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 UNUSED 300 /opt/oracle/oradata/FREE/redo-02.log
3 1 CURRENT 300 /opt/oracle/oradata/FREE/redo-03.log
SQL> alter system switch logfile;
System altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 INACTIVE 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 CURRENT 300 /opt/oracle/oradata/FREE/redo-02.log
3 1 ACTIVE 300 /opt/oracle/oradata/FREE/redo-03.log
SQL> alter system checkpoint;
System altered.
SQL> SELECT l.GROUP#, l.MEMBERS, l.STATUS, l.BYTES/1024/1024 AS MB,lf.member FROM V$LOG l JOIN V$LOGFILE lf ON l.GROUP# = lf.GROUP# ORDER BY GROUP#;
GROUP# MEMBERS STATUS MB MEMBER
------ ------- --------------- ---------- --------------------------------------------------
1 1 INACTIVE 300 /opt/oracle/oradata/FREE/redo-01.log
2 1 CURRENT 300 /opt/oracle/oradata/FREE/redo-02.log
3 1 INACTIVE 300 /opt/oracle/oradata/FREE/redo-03.logこれで全グループが300MBに変更されました。
まとめ
オンラインREDOログをOracle AI Database/Oracle Databaseを停止することなく、オンラインで変更する手順は以下になります。
- 現在のREDOログのサイズ確認
- 手動ログスイッチ
- REDOログのグループの削除・作成
- REDOログのグループ数だけ繰り返す
最後までご愛読ありがとうございました。
