はじめに
データベースのアーキテクチャ、つまり仕組みを知るということは、データベース管理者(以下、DBA)にとって大変重要なことです。アーキテクチャを理解していると、データベースに障害が発生した際、その原因の解明や対処方法の検討を進めやすくなります。また、データベースの性能低下時における対処方法も考えられるようになります。
なお、データベースのアーキテクチャは製品ごとに異なります。そのため、本パートではOracle Database 10g(以下、Oracle)を例に説明を進めます。
データベースへの接続
まずは、SQL文がどのようにデータベース上で処理されていくかの大まかな流れを本パートの前半で説明していきます。一連の処理の流れをつかんでいただいた後に、後半で処理の詳細を解説します。まずはデータベースへの接続からです。
データベースへSQL文を発行する前には、データベースへの接続の操作を行なう必要があります。クライアント/サーバーシステムでは、クライアント側でSQL*Plusなどのツールを起動し、ユーザー名やパスワードを入力してログインします。このとき、Oracleは図1のように処理を行ないます。図中の丸数字で示している動作を、1つずつ説明しましょう。
なお、以降のデータベース処理の大まかな流れの説明でも、図を参照しながら数字で示されている各処理について、本文で解説することにします(本文中の数字が図内の丸数字と対応します)。
- クライアント側でデータベースへの要求のとりまとめを行なうユーザープロセスが起動し、以後ユーザープロセスを経由してデータベース側に各種の処理を依頼することとなります。
- データベース側では対応してサーバープロセスがメモリ上で起動します。サーバープロセスは接続の管理や処理の実行を行なうこととなります。
ユーザープロセスとサーバープロセスの関係は原則的には1対1の構成になります。サーバープロセスには専用の作業場所であるPGA(プログラムグローバル領域)がメモリ上に確保され、セキュリティ情報やリソースの使用量などが格納されます。またSQL文を実行する際、ORDER BY句があるときなどはソート(並べ替え)が必要となりますが、そのソートもPGAで行なわれます。
接続された状態をセッションとも呼びます。接続を切断するとユーザープロセスやサーバープロセスは終了し、メモリ内の関連する資源が解放されます。
SELECT文の実行
次に、SELECT文が発行されたときにOracleがどうデータを取り出すのかを見てみます。図2はその一連の処理を示したもので、クライアントマシンのSQL*PlusからSELECT文を発行する場面を想定しています。データベース処理の中でも、最も典型的な処理の1つなので、しっかり押さえましょう。
クライアントからSQL文を渡す
- ユーザーがSQL*Plus上でSELECT文を発行すると、まずユーザープロセスがそのとりまとめを行ないます。
- ユーザープロセスはサーバープロセスにそのSQL文を渡して処理を依頼します。
- サーバープロセスは、まずSGA(システムグローバル領域)の中の共有プールと呼ばれるところをチェックしに行きます。
SGAはインスタンスを構成する基本的なメモリ構成で、すべてのサーバープロセスによって共有されます。基本的には、SGAは次のものから構成されます(図3)。
- 共有プール
ユーザー間で共有できる「実行計画」や、データディクショナリのデータが格納される場所です。
- データベースバッファキャッシュ
表はディスク上のデータファイルに格納されますが、データベースバッファキャッシュはデータファイルから取り出されたデータブロックを格納する場所で、行を検索したり更新したりする際に使用されます。更新した行は、データブロック単位でデータファイル上に書き出されます。
- REDOログバッファ
ユーザーが行の追加/更新/削除などの処理を依頼すると、障害が発生したときの回復処理に必要となる情報として、REDOログが生成されます。REDOログバッファは、そのREDOログを一時的に格納する場所です。REDOログは、後でディスク上のREDOログファイルに書き出されます。
なお、実行計画とは、どのように表に対して検索を行なうか(「アクセスパス」と言います)が書かれた、いわば“SQLの実行手順書”です。Oracleは、SQL文を実行する際にはまず、SQL文を解析して最も効率的な実行計画を生成します。過去に同じSQL文が実行されていれば、その実行計画が格納されているので、以後の解析を行なうことなくSQL文が実行されます。解析されない分、実行時間は短縮されます。
SQL文を解析し実行計画を生成する
話が少しそれましたが、再び図2の解説に戻ります。
- 渡されたSQL文の実行計画が共有プールに見あたらない場合、Oracleはその解析作業を行ないます。解析作業はSQL文が文法的に正しいか、また指定対象の表や列が存在するかをチェックします。
- 表や列が存在するかどうかを確認するためには、データベースに関する管理情報が格納されている「データディクショナリ」を参照する必要があります。データディクショナリはSYSTEM表領域に格納されていますが、それを共有プール上に格納します。SYSTEM表領域とはデータディクショナリを含むOracleの管理データを格納するための表領域です。
- もし、SQL文の解析に必要な情報が共有プールに格納されていなければ、ディスクのデータディクショナリを参照して、共有プール上に格納します。
- 解析が終わり実行計画を作成したら、それがサーバープロセス間で再利用されるように共有プールに格納します。共有プールがいっぱいで実行計画が入り切らない場合には、LRUアルゴリズム(一番長い間参照されなかった情報を削除する方式)によって空きを作って格納します。
実行計画に基づいて表を検索する
- 実行計画を用意できたら、実行計画に基づいて表の検索を開始します。表の検索はSGAの中のデータベースバッファキャッシュに対して行なわれます。
- 表を検索する際、Oracleは参照する行のデータブロックがデータベースバッファキャッシュにあるか確認し、なければ実際にディスク上に格納されている表からデータブロック単位で取り出して、データベースバッファキャッシュに格納します。格納されたデータブロックは、サーバープロセス間で検索時や更新時に共有使用します。
なお、データベースバッファキャッシュがいっぱいになってしまった場合には、LRUアルゴリズムで空きを作って格納します。
- 表の検索処理は、索引を使用する検索と使用しない検索で異なります。索引については後に説明しますので、ここでは使用しない場合の検索処理を説明します。
索引を使用しない場合には、表の全行から検索条件に合う行を探すことになります。また、その際Oracle内部では表を構成する先頭のデータブロックの行から、「ハイウォーターマーク(HWM)」と呼ばれる印のあるデータブロックの最後の行まで検索が行なわれます(図4)。
なお、ハイウォーターマークは「高水位標」とも呼ばれ、もとは河川の過去最高水位を示す指標を意味します。Oracleにおけるハイウォーターマークは、過去に行が格納されたことがある最高位のデータブロックを指します。行を削除しても、このハイウォーターマークは下がりません。
- 表の検索をサーバープロセスが行なうと、その検索結果をユーザープロセスに引き渡します。これを「フェッチ」と言います。WHERE句などで検索条件が設定されている場合、サーバープロセスは行を絞り込んでユーザープロセスに結果を引き渡すことになります。ユーザープロセスはサーバープロセスから行を受け取ると、SQL*Plusの画面上に結果を表示します。