
- 導入製品:Oracle AI Database 26ai Enterprise Edition Release 23.26.1.0.0
Oracle AI Database/Oracle Databaseを運用していると、下記のような状況に直面することがあります。
「REDOログのサイズを変更したいけど、本番DBで止められない…」
ログスイッチが頻繁に発生し、アーカイブログが大量に生成されるため、早急に対処したいがデータベースを停止する選択肢はないというケースは珍しくないです。
本記事では、DB停止なし(起動中)のままREDOログサイズを変更する手順を、実際のSQL実行結果を交えながら解説します。
- REDOログのサイズを増加させる必要性について
- REDOログのサイズ変更手順(DB起動中)
REDOログとは
REDOログ(オンラインREDOログ)とは、Oracle AI Database/Oracle Database上でのデータ変更履歴(INSERT/UPDATE/DELETE)を記録・保存するファイルです。
インスタンス障害、メディア障害のリカバリに使用されるため、非常に重要なデータベースファイルの一種です。
REDOログは、グループとメンバーで構成されています。
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ログが溜まって自動ログスイッチされないように一度手動でログスイッチします。
また、チェックポイントが未完了な状態なので手動でチェックポイントします。
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ログのグループ数だけ繰り返す
最後までご愛読ありがとうございました。
