
Oracle データベース用の Docker イメージを作成していますが、同じイメージからさまざまなコンテナーが生成されます。
Oracle インスタンスを起動すると、何らかの理由で、すべてのアクティブなデータファイルに数バイトが書き込まれます。Docker はコンテナからベース イメージへの差分を保存しますが、差分は変更されたファイル全体であるため、コンテナを起動するたびに、データベースを起動するためだけに 6 GB 以上がディスクに書き込まれます。
では、なぜ Oracle はデータベースの起動時にデータファイルに書き込むのでしょうか? 最も論理的な動作は、データが変更されてコミットされたときにのみデータファイルに書き込むことです。これを変更する方法はありますか?
Oracle Linux (私のイメージのベース) のほかに、Windows でも試してみましたが、動作は同じで、すべてのデータファイルが書き込まれました。
表領域を読み取り専用に設定してみました。これにより書き込み操作は回避されますが、表領域を読み取り/書き込みに設定するとすぐにファイルに書き込まれるため、再び問題が発生します。
明確にするために、テーブルスペースは書き込み可能である必要がありますが、それはデータが実際に変更されたときだけです。
答え1
これを避ける方法はありません。ユーザー データの他に、Oracle には多くのメタデータも含まれており、これらも維持する必要があります。Oracle は内部的に SCN (システム変更番号) と呼ばれる番号を維持しています。この番号は、データベースで「何か」が変更されるたびに増加します。
この SCN 番号は、すべてのデータファイルの先頭とすべての制御ファイルにも書き込まれます。データベースを開く (起動する) ときに、Oracle は、この番号がすべてのファイルで同じであることを確認します。その後、ファイルは一貫していると想定されます。
この SCN は、データベースに負荷がない場合でも増加します。また、統計収集などのバックグラウンド ジョブも負荷をかけます。また、ユーザーは、ON DATABASE STARTUP
データベースの起動時に何らかのジョブを実行するシステム トリガーを作成することもできます。
一般的に、Oracle データベース サーバーは仮想化に適していません。Oracle はジャーナリングを内部的にも行うため、同じデータを 2 回保持することになります (これらのファイルはアーカイブ redo-log と呼ばれます)。そのため、コンテナーの diff (データファイルのみ) を削除しても、Oracle は redo-log からトランザクションを再生できるため、その状態を生き残ることができます。
PS: データベースをクローンするときは、データベース SID を一意に変更することも検討する必要があります。または、少なくとも nid を使用してデータベースの一意の番号 DBID を変更する必要があります。そうしないと、RMAN データベース バックアップを復元するときに問題が発生する可能性があります。