前回は障害時の情報を確認するためのログについて説明しました。今回は領域に関する問題「セグメント拡張時のエラー」について紹介します。データベースは運用から時間がたつにつれてデータ量が増え、構築時に想定していた容量では収まりきらなくなりセグメントの拡張を行わなくてはいけない状況が発生します。その際にセグメントが正常に拡張できずシステム障害が発生する場合があります。今回はそのような問題を防ぐための考え方と、発生した際の対応策について解説します。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
そもそもセグメントとは何でしょうか? Oracle Database(以降、Oracle)がデータを格納する際にOSレベルで管理する構造(データファイル)を物理構造といい、データファイル内の領域を論理的に管理する構造(表領域、セグメント、エクステント、データブロックなど)を論理構造といいます。
論理構造という考え方がなかった場合、テーブルを1つ作るごとにデータファイルが1つ作成されることになり、管理などが非常に複雑化します。Oracleでは論理構造という考え方を取り入れることにより、データファイル内に論理的に領域を区切り、管理を行っています。
セグメントの拡張について説明をする前に、セグメントを取り巻く記憶構造について説明しておきましょう(図1)。
名称 | 概要 |
---|---|
データファイル | OSレベルで管理される物理的な領域。Oracleでは、1つ以上のファイルをまとめて「表領域」という論理構造を構成 |
表領域 | 1つ以上のデータファイルにより構成される論理的な領域。ここに、テーブルやインデックスなどを格納 |
データブロック | Oracleがデータを読み込む際の最小単位 |
エクステント | 連続した、1つ以上のデータブロックのまとまり |
セグメント | 1つ以上のエクステントのまとまり。あるデータを記録するための領域そのもの(テーブル、インデックス) |
表1 図1の要素一覧 |
・データファイル
OSレベルで管理される物理的な構造です。Oracleが扱うデータは、実質はすべてこのデータファイル内に格納されます。
・表領域
1つ以上のデータファイルから構成される、Oracleの論理構造です。テーブルやインデックスなど、データを記録するためのセグメントが保存される領域です。表領域には、格納されるデータによっていくつかの種類があります(表2)。
領域名 | 内容 |
---|---|
SYSTEM表領域 | Oracleを運用するうえで必要なディクショナリ情報などを格納する |
SYSAUX表領域 | SYSTEM表領域の補助表領域として、データベース・コンポーネントを格納する(必ず作成する必要があります) |
UNDO情報 | 読み取り一貫性に必要な情報を格納する |
TEMP表領域 | メモリ上で処理しきれないソート処理時に使用する |
ユーザー・データ用表領域 | テーブルやインデックスを格納する |
表2 表領域に格納されるデータの種類 |
・データブロック
データブロックは、Oracleが管理する論理構造の最小単位です。Oracleでは、データファイルの中をデータブロック単位で区切り、データを格納しています。
・エクステント
エクステントは、連続したデータブロックで構成されています。Oracleはテーブルやインデックスを作成・拡張した際に、エクステント単位で領域の割り当てを行います。
・セグメント
セグメントは、1つ以上のエクステントによって構成されます。また、論理構造ではセグメントと呼びますが、これがイコール「テーブル」や「インデックス」となります。つまり、セグメント(テーブルやインデックス)内の既存のデータブロックを使い尽くすと、Oracleはそのセグメントに、新しいエクステントを割り当てます。
表領域は、1つ以上のデータファイルから構成されるOracleの論理構造ですが、エクステントの管理方法にはSYSTEM表領域のディクショナリで管理する「ディクショナリ管理表領域」と、各デ−タファイル内のビットマップで管理する「ローカル管理表領域」の2種類があります。
以降では、この2つの表領域の管理方法について確認します。
・ディクショナリ管理表領域
Oracle 8.0以前でのデフォルトの表領域管理方法です。各パラメータ設定によりエクステント割り当てが指定されます。エクステント割り当ての情報はSYSTEM表領域にあるディクショナリ内で管理されますが、エクステント拡張・削除処理のたびにSYSTEM表領域へアクセスされるため、競合が発生し、Oracleの負荷が高くなりやすい欠点があります。
・ローカル管理表領域
Oracle 8iから使用できるようになった表領域の管理方法です。表領域内のエクステントのメンテナンスを各データファイル内のビットマップによって管理しています。エクステントの管理情報を各データファイルに書き込むため、競合によるOracleの負荷が軽減されています。
ここまでで、セグメントを取り巻く記憶構造についてのひと通りの確認はできました。次に、実際にセグメントが拡張するのはどのようなときなのかについて見ていきます。
作成したセグメント(テーブルやインデックス)は、データが後から追加されたり更新されることが多々あります。それによって、セグメントに対してデータを格納していくと「拡張」という動作が発生します。
これは、最初に作成した際のセグメントのサイズではデータを格納できなくなった際に、追加データを格納するために発生する動作です。Oracleには、「拡張」をする際に2つの拡張方法が用意されています。
・UNIFORM SIZE
セグメント(テーブル、インデックス)を作成時にユーザーが指定したエクステントのサイズを基に、均一に拡張する方式です。拡張するデータ量があらかじめ見積もれる場合には、無駄なく領域を使うことができます。
一方で、拡張するデータ量が見積もれない場合には、必要以上の領域を確保してしまい、領域の無駄が発生します。しかし、均一のエクステントで拡張するように設定すると、すべてのエクステントが同一サイズとなるため、過去に使用したエクステントの再利用がしやすくなります。
・AUTOALLOCATE
セグメント(テーブル、インデックス)作成時にエクステントの拡張サイズを指定しない場合、すべてAUTOALLOCATEになります。
AUTOALLOCATEの場合、セグメントの大きさにより、拡張するエクステントの大きさが変化します(最小単位は64Kbytes)。
そのため、非常に小さいセグメントの場合には領域の無駄が発生する可能性がありますが、セグメントごとに拡張するエクステントサイズを設定する手間が省けます。
一方で、作成するセグメントにより、拡張するエクステントのサイズがまちまちになるため、エクステントの再利用がしにくくなります。
図2は、(1)UNIFORM SIZEを指定した場合と、(2)AUTOALLOCATEを指定した場合の、エクステント拡張時の違いを表しています。白い四角は、まだ確保されていないデータブロックを表し、オレンジの四角は、エクステントとして確保されたデータブロックを表しています。
図を見ると分かるとおり、UNIFORM SIZEを指定した場合、均一なサイズで拡張していきます。これに対して、AUTOALLOCATEを指定した場合、新たに拡張されるエクステントのサイズが、どんどん大きくなっていくことが分かります。
Copyright © ITmedia, Inc. All Rights Reserved.