(57)【要約】【課題】更新を伴う複数のトランザクションを平行実行してもデータベースサーバ間で常に同期を維持し続ける高信頼化データベースシステムにおける同期維持方法を提供する。【解決手段】仲介装置２０は、複数のデータベースサーバ１０のうち一つをｌｅａｄｅｒとし残りをｆｏｌｌｏｗｅｒとしてあらかじめ選定しておき、クライアントコンピュータ５０から処理要求を受信した時、該処理要求をｌｅａｄｅｒのみに送信し、ｌｅａｄｅｒから該処理要求に対する応答を受信したらｆｏｌｌｏｗｅｒへ該処理要求を送信する。【選択図】図１
2009169449.tif 000002
【特許請求の範囲】
【請求項１】
同一データに複数の処理要求が同時にアクセスを試みた場合一つの処理要求のみを実行しその他は待たせる機能を有する複数のデータベースサーバと、クライアントコンピュータからの処理要求を一つ以上のデータベースサーバに中継するとともに前記データベースサーバからの正当な応答の一つをクライアントコンピュータに処理結果として返す仲介装置とを備えた高信頼化データベースシステムにおいて、各データベースサーバ間の同期を維持する方法であって、
仲介装置は、前記複数のデータベースサーバのうち一つをｌｅａｄｅｒとし残りをｆｏｌｌｏｗｅｒとしてあらかじめ選定しておき、
クライアントコンピュータから処理要求を受信した時、
（ａ）該処理要求をｌｅａｄｅｒのみに送信し、
（ｂ）ｌｅａｄｅｒから該処理要求に対する応答を受信したらｆｏｌｌｏｗｅｒへ該処理要求を送信する
ことを特徴とする高信頼化データベースシステムにおける同期方法。
【請求項２】
仲介装置は、前記ステップ（ａ）において、クライアントコンピュータから処理要求（以降「新しい処理要求」と言う）を受信した時、既にサーバへ送信した別の処理要求（以降「古い処理要求」と言う）に対して応答を返していないサーバが存在しかつ前記新しい処理要求と前記古い処理要求が同一トランザクションに属する場合前記新しい処理要求を仲介装置で保持し、前記応答を受信したら前記新しい処理要求をｌｅａｄｅｒのみに送信する
ことを特徴とする請求項１記載の高信頼化データベースシステムにおける同期方法。
【請求項３】
仲介装置は、処理要求を送信したｆｏｌｌｏｗｅｒからの応答を全て受信したら該応答の一つをクライアントコンピュータへ返す
ことを特徴とする請求項１又は２いずれか１項記載の高信頼化データベースシステムにおける同期方法。
【請求項４】
クライアントコンピュータは、既に送信した処理要求に対する応答を受信してから新たな処理要求を送信する
ことを特徴とする請求項１乃至３いずれか１項記載の高信頼化データベースシステムにおける同期方法。
【請求項５】
仲介装置は、クライアントコンピュータからの処理要求を差分情報として記憶する差分情報記憶部を備え、同期から外れているデータベースサーバ（以降「同期外れデータベースサーバ」と言う）の同期化要求があると、正常稼働中のデータベースサーバからバックアップデータの作成を開始し、クライアントコンピュータから受信する処理要求を差分情報記憶部にｌｅａｄｅｒからの応答を受信した順序で記憶し、バックアップデータの作成を完了すると該バックアップデータを用いて同期外れデータベースサーバを復元させ、同期外れデータベースサーバにおいて前記バックアップデータからのデータベースの復元が完了すると、差分情報記憶部に記憶されている処理要求を同期外れデータベースサーバに順次送出する
ことを特徴とする請求項１乃至４いずれか１項記載の高信頼化データベースシステムにおける同期方法。
【請求項６】
仲介装置は、クライアントコンピュータから処理要求を受信した時、該処理要求がデータベースの更新を伴う処理要求又はデータベースの更新を伴う処理要求の動作に影響を与える処理要求の場合同期維持処理を行い、
前記同期維持処理においては、前記（ａ）のステップを行い、前記（ｂ）のステップを行う、
ことを特徴とする請求項１乃至５いずれか１項記載の高信頼化データベースシステムにおける同期方法。
【請求項７】
仲介装置は、クライアントコンピュータから処理要求を受信した時、該処理要求がデータベースの更新を伴う処理要求又はデータベースの更新を伴う処理要求の動作に影響を与える処理要求の場合前記同期維持処理を行い、該処理要求がデータベースの更新を伴う処理要求でもなくデータベースの更新を伴う処理要求の動作に影響を与える処理要求でもなくデータベースへの更新を確定する処理要求でもない場合通常処理を行い、該処理要求がデータベースの更新を伴う処理要求でもなくデータベースの更新を伴う処理要求の動作に影響を与える処理要求でもなくデータベースへの更新を確定する処理要求である場合確定処理を行い、
前記通常処理においては、クライアントコンピュータからの処理要求をサーバへ送信し、処理要求を送信したサーバから応答を受信し、
前記確定処理においては、他の処理要求が実行中の場合は他の処理要求が実行中でない状態になるまで待ち、他の処理要求が実行中でない場合は他の処理要求が実行できないようにし、通常処理を行い、再び他の処理要求が実行できるようにする
ことを特徴とする請求項１乃至６いずれか１項記載の高信頼化データベースシステムにおける同期方法。
【請求項８】
仲介装置は、クライアントコンピュータから処理要求を受信した時、データベースのコピーであるスナップショットが作成済みでない場合かつ該処理要求がスナップショットを作成する処理要求である場合スナップショット作成処理を行い、スナップショットが作成済みでない場合かつ該処理要求がスナップショットを作成する処理要求でない場合通常処理を行い、スナップショット作成済みである場合かつ該処理要求がデータベースの更新を伴う処理要求又はデータベースの更新を伴う処理要求の動作に影響を与える処理要求の場合前記同期維持処理を行い、スナップショット作成済みである場合かつ該処理要求がデータベースの更新を伴う処理要求でもなくデータベースの更新を伴う処理要求の動作に影響を与える処理要求でもなくデータベースへの更新を確定する処理要求でもない場合通常処理を行い、スナップショット作成済みである場合かつ該処理要求がデータベースの更新を伴う処理要求でもなくデータベースの更新を伴う処理要求の動作に影響を与える処理要求でもなくデータベースへの更新を確定する処理要求である場合確定処理を行い、
前記スナップショット作成処理においては、データベースへの更新を確定する処理要求が実行中の場合はデータベースへの更新を確定する処理要求が実行中でない状態になるまで待ち、データベースへの更新を確定する処理要求が実行中でない場合はデータベースへの更新を確定する処理要求が実行できないようにし、前記処理要求がデータベースの更新を伴う処理要求又はデータベースの更新を伴う処理要求の動作に影響を与える処理要求の場合は同期維持処理を行い、データベースの更新を伴う処理要求でもなくデータベースの更新を伴う処理要求の動作に影響を与える処理要求でもない場合は通常処理を行い、再びデータベースへの更新を確定する処理要求が実行できるようにし、
前記確定処理においては、スナップショットを作成する処理要求が実行中の場合はスナップショットを作成する処理要求が実行中でない状態になるまで待ち、スナップショットを作成する処理要求が実行中でない場合はスナップショットを作成する処理要求が実行できないようにし、通常処理を行い、再びスナップショットを作成する処理要求が実行できるようにする
ことを特徴とする請求項１乃至７いずれか１項記載の高信頼化データベースシステムにおける同期方法。
【請求項９】
同一データに複数の処理要求が同時にアクセスを試みた場合一つの処理要求のみを実行しその他は待たせる機能を有する複数のデータベースサーバと、クライアントコンピュータからの処理要求を一つ以上のデータベースサーバに中継するとともに前記データベースサーバからの正当な応答の一つをクライアントコンピュータに処理結果として返す仲介装置とを備えた高信頼化データベースシステムにおいて、
仲介装置は、前記複数のデータベースサーバのうち一つをｌｅａｄｅｒとし残りをｆｏｌｌｏｗｅｒとしてあらかじめ選定しておき、クライアントコンピュータから処理要求を受信した時、該処理要求をｌｅａｄｅｒのみに送信し、ｌｅａｄｅｒから該処理要求に対する応答を受信したらｆｏｌｌｏｗｅｒへ該処理要求を送信する制御部を備えた
ことを特徴とする高信頼化データベースシステム。
【請求項１０】
同一データに複数の処理要求が同時にアクセスを試みた場合一つの処理要求のみを実行しその他は待たせる機能を有する複数のデータベースサーバと、クライアントコンピュータからの処理要求を一つ以上のデータベースサーバに中継するとともに前記データベースサーバからの正当な応答の一つをクライアントコンピュータに処理結果として返す仲介装置とを備えた高信頼化データベースシステムにおける仲介方法であって、
前記複数のデータベースサーバのうち一つをｌｅａｄｅｒとし残りをｆｏｌｌｏｗｅｒとしてあらかじめ選定しておき、クライアントコンピュータから処理要求を受信した時、該処理要求をｌｅａｄｅｒのみに送信し、ｌｅａｄｅｒから該処理要求に対する応答を受信したらｆｏｌｌｏｗｅｒへ該処理要求を送信する
ことを特徴とする仲介方法。
【請求項１１】
同一データに複数の処理要求が同時にアクセスを試みた場合一つの処理要求のみを実行しその他は待たせる機能を有する複数のデータベースサーバと、クライアントコンピュータからの処理要求を一つ以上のデータベースサーバに中継するとともに前記データベースサーバからの正当な応答の一つをクライアントコンピュータに処理結果として返す仲介装置とを備えた高信頼化データベースシステムにおける仲介装置であって、
前記複数のデータベースサーバのうち一つをｌｅａｄｅｒとし残りをｆｏｌｌｏｗｅｒとしてあらかじめ選定しておき、クライアントコンピュータから処理要求を受信した時、該処理要求をｌｅａｄｅｒのみに送信し、ｌｅａｄｅｒから該処理要求に対する応答を受信したらｆｏｌｌｏｗｅｒへ該処理要求を送信する制御部を備えた
ことを特徴とする仲介装置。
【請求項１２】
同一データに複数の処理要求が同時にアクセスを試みた場合一つの処理要求のみを実行しその他は待たせる機能を有する複数のデータベースサーバと、クライアントコンピュータからの処理要求を一つ以上のデータベースサーバに中継するとともに前記データベースサーバからの正当な応答の一つをクライアントコンピュータに処理結果として返す仲介装置とを備えた高信頼化データベースシステムにおける仲介装置を実現するプログラムであって、
コンピュータを、前記複数のデータベースサーバのうち１つをｌｅａｄｅｒとし残りをｆｏｌｌｏｗｅｒとしてあらかじめ選定しておき、クライアントコンピュータから処理要求を受信した時、該処理要求をｌｅａｄｅｒのみに送信し、ｌｅａｄｅｒから該処理要求に対する応答を受信したらｆｏｌｌｏｗｅｒへ該処理要求を送信する制御部として機能させる
ことを特徴とする仲介プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】本発明は、複数のデータベースサーバを平行動作させる高信頼化データベースシステムに関し、特に各サーバ間の同期技術に関する。
【背景技術】
【０００２】第一の従来の高信頼化データベースシステムは例えば特許文献１に記載されたものが知られている。このシステムは図２１に示すように、複数のデータベースサーバ（以下「サーバ」と言う）と、クライアントコンピュータ（以下「クライアント」と言う）からの処理要求を各サーバに中継するとともに各サーバからの正当な応答の１つをクライアントに処理結果として返す仲介装置とを備えている。【０００３】複数の更新クエリを実行した結果、サーバ間で同期が崩れることがある。それは、同一データアイテムに対する更新の順序が全てのサーバで同一でなかったことが原因である。仲介装置が同期崩れを検出した場合は、同期から外れたサーバ（以下「同期外れサーバ」という）をシステムから一旦切り離しそのサーバのデータを全て捨てる。仲介装置は正常稼動しているサーバ（以下「正常サーバ」という）からある時点のバックアップデータを作成し、その時点以降に正常サーバで実行される更新クエリを差分情報として保持しておく。仲介装置はバックアップデータを使って同期外れサーバのデータベースを復旧し、さらに差分情報を順に実行する。もし、全ての差分情報の実行結果が正常サーバの実行結果と同じならば同期外れサーバは再び同期状態に戻ることができる。しかし、差分情報の実行結果が正常サーバの実行結果と異なる場合は、再び同期崩れが発生したので再度バックアップデータの作成からやり直す。【０００４】第二の従来の高信頼化データベースシステムは例えば非特許文献１に記載されたものが知られている。このシステムは図２２に示すように、複数のデータベースサーバ（以下「サーバ」と言う）と、クライアントコンピュータ（以下「クライアント」と言う）と、クライアントからのクエリをサーバへ渡しその応答をクライアントへ返すスケジューラと、いわゆる２相ロック（２ＰＬ）によって同期を維持するプロキシとから構成されている。【０００５】２ＰＬを実現するためにクライアントが実行するアプリケーションは、トランザクションの先頭で、アクセスを行う予定の全てのテーブルに対してＬＯＣＫ命令でロックを獲得しなければならない。また、トランザクションの最後で、更新が終わったテーブルに対してＵＮＬＯＣＫ命令でロックを開放しなければならない。このＬＯＣＫ命令とＵＮＬＯＣＫ命令はプロキシに対するものであってサーバには送信されない。スケジューラはＬＯＣＫ命令を受信すると一意の番号を割り当ててそのＬＯＣＫ命令とともにその番号をプロキシへ送る。プロキシは一つのテーブルに対して一つのクライアントのみにしかアクセスを許さない。つまり、一つのテーブルにつき一番小さい番号を持ったＬＯＣＫ命令のみに応答を返す。クライアントはＬＯＣＫ命令に対して応答が返ってきたことによってテーブルに対してロックが確保できたと理解し、サーバで実行させるクエリの送信を開始する。プロキシはＵＮＬＯＣＫ命令を受信した場合、ロックを開放し次に小さい番号を持ったＬＯＣＫ命令に許可を与える。つまり、ＬＯＣＫ命令に対して応答を返す。【０００６】以上より、複数のクライアントが同じテーブルをアクセスするトランザクションを同時に平行実行しようとしても、プロキシは一つのトランザクションだけにアクセスを許可するため、最大で一つの更新のみしか実行されない。従って、複数の更新が平行に同時実行されなければ複数の更新の順序の入れ代わりが起きようがないので全てのサーバは同期を維持し続ける。
【特許文献１】特開２００７−２４１３２５号公報
【非特許文献１】「Ｃｏｎｆｌｉｃｔ−ａｗａｒｅ  Ｓｃｈｅｄｕｌｉｎｇ  ｆｏｒ  Ｄｙｎａｍｉｃ  Ｃｏｎｔｅｎｔ  Ａｐｐｌｉｃａｔｉｏｎｓ」、ＵＳＥＮＩＸ２００３
【発明の開示】
【発明が解決しようとする課題】
【０００７】しかしながら、上述の第一の従来技術は、複数のデータベースサーバ間の同期が崩れたことを検出して再び同期状態に戻す（以下「再同期処理」という）方法であって、複数のデータベースサーバ間の同期を維持する（同期が崩れないようにする）方法ではない。再同期処理は完了までに時間がかかること、その間同期外れサーバは正常サーバのバックアップになっておらずシステムの信頼性が落ちること、バックアップデータの作成中は正常サーバの負荷が重くなりクライアントへのサービスが滞るまたはバックアップデータの作成が完了するまでクライアントに対するサービスは停止しなければならないこと、再同期処理が失敗する事がありもし失敗したら最初からやり直さなければならないこと、何度やり直しても失敗し無限に再同期処理が繰り返される可能性があること、障害発生と同期崩れの区別がつかないので障害発生時に無駄な再同期処理が動作してしまうこと（障害から復旧するためには再同期処理は意味無い）、などの問題が生じる。サーバ間で同期が崩れるのはライトコンフリクト（複数のクライアントから発行された更新クエリが同一データアイテムを同時に更新しようと試みること）時に発生する。以下に具体例を示す。【０００８】図２３にｔｅｓｔ＿ｔａｂｌｅという名前のテーブルに対して、図２４に示すトランザクションＴ１とＴ２が平行実行される場合を示す。Ｔ１はｉｄ＝１の行を更新し、Ｔ２はｉｄ＝１と２の行を更新する。つまり、ｉｄ＝１でライトコンフリクトする。どちらのトランザクションが先にｉｄ＝１のロックを獲得するかによって最終結果は異なってしまう。【０００９】ロックを取る順序は、Ｔ１が先に取る場合とＴ２が先に取る場合の２通りが考えられる。例えばＴ１とＴ２が並行実行されていてトランザクション隔離レベルとしてＳＥＲＩＡＬＩＺＡＢＬＥである時、Ｔ１が先にロックを取ったならばｉｄ＝１の最終結果はｄｅｐ＝１となり（Ｔ２はＳＥＲＩＡＬＩＺＡＢＬＥ失敗でＴ２のＵＰＤＡＴＥは無効）、Ｔ２が先にロックを取ったならばｄｅｐ＝２となる（Ｔ１はＳＥＲＩＡＬＡＢＬＥ失敗でＴ１のＵＰＤＡＴＥは無効）。【００１０】従って、複数のサーバでＴ１とＴ２を平行実行した時、あるサーバはＴ１が先にロックを獲得し、別のサーバはＴ２が先にロックを獲得したならば二つのデータベースは同期状態（同じデータを保持している状態）が崩れてしまい、前記問題を持った再同期化処理が実行されてしまう。【００１１】また、この従来技術は同期が崩れていないのにも係わらず異なった応答を返すという問題もある。図２３に示すｔｅｓｔ＿ｔａｂｌｅに対して図２５に示すトランザクションＴ３とＴ４が平行実行される場合を示す。Ｔ３のＣＯＭＭＩＴとＴ４のＳＥＬＥＣＴの実行のタイミングによってはＳＥＬＥＣＴの結果が変わってしまう。【００１２】あるサーバではＴ３のＣＯＭＭＩＴが実行される前にＴ４のＳＥＬＥＣＴが実行されたとすると、ＳＥＬＥＣＴの結果はｄｅｐ＝３となる。これに対して、別のサーバではＴ３のＣＯＭＭＩＴが実行された後にＴ４のＳＥＬＥＣＴが実行されたとすると、ｄｅｐ＝１となる。仲介装置で結果の比較や多数決で障害検出を行っている場合、同期が崩れている訳でもなく障害起きている訳でもなく正常状態なのに異常が起きたと誤認してしまう問題が発生する。【００１３】さらに、上述の第二の従来技術は、複数のデータベースサーバ間の同期を維持するためにアクセスできるトランザクションを一つだけに限定している。従って、平行実行したらライトコンフリクトする更新クエリを一つずつシーケンシャルに実行することによってライトコンフリクトを防ぐことで同期を維持する。しなしながら、ライトコンフリクトするかどうかはサーバで実行してみないと分からない（例えば図２４のＴ１とＴ２を見比べただけではライトコンフリクトするかどうかは分からない）ので、ライトコンフリクトしない更新クエリも一つずつシーケンシャルに実行しなければならない。従って、スループットが低下してしまうという問題がある。また、このシステムだけの固有の命令である、ＬＯＣＫ命令とＵＮＬＯＣＫ命令を記述する必要であり、既存のアプリケーションを流用できないという問題もある。以下に具体例を示す。【００１４】図２３のｔｅｓｔ＿ｔａｂｌｅに対して、図２６に示すトランザクションＴ５とＴ６が平行実行される場合を示す。Ｔ５はｉｄ＝４の行を更新し、Ｔ６はｉｄ＝５の行を更新するため、本来は平行実行可能であるにも係わらず、本従来技術ではそれができないことを示す。まずは、プロキシが２ＰＬを実現可能にするために図２６のＴ５とＴ６はそれぞれ図２７のＴ５０とＴ６０へ改造しなければならない。【００１５】スケジューラは二つのＬＯＣＫ命令のうちＴ５０のＬＯＣＫ命令を先に受信したとする。スケジューラは一意の番号を与えプロキシへ転送する。ｔｅｓｔ＿ｔａｂｌｅのロックを保持しているトランザクションが無いので、プロキシはＴ５０にロックを与えてその旨をスケジューラ経由でクライアントへ返答する。遅れてスケジューラに到着したＴ６０のＬＯＣＫ命令は別の番号を与えてプロキシへ転送する。ｔｅｓｔ＿ｔａｂｌｅのロックは空いていないため、このＬＯＣＫ命令はプロキシが保持する。Ｔ６０を実行中のクライアントはプロキシから返答がないため、次のクエリを実行できないまま返答を待つ。【００１６】返答をもらったＴ５０を実行中のクライアントはＵＰＤＡＴＥ、ＳＥＬＥＣＴを順に送信し、最後にＵＮＬＯＣＫ命令を送信する。プロキシはこのＵＮＬＯＣＫ命令を受け取ってＴ５０に対するロックを開放し次に小さい番号を持つトランザクションにロックを渡す。今、Ｔ６０しか待っているトランザクションが無いためＴ６０にロックを渡しクライアントへ返答する。【００１７】返答をもらったＴ６０を実行中のクライアントはここでやっと次のＵＰＤＡＴＥを送信できるようになる。【００１８】つまり、更新クエリを一つずつシーケンシャルに実行させることで更新の入れ替わりを無くし同期を維持する。しかし、Ｔ５０とＴ６０のようにライトコンフリクトせず本来平行に実行できる更新クエリも平行実行できないため性能が低下してしまうという問題がある。またＵＰＤＡＴＥが実行できないためにＵＰＤＡＴＥに続くクエリ（例えばＴ５０、Ｔ６０の場合はＳＥＬＥＣＴクエリ）も平行実行できず、ますます性能低下は無視できない問題である。さらに、サーバは改造せず既存のものを流用できるが、クライアントアプリケーションは改造しなければならないという問題もある。【００１９】本発明は、上記事情に鑑みてなされたものであり、その目的とするところは、複数の更新クエリを平行実行し性能低下を防ぐと同時にデータベースサーバ間で常に同期を維持し続ける高信頼化データベースシステムにおける同期維持方法を提供することにある。また、クライアントへのサービス停止時間を極力抑えて同期から外れたデータベースサーバを正常稼動中のデータベースサーバに同期させる同期化方法を提供することにある。本発明は、既存のデータベースサーバもアプリケーションも改造せずに流用できるため、低コストで実用的である。
【課題を解決するための手段】
【００２０】上記目的を達成するために、本願発明では、同一データに複数の処理要求が同時にアクセスを試みた場合一つの処理要求のみを実行しその他は待たせる機能を有する複数のデータベースサーバと、クライアントコンピュータからの処理要求を一つ以上のデータベースサーバに中継するとともに前記データベースサーバからの正当な応答の一つをクライアントコンピュータに処理結果として返す仲介装置とを備えた高信頼化データベースシステムにおいて、仲介装置は、前記複数のデータベースサーバのうち一つをｌｅａｄｅｒとし残りをｆｏｌｌｏｗｅｒとしてあらかじめ選定しておき、クライアントコンピュータから処理要求を受信した時、該処理要求をｌｅａｄｅｒのみに送信し、ｌｅａｄｅｒから該処理要求に対する応答を受信したらｆｏｌｌｏｗｅｒへ該処理要求を送信する制御部を備える。【００２１】このようなシステムによれば、複数の更新クエリを平行実行し性能低下を防ぐと同時にデータベースサーバ間で常に同期を維持し続けることができる。【００２２】また、本願発明では、クライアントコンピュータからの処理要求を差分情報として記憶する差分情報記憶部を備え、同期から外れているデータベースサーバ（以降「同期外れデータベースサーバ」と言う）の同期化要求があると、正常稼働中のデータベースサーバからバックアップデータの作成を開始し、クライアントコンピュータから受信する処理要求を差分情報記憶部にｌｅａｄｅｒからの応答を受信した順序で記憶し、バックアップデータの作成を完了すると該バックアップデータを用いて同期外れデータベースサーバを復元させ、同期外れデータベースサーバにおいて前記バックアップデータからのデータベースの復元が完了すると、差分情報記憶部に記憶されている処理要求を同期外れデータベースサーバに順次送出する。【００２３】このようなシステムによれば、クライアントへのサービス停止時間を極力抑えて同期外れデータベースサーバを正常稼動中のデータベースサーバに同期させることができる。また、差分情報記憶部に記憶されている処理要求を実行中にｌｅａｄｅｒと実行順序が異なり同期化が失敗することは無い。【００２４】さらに、本願発明では、既存のデータベースサーバもアプリケーションも改造せずに流用できるため、低コストで実用的である。
【発明の効果】
【００２５】  以上説明したように本発明によれば、複数の更新クエリを平行実行し性能低下を防ぐと同時にデータベースサーバ間で常に同期を維持し続ける高信頼化データベースシステムにおける同期方法を提供することにある。また、クライアントへのサービス停止時間を極力抑えて同期から外れたデータベースサーバを正常稼動中のデータベースサーバに同期させる同期方法を提供することにある。本発明は、既存のデータベースサーバもアプリケーションも改造せずに流用できるため、低コストで実用的である。
【発明を実施するための最良の形態】
【００２６】（第１の実施の形態）
本発明の第１の実施の形態に係る高信頼化データベースシステムについて図面を参照して説明する。図１は本実施の形態に係る高信頼化データベースシステムの全体構成を説明するブロック図である。【００２７】  この高信頼化データベースシステムは、図１に示すように、複数のデータベースサーバ（以下「サーバ」と言う）１０と仲介装置２０とをネットワーク３０で接続したものであり、ネットワーク４０を介して１以上のクライアントコンピュータ（以下「クライアント」と言う）５０からアクセスされるものである。本実施の形態では、図１に示すように、２台のサーバ１０ａ及び１０ｂを有しており、２台のクライアント５０ｍ及び５０ｎからアクセスされる。以降の説明において各サーバ１０を他のサーバ１０と区別する場合は添え字「ａ」「ｂ」を付加する。クライアント５０についても「ｍ」「ｎ」を付加する。本発明ではサーバもクライアントも本発明のために改造する必要はなく、既存のものを無改造で使用することができる。【００２８】複数のサーバのうち一つをｌｅａｄｅｒとして選定し残りをｆｏｌｌｏｗｅｒとする。ｌｅａｄｅｒはどのサーバを選んでも良い。本実施例では１０ａをｌｅａｄｅｒとして１０ｂをｆｏｌｌｏｗｅｒとする。サーバ１０は、ＳＱＬを介して処理を行うＲＤＢＭＳである。このようなサーバ１０としては様々なものがあり、例えばオープンソースソフトウェアのＰｏｓｔｇｒｅＳＱＬ（ｈｔｔｐ：／／ｗｗｗ．ｐｏｓｔｇｒｅｓ．ｏｒｇ／）やＯｒａｃｌｅ社によるＯｒａｃｌｅ（登録商標）（ｈｔｔｐ：／／ｗｗｗ．ｏｒａｃｌｅ．ｃｏｍ）などが挙げられる。【００２９】サーバはライトコンフリクト（複数のクライアントから発行された更新クエリが同一データアイテムを同時に更新しようと試みること）時には一つの更新クエリのみの実行を許しそれ以外の更新クエリはブロックされる動作を行うものを使う。具体例を図２に示す。図２はクライアント５０ｍと５０ｎがそれぞれ図２４のトランザクションＴ１とＴ２を図２３のテーブルｔｅｓｔ＿ｔａｂｌｅに対して実行している例である。Ｔ１とＴ２のＵＰＤＡＴＥはｉｄ＝１でライトコンフリクトする。【００３０】クライアント７０１ｎがＢＥＧＩＮを送信し（ステップＳ７００）、サーバ７００がそれを実行して応答を返す（ステップＳ７０１）。クライアント７０１ｍもＢＥＧＩＮを送信し（ステップＳ７０２）、サーバ７００がそれを実行して応答を返す（ステップＳ７０３）。クライアント７０１ｎとクライアント７０１ｍはほぼ同時にＵＰＤＡＴＥをサーバ７００へ送信する（ステップＳ７０４、Ｓ７０５）。二つのＵＰＤＡＴＥはライトコンフリクトするので一つしか実行されず残りはブロックされる。図２の場合、クライアント７０１ｎによって実行中のトランザクションＴ２がｉｄ＝１のロックを確保してＵＰＤＡＴＥの応答がクライアント７０１ｎへ返された（ステップＳ７０６）が、クライアント７０１ｍのトランザクションＴ１はロックが確保できずにブロックされＵＰＤＡＴＥの応答は返らない。ロックを開放するタイミングはロックを確保しているトランザクションＴ２がＣＯＭＭＩＴまたはＡＢＯＲＴでトランザクションが終了した時である。図２の場合、クライアント���０１ｎがＣＯＭＭＩＴをサーバ７００に送信し（ステップＳ７０７）、サーバ７００がそれを実行する事でｉｄ＝１のロックを開放する。従って、サーバ７００はＣＯＭＭＩＴに対する応答をクライアント７０１ｎへ返す（ステップＳ７０８）のに加えて、ブロックされていたＵＰＤＡＴＥを実行しその結果をクライアント７０１ｍへ返す（ステップＳ７０９）。【００３１】サーバはいくつかのトランザクション隔離レベルを実装している。その中で、データの一貫性について最も厳密なものがＳＥＲＩＡＬＩＺＡＢＬＥである。ＳＥＲＩＡＬＩＺＡＢＬＥはｓｎａｐｓｈｏｔ  ｉｓｏｌａｔｉｏｎの一種である。【００３２】ｓｎａｐｓｈｏｔ  ｉｓｏｌａｔｉｏｎで動作するトランザクションは、トランザクションがスタートした時点でデータベース全体のコピーであるスナップショットを作成する。このスナップショットにはＣＯＭＭＩＴされた他のトランザクションの変更は含まれるが、ＣＯＭＭＩＴされていないトランザクションの変更は含まれていない。トランザクション内の全てのクエリの実行はこのスナップショットに対して行われる。トランザクションがＣＯＭＭＩＴすると、スナップショットへの変更はデータベース本体へ反映される。ライトコンフリクトが起きた場合は一つだけが成功しＣＯＭＭＩＴできる。図３を使って具体例を示す。【００３３】図３は右へ行くほど時間が経過することを表す。四つのトランザクションＴ１０、Ｔ１１、Ｔ１２、Ｔ１３がある。Ｂ、Ｓ、Ｃ、ＡはそれぞれＢＥＧＩＮの実行、スナップショットの取得、ＣＯＭＭＩＴの実行、ＡＢＯＲＴの実行を表す。「ｉｄ＝１」とは更新した対象を表す。トランザクションＴ１１が取得したスナップショットにはトランザクションＴ１０の更新は含まれていない（なぜならばスナップショット取得時点でＣＯＭＭＩＴしていない）。Ｔ１０とＴ１１は同じｉｄ＝１を更新するためライトコンフリクトする。Ｔ１０がＣＯＭＭＩＴすると、他のライトコンフリクトするトランザクションは失敗するためＴ１１はＡＢＯＲＴする。トランザクションＴ１２はトランザクションＴ１０の更新もＴ１１の更新も含まれていない。更新対象が異なるためＴ１２はライトコンフリクトせず、ＣＯＭＭＩＴできる。トランザクションＴ１３のスナップショットにはトランザクションＴ１０の更新もＴ１２の更新も含まれている。ｉｄ＝１を更新するがライトコンフリクトしないため（なぜならば、Ｔ１０やＴ１１と平行に実行していない）、ＣＯＭＭＩＴできる。【００３４】本実施例では、ＳＥＲＩＡＬＩＺＡＢＬＥで動作するＰｏｓｔｇｒｅＳＱＬを具体的に説明する。【００３５】仲介装置２０がネットワーク４０側に公開しているアドレスがクライアント５０にとっての仮想的なデータベースサーバである。つまり、クライアントは仲介装置２０がデータベースサーバそのものだとみなして処理を行えばよい。これは、サーバ１０が何台稼動していようと、障害でダウンしているサーバがあろうと、障害から復旧して再びシステムに組み込まれようと、どのようなシステムであってもクライアント５０は意識することなく（設定など変更することなく）仲介装置２０と通信を行う事ができる。【００３６】仲介装置２０は後述する同期維持アルゴリズムに従ってクライアントから受け取ったクエリをサーバ１０へ送信し正常な応答の一つをクライアントへ返すものである。【００３７】クライアント５０はデータベースシステムに対してクエリを送信するものである。【００３８】次に、同期維持アルゴリズムについて説明する。本アルゴリズムは次の二点の特徴を持ったデータベースシステムを前提とする。
（ａ）クライアントは、既に送信したクエリに対する応答を受信してから新たなクエリを送信する。
（ｂ）ライトコンフリクトした場合はロックを獲得できたトランザクションの更新クエリのみが実行可能でありロックを獲得できなかったトランザクションの更新クエリはロックを取得するまでブロックされる。【００３９】ここで更新クエリにはＵＰＤＡＴＥ，ＤＥＬＥＴＥなどデータアイテムを更新する際に行ロックを必要とするクエリの他に、これらのクエリの動作に影響を与えるクエリも更新クエリとして扱う。例えば、ＳＥＬＥＣＴ  ＦＯＲ  ＵＰＤＡＴＥはその実行にデータアイテムの更新を伴わないが、その実行に行ロックを必要としＵＰＤＡＴＥやＤＥＬＥＴＥと同時に実行した場合には行ロックの競合が発生するため、更新クエリとして扱う。【００４０】全てのサーバで同期を維持するためには、同一データアイテムに対する更新の順序が全てのサーバで同一になることを保障する必要がある。この順序保障は、異なるトランザクションに属する更新クエリ同士だけでなく、同一トランザクション内の更新クエリ同士も保障する必要がある。上記二つの条件を持ったデータベースシステムでサーバ／クライアント間のクエリを次の三つのルールで制御することで順序保障を実現し同期を維持する。
（１）仲介装置２０はクライアント５０から受信した全ての更新クエリをｌｅａｄｅｒのみに送信する。ｌｅａｄｅｒへの送信順序は任意である。
（２）仲介装置２０は更新クエリの応答をｌｅａｄｅｒから受信したら、更新クエリを全てのｆｏｌｌｏｗｅｒへ送信する。
（３）仲介装置２０は全てのデータベースサーバから応答を受信したらクライアントへ応答を返す。【００４１】（ａ）と（３）で同一トランザクションに属する更新クエリ同士の順序の一意性を保障し、（ｂ）と（１）（２）で異なるトランザクションに属する更新クエリ同士の順序の一意性を保障する。更新クエリ以外のクエリはｌｅａｄｅｒ、ｆｏｌｌｏｗｅｒの区別無く全てのサーバへ送信する。【００４２】仲介装置２０は、図４に示すように、クライアント５０からの接続要求を受け付けて実際にクライアントと接続し空いている制御部２２へ接続情報を渡す接続処理部２１と、全てのサーバ１０と接続をした後上記アルゴリズムに従ってクエリと応答の送受信を制御する制御部２２とを備えている。本実施の形態では、三つの制御部２２ｘ、２２ｙ、２２ｚを有している。以降の説明において各制御部２２を他の制御部２２と区別する場合は添え字「ｘ」「ｙ」「ｚ」を付加する。【００４３】次に、図５から図９のフローチャートを参照して制御部２２の動作について説明する。制御部２２はクエリをクライアント５０から受信すると（ステップＳ１）、スナップショットの作成が済んでいるかどうかを確認する（ステップＳ２）。【００４４】スナップショットが作成されていない場合（ステップＳ２）、クエリはスナップショットを作成するクエリかどうかを確認する（ステップＳ３）。スナップショットを作成するクエリはトランザクションの最初に現れるデータアイテムにアクセスするクエリである。つまり、例えば図２４のトランザクションＴ１の場合、ＢＥＧＩＮではなくＳＥＬＥＣＴである。ステップＳ３でスナップショットを作成するクエリであった場合はスナップショット作成ルーチンを実行し（ステップＳ４）再びクライアント５０からクエリを受信する（ステップＳ１）。ステップＳ３でスナップショットを作成するクエリでない場合は通常ルーチンを実行し（ステップＳ５）再びクライアント５０からクエリを受信する（ステップＳ１）。【００４５】前記Ｓ２で既にスナップショットが作成済みの場合、更新クエリかどうかをチェックし（ステップＳ６）、更新クエリならば同期維持ルーチン（ステップＳ７）を実行し再びクライアント５０からクエリを受信する（ステップＳ１）。前記ステップＳ６で更新クエリでない場合、コミットクエリかどうかをチェックし（ステップＳ８）、コミットクエリの場合はコミット処理ルーチンを実行し（ステップＳ９）再びクライアント５０からクエリを受信する（ステップＳ１）。前記Ｓ８でコミットクエリでない場合、通常ルーチンＳ５を実行し再びクライアント５０からクエリを受信する（ステップＳ１）。【００４６】図６のフローチャートを参照して通常ルーチンを説明する。全てのサーバ１０へそのクエリを送信し（ステップＳ１０）、全てのサーバ１０から応答を受信する（ステップＳ１１）。多数決で正当な応答を判定し（ステップＳ１２）正当な応答の一つをクライアント５０へ送信する（ステップ１３）。【００４７】図７のフローチャートを参照してスナップショット作成ルーチンを説明する。スナップショットの作成とコミットの実行は排他制御しなければならない。そのためにコミットカウンタとスナップショット作成カウンタを用いる。コミットカウンタが１以上の場合、コミット実行中のトランザクションが存在することを意味する。同様に、スナップショット作成カウンタが１以上の場合、スナップショット作成中のトランザクションが存在することを意味する。両方が１以上にならないように制御することで、スナップショット作成中のトランザクションとコミット実行中のトランザクション両方が存在しないことを保証する。これらのカウンタの読み書きには共通のロック（例えばｐｔｈｒｅａｄ＿ｌｏｃｋ）を使う。【００４８】コミットカウンタが０でない場合（ステップＳ２０）、コミット実行中のトランザクションが存在するのでスリープする（ステップＳ２１）。ｗａｋｅ  ｕｐすると再びコミットカウンタが０かどうかチェックする（ステップＳ２０）。コミットカウンタが０の場合、コミット実行中のトランザクションがないことを意味するのでスナップショット作成中であることを表すためにスナップショット作成カウンタを１増やし（ステップＳ２２）スナップショットの作成に入る。スナップショット作成は有効なクエリを実行する事で実現されるが更新クエリの場合はスナップショットの作成と同時に同期を維持しなければならない。すなわち、更新クエリかどうかをチェックし（ステップＳ２３）、更新クエリでない場合は通常ルーチンを実行し（ステップＳ５）、更新クエリの場合は同期維持ルーチンを実行する（ステップＳ７）。いずれのルーチンを実行してもスナップショット作成は完了するから、その旨を表すためにスナップショット作成カウンタを１減らす（ステップＳ２４）。スナップショット作成カウンタが０ならば（ステップＳ２５）、スナップショット作成カウンタが０になるのを待っている制御部２３をｗａｋｅ  ｕｐさせる（ステップＳ２６）。【００４９】図８のフローチャートを参照して同期維持ルーチンを説明する。サーバ１０のうちｌｅａｄｅｒのみにクエリを送信する（ステップＳ３０）。ｌｅａｄｅｒから応答を受信したら（ステップＳ３１）、全てのｆｏｌｌｏｗｅｒへクエリを送信する（ステップＳ３２）。全てのｆｏｌｌｏｗｅｒから応答を受信したら（ステップＳ３３）、多数決で正しい応答を判定し（ステップＳ３４）正しい応答の一つをクライアント５０へ返す（ステップＳ３５）。【００５０】図９のフローチャートを参照してコミット処理ルーチンを説明する。前述のように、スナップショットの作成とコミットの実行は排他制御する。【００５１】スナップショット作成カウンタが０でない場合（ステップＳ４０）、スナップショット作成中のトランザクションが存在するのでスリープする（ステップＳ４１）。ｗａｋｅ  ｕｐすると再びスナップショット作成カウンタが０かどうかチェックする（ステップ４０）。スナップショット作成カウンタが０の場合、スナップショット作成中のトランザクションがないことを意味するのでコミット実行中であることを表すためにコミットカウンタを１増やし（ステップ４２）通常ルーチンを使ってコミットの実行に入る。コミット実行が終わったらその旨を表すためにコミットカウンタを１減らす（ステップ４３）。コミットカウンタが０ならば（ステップＳ４４）、コミットカウンタが０になるのを待っている制御部２３をｗａｋｅ  ｕｐさせる（ステップＳ４５）。【００５２】次に図１０のシーケンス図を参照してライトコンフリクトする更新クエリを含むトランザクションを実行しても同期が維持されることを説明する。つまり、ライトコンフリクトする更新クエリの実行順序がｌｅａｄｅｒとｆｏｌｌｏｗｅｒで必ず同一になることが保障されることを示す。クライアント５０ｍと５０ｎがそれぞれ図２４のトランザクションＴ１とＴ２を実行している場合を示す。仲介装置２０の接続処理部２１はクライアント５０ｍと５０ｎにそれぞれ制御部２２ｘと２２ｙを割り当てたとする。【００５３】クライアント５０ｍはＢＥＧＩＮクエリを送信し制御部２２ｘがこれを受信する（ステップ５０）。制御部２２ｘは全てのサーバ１０にクエリを送信し（ステップＳ５１、５２）、全てのサーバ１０から応答を受信して（ステップＳ５３，５４）、正当な応答の一つをクライアント５０ｍへ返す（ステップＳ５５）。クライアント５０ｎについても同様である（ステップＳ５６〜Ｓ６１）。【００５４】次にクライアント５０ｍと５０ｎはほぼ同時にライトコンフリクトするＵＰＤＡＴＥクエリを送信する（ステップＳ６２、Ｓ６３）。そのクエリを受け取った制御部２２ｘと２２ｙはそのクエリをｌｅａｄｅｒのみに送信する（ステップＳ６４、Ｓ６５）。ほぼ同時に受信したクエリのｌｅａｄｅｒでの実行順序は制御部２２が送信した順序と同じとは限らない。制御部２２とサーバ１０間の通信路で順序が入れ替わるかもしれないしサーバ１０のスケジューラで順序が変わることもある。この例の場合はクライアント５０ｍが実行するトランザクションＴ１が先にロックを確保し更新クエリが実行されたことを表しており、制御部２２ｘは応答を受け取る（ステップＳ６６）。一方、ロックを確保できなかったクライアント５０ｎのトランザクションＴ２はロックが確保できるまでブロックする。つまり、更新クエリは実行されずにｌｅａｄｅｒが保持する。【００５５】応答を受け取った制御部２２ｘは次にｆｏｌｌｏｗｅｒへ更新クエリを送信する（ステップＳ６７）。ｆｏｌｌｏｗｅｒから応答を受け取ると（ステップ６８）、制御部２２ｘは正当な応答の一つをクライアント５０ｍへ返す（ステップＳ６９）。【００５６】クライアント５０ｍはコミットクエリを送信し制御部２２ｘがこれを受信する（ステップＳ７０）。制御部２２ｘは全てのサーバ１０にクエリを送信し（ステップＳ７１、７２）、全てのサーバ１０から応答を受信して（ステップＳ７３、７４）、正当な応答の一つをクライアント５０ｍへ返す（ステップＳ７５）。【００５７】トランザクションＴ１のコミットが実行されるとＴ１が保持していたｉ＝１のライトロックは開放され、その開放を待っていたトランザクションＴ２がロックを確保しｌｅａｄｅｒで更新クエリが実行されその結果が制御部２２ｙへ返送される（ステップＳ７６）。制御部２２ｙはこのクエリをｆｏｌｌｏｗｅｒへも転送し（ステップＳ７７）、応答を受信する（ステップＳ７８）。制御部２２ｙはＵＰＤＡＴＥ失敗をクライアント５０ｎへ返す（ステップＳ７９）。【００５８】以上のようにして、ｌｅａｄｅｒに送信した更新クエリの応答を受信したらｆｏｌｌｏｗｅｒに���信するように制御することにより、ライトコンフリクトする更新クエリの実行順序を各サーバ１０で同一にすることができるので同期を維持することができる。【００５９】次に図１１と図１２のシーケンス図を参照してＳＥＬＥＣＴとＣＯＭＭＩＴの実行順序がサーバ毎に異なることなくＳＥＬＥＣＴの結果が一意になることを説明する。クライアント５０ｍと５０ｎがそれぞれ図２５のトランザクションＴ３とＴ４を実行している場合を示す。仲介装置２０の接続処理部２１はクライアント５０ｍと５０ｎにそれぞれ制御部２２ｘと２２ｙを割り当てたとする。【００６０】クライアント５０ｍはＢＥＧＩＮクエリを送信し、制御部２２ｘがこれを受信した後全てのサーバへ転送し応答を受け取ってクライアント５０ｍへ応答を返す（ステップＳ２００〜Ｓ２０５）。ＵＰＤＡＴＥもｌｅａｄｅｒ及びｆｏｌｌｏｗｅｒで実行されクライアント５０ｍに応答が返る（ステップＳ２０６〜Ｓ２１１）。クライアント５０ｎについても同様にＢＥＧＩＮを実行する（ステップＳ２１２〜Ｓ２１７）。【００６１】クライアント５０ｍはＣＯＭＭＩＴを送信し制御部２２ｘがこれを受け取り（ステップＳ２１８）、ほぼ同時にクライアント５０ｎはＳＥＬＥＣＴを送信し制御部２２ｙがこれを受け取る（ステップＳ２１９）。制御部２２ｘと２２ｙはそれぞれ図９のコミット処理ルーチンと図７のスナップショット作成ルーチンを実行し始めるが、図９のスナップショット作成カウンタのチェック（ステップＳ４０）とコミットカウンタの変更（ステップＳ４２）は、図７のコミットカウンタのチェック（ステップＳ２０）とスナップショットカウンタの変更（ステップＳ２２）と排他制御されているので、同時に実行されることは無い。【００６２】図１１の場合は制御部２２ｘが先にこのクリティカルリージョンを実行したとする。つまり、制御部２２ｘはスナップショット作成カウンタが０なので（ステップＳ４０）コミットカウンタを１に変更し（ステップＳ４２）、ＣＯＭＭＩＴを全てのサーバ１０へ送信する（ステップＳ２２０、２２１）。制御部２２ｙはコミットカウンタをチェックすると（ステップＳ２０）０ではないのでスリープする（ステップ２１）。【００６３】制御部２２ｘがＣＯＭＭＩＴ成功を受信すると（ステップＳ２２２，２２３）、コミットカウンタを０に変更する（ステップＳ４３）。コミットカウンタが０なので（ステップＳ４４）制御部２２ｙをｗａｋｅ  ｕｐし（ステップＳ４５）クライアント５０ｍへＣＯＭＭＩＴ成功を送信する（ステップＳ２２４）。【００６４】制御部２２ｙは再びコミットカウンタをチェックすると（ステップＳ２０）０なのでスナップショット作成カウンタを１に変更しＳＥＬＥＣＴを全てのサーバへ送信する（ステップＳ２２５、Ｓ２２６）。全てのサーバからＴ３の変更が反映されたｄｅｐ＝１を受信し（ステップＳ２２７、Ｓ２２８）、クライアント５０ｎへｄｅｐ＝１を返す（ステップＳ２２９）。【００６５】図１２は制御部２２ｙが先にクリティカルリージョンを実行した場合を説明する。なお、ステップＳ２００からステップＳ２１９までは図１１と同じなので説明を省略する。制御部２２ｙはコミットカウンタが０なので（ステップＳ２０）ス��ップショット作成カウンタを１に変更し（ステップＳ２２）、ＳＥＬＥＣＴを全てのサーバ１０へ送信する（ステップＳ２５０、２５１）。制御部２２ｘはスナップショット作成カウンタをチェックすると（ステップＳ４０）０ではないのでスリープする（ステップ４１）。【００６６】サーバ１０ａはトランザクションＴ３のＣＯＭＭＩＴが実行されていないので、ｄｅｐの値は古いままである。従って、制御部２２ｙはｄｅｐ＝３をサーバ１０ａから受信する（ステップＳ２５２）。制御部２２ｙはサーバ１０ｂからも同様にｄｅｐ＝３を受信する（ステップＳ２５３）。制御部２２ｙはクライアント５０ｎへｄｅｐ＝３を送信すると（ステップＳ２５４）、スナップショット作成カウンタを０にする（ステップＳ２４）。スナップショット作成カウンタが０なので（ステップＳ２５）、制御部２２ｘをｗａｋｅ  ｕｐする（ステップＳ２６）。【００６７】制御部２２ｘは再びスナップショット作成カウンタをチェックすると（ステップＳ４０）０なのでコミットカウンタを１に変更しＣＯＭＭＩＴを全てのサーバへ送信する（ステップＳ２５５、Ｓ２５６）。全てのサーバからＣＯＭＭＩＴ成功を受信し（ステップＳ２５７、Ｓ２５８）、クライアント５０ｍへＣＯＭＭＩＴ成功を返す（ステップＳ２５９）。【００６８】次に図１３のシーケンス図を参照してライトコンフリクトしない更新クエリを含むトランザクションを実行した場合、同期を維持しつつ更新クエリを平行に実行できることを説明する。クライアント５０ｍと５０ｎがそれぞれ図２６のトランザクションＴ５とＴ６を実行している場合を示す。仲介装置２０の接続処理部２１はクライアント５０ｍと５０ｎにそれぞれ制御部２２ｘと２２ｙを割り当てたとする。【００６９】クライアント５０ｍはＢＥＧＩＮクエリを送信し、制御部２２ｘがこれを受信した後全てのサーバへ転送し応答を受け取ってクライアント５０ｍへ応答を返す（ステップＳ１００〜Ｓ１０５）。クライアント５０ｎについても同様である（ステップＳ１０６〜Ｓ１１１）。【００７０】次にクライアント５０ｍと５０ｎはほぼ同時にライトコンフリクトしないＵＰＤＡＴＥクエリを送信する（ステップＳ１１２、Ｓ１１３）。そのクエリを受け取った制御部２２ｘと２２ｙはそのクエリをｌｅａｄｅｒのみに送信する（ステップＳ１１４、Ｓ１１５）。更新クエリそれぞれの更新対象行は異なるため、制御部２２ｘも２２ｙも応答を受け取る（ステップＳ１１６、Ｓ１１７）。制御部２２ｘと２２ｙはｆｏｌｌｏｗｅｒへもクエリを送信しその応答を受け取り（ステップＳ１１８〜Ｓ１２１）、クライアント５０へ応答を返す（ステップＳ１２２，１２３）。【００７１】以上のようにして、ｌｅａｄｅｒに送信した更新クエリの応答を受信したらｆｏｌｌｏｗｅｒに送信するように制御することにより、ライトコンフリクトする更新クエリの実行順序を各サーバ１０で同一にすることができるので同期を維持することができる。また、ライトコンフリクトを起こさない更新クエリは平行に実行できるので性能低下を招く事は無い。さらに、各サーバから返るＳＥＬＥＣＴの結果は一致するため、障害と誤判断することもない。さらに、既存のサーバとクライアントを無改造で利用できるため、低コストで実用的である。【００７２】（第２の実施の形態）
本発明の第２の実施の形態に係る高信頼化データベースシステムについて説明する。本実施の形態が第１の実施の形態と異なる点は、同期から外れているサーバを同期状態にする（以下「同期化処理」という）点である。同期から外れている理由は、障害などで動作が停止していた場合や、新たにサーバ１０を増設する場合などが挙げられる。他の構成・動作等については第１の実施の形態と同様なので、ここでは相違点のみを説明する。【００７３】ここでは、３台のサーバ１０ａ〜１０ｃのうちサーバ１０ｃが同期から外れている状態から該サーバ１０ｃを１０ａおよび１０ｂに同期化させる場合を説明する。【００７４】図４の仲介装置２０は図１４の仲介装置２３のように変更する。仲介装置２３は、仲介装置２０と同様に接続処理部２１と制御部２２を持つのに加えて、ある時点の正常サーバ（この場合、サーバ１０ａまたはサーバ１０ｂ）のバックアップデータを作るバックアップデータ作成部２４と、そのある時点以降にｌｅａｄｅｒが実行したクエリを保持するバッファ２５と、それらを管理する管理部２６とを備えている。【００７５】バックアップデータ作成部２４は、管理部２６の指示である時点の正常サーバのデータのバックアップを作成する。バッファ２５は、管理部２６の指示でｌｅａｄｅｒから応答を受け取った順序（ｆｏｌｌｏｗｅｒへ送信する順序に等しい）でクエリを保存する。管理部２６は同期化処理を開始する指示を受け取った場合、各部へ適切な指示を行う。初期状態ではバッファ２５は空である。【００７６】図１５に示すように、クライアント５０ｍはトランザクションを開始する（ステップＳ３００〜Ｓ３０５）。ここで管理部２６は同期化指示を受け取ると、クライアント５０からの新規接続は保留し新たなトランザクションを開始しないように接続処理部２１へ指示する（ステップＳ３０６）。同期化指示はシステム管理者が仲介装置に接続したキーボードから入力したり、図示していない管理端末からネットワークを通して入力したり、することで管理部２６へ送られる。管理部２６はすでに開始しているトランザクションの終了を待つ。具体的には、クライアント５０ｍがＵＰＤＡＴＥを実行し（ステップＳ３０７〜Ｓ３１２）、ＣＯＭＭＩＴを実行する（ステップＳ３１３〜Ｓ３１８）まで待つ。【００７７】サーバ１０で実行中のトランザクションがなくなったので管理部２６はバックアップデータ作成部２４に正常サーバのバックアップを取るように指示する（ステップＳ３１９）。指示を受けたバックアップデータ作成部２４は正常サーバ１０のうち一台を選んでバックアップデータを作成する。この例ではサーバ１０ｂのバックアップデータを作成する。バックアップデータを作成する方法は、例えばＰｏｓｔｇｒｅＳＱＬならばｐｇ＿ｄｕｍｐを使う。このツールはバックアップデータを作成中に新たな更新が実行されても、その更新はバックアップデータに反映されない特徴を持っている。【００７８】バックアップデータの取得開始を確認した管理部２６は、接続処理部２１に対してクライアント５０からの新規接続を再開するように指示する。接続処理部２１は５０ｎからの接続要求を処理し、制御部２２はＢＥＧＩＮを受け取る（ステップＳ３２０）。制御部２２はサーバ１０にＢＥＧＩＮを送信し（ステップＳ３２１、Ｓ３２２）、サーバ１０から応答を受け取る（ステップＳ３２３、Ｓ３２４）。応答を受け取ったことを契機に制御部２２はＢＥＧＩＮクエリをバッファ２５へ保存し（ステップＳ３２５）、応答をクライアント５０ｎへ返す（ステップＳ３２６）。ここでバッファ２５へ保存するタイミングはｌｅａｄｅｒから応答をもらった時点である。【００７９】次に図１６に示すようにクライアント５０ｎはＳＥＬＥＣＴを送信し（ステップＳ３２７）、制御部２２がこれをサーバへ転送し（Ｓ３２８、Ｓ３２９）サーバ１０から応答を受け取る（Ｓ３３０、Ｓ３３１）とバッファ２５へＳＥＬＥＣＴを保存し（ステップＳ３３２）クライアント５０ｎへ応答を返す（ステップＳ３３３）。【００８０】ここでバックアップデータの取得が完了したことをバックアップデータ作成部２４は管理部２６へ通知し（ステップＳ３３４）、それを受けた管理部２６はそのバックアップデータを使ってデータベースを構築するようにサーバ１０ｃへ指示する（ステップＳ３３５）。サーバ１０ｃはｐｓｑｌなどを使ってデータベース構築を開始する（ステップＳ３３６）。【００８１】クライアント５０ｎはＵＰＤＡＴＥを送信した（ステップＳ３３７）。制御部２２はｌｅａｄｅｒであるサーバ１０ａへＵＰＤＡＴＥを送信し（ステップＳ３３８）、サーバ１０ａから応答を受信する（ステップＳ３３９）。この時点で制御部２２はＵＰＤＡＴＥをバッファ２５へ保存する（ステップＳ３４０）。ｌｅａｄｅｒから応答を受け取った順序でバッファに蓄積する理由は、サーバ１０ｃをｆｏｌｌｏｗｅｒとしてクエリを実行することでｌｅａｄｅｒに同期させるためである。【００８２】制御部２２はｆｏｌｌｏｗｅｒであるサーバ１０ｂへＵＰＤＡＴＥを送信し（ステップＳ３４１）、サーバ１０ｂから応答を受信して（ステップＳ３４２）、クライアント５０ｎへ応答を返す（ステップＳ３４３）。【００８３】ここでサーバ１０ｃのデータベース構築が完了し（ステップＳ３４４）、管理部２６はそれを知る（ステップＳ３４５）。ただし、サーバ１０ｃはステップＳ３１８までが反映された１０ａおよび１０ｂのデータベースに復旧したのであって、現在の１０ａおよび１０ｂに同期した状態ではない。同期した状態にするためにはステップＳ３２０以降のクエリを実行する必要がある。それらのクエリはバッファ２５に保存してある。【００８４】制御部２２はバッファの先頭から順にクエリを実行する。バッファに保存されている順序はｆｏｌｌｏｗｅｒが実行すべき順序で保存されているので、この順序でサーバ１０ｃへ送信し実行すれば必ずサーバ１０ａ及び１０ｂと同期する。管理部２６は制御部２２に対してバッファ内のクエリの実行を指示する（ステップＳ３４６）。制御部２２はバッファ２５の先頭から順にクエリを実行する（ステップＳ３４７〜ステップＳ３５２）。バッファ２５内が空になったらサーバ１０ｃはサーバ１０ａおよび１０ｂと同期したのでシステムに追加する。【００８５】以上のようにして、第１の実施の形態を応用してサービス停止時間を極力無くして同期から外れたサーバをｌｅａｄｅｒに同期させることができる。つまり、バックアップデータを使ってある時点まで復旧したサーバ１０にある時点以降のクエリを実行することによってｌｅａｄｅｒに同期化することができる。ここである時点以降のクエリはｆｏｌｌｏｗｅｒの実行を再現するので、同期化に失敗することなくｌｅａｄｅｒに同期化できる。他の効果については第１の実施の形態と同様である。【００８６】なお、本実施形態では、バッファ２５には全てのクエリを蓄積したが、データベースの状態を変えるクエリのみを蓄積しても良い。例えば、単純なデータのリードなどはデータベースの状態を変えないのでバッファ２５への蓄積を省略しても良い。ただし、単純なリードであっても、トランザクションの最初の有効なクエリであってスナップショットを作成するトリガになっている場合省略はできない。このような工夫で、バッファ２５を節約することができる。【００８７】また、本実施の形態では、同期化指示を受け取った後、実行中のトランザクションが無い状態を作り出してからバックアップデータの作成を開始したが、同期化指示を受け取る前からあらかじめクエリの保存をしておけば、同期化指示を受け取った直後にバックアップデータの作成が開始できる。【００８８】例えば、図１５において、ＢＥＧＩＮクエリ（ステップＳ３００）をあらかじめバッファに保存してあれば、同期化指示を受け取った時点（ステップＳ３０６）でバックアップデータを作成できる。なぜならば、このバックアップデータにはコミットされていないステップＳ３００から始まるトランザクションは含まれていないので、そのトランザクションのクエリがバッファに保存されていれば良い。【００８９】あらかじめバッファに保存しておく一つの方法として、全てのクエリをバッファに保存しておく方法が考えられる。しかし、この方法ではどんどんバッファを食いつぶしてしまう。そこで、コミットされてデータベースに反映されたトランザクションのクエリはバッファから削除するようにすれば、バッファを食いつぶしてしまうことはない。【００９０】これらの工夫により、サービスの停止時間は全く無くすことができる。【００９１】（第３の実施の形態）
本発明の第３の実施の形態に係る高信頼化データベースシステムについて説明する。本実施の形態が第１の実施の形態と異なる点は、クエリの送信タイミングである。他の構成・動作等については第１の実施の形態と同様なので、ここでは相違点のみを説明する。【００９２】第１の実施の形態では多数決を行っているため（３）は必要な条件であった。しかし、（３）によってシステム全体の性能は最も性能が低いサーバに足を引っ張られる（最も遅い応答が返って来ないとクライアントへ応答が返らない）ことになり、性能を重視する場合はこれが欠点となる。そこで、多数決ではなく、ｌｅａｄｅｒからの応答が常に正しいとしてｌｅａｄｅｒから応答が返ったら即座にクライアントへ応答を返すことでこの欠点が解消できる。【００９３】ただし、第１の実施の形態では条件（ａ）と（３）によって同一トランザクション内の同一データを更新する更新クエリの順序を保障していた。上記改良を行うことで他の方法で同一トランザクション内の同一データを更新する更新クエリの順序の一意性を保障しなければならない。そこで、（ａ）と（３）は削除し（１）と（２）をそれぞれ以下の（Ｉ）と（ＩＩ）に変更する。【００９４】（Ｉ）仲介装置２０は、もし、クライアント５０から新しい更新クエリを受信した時、既にサーバ１０へ送信した別の古い更新クエリに対して応答を返していないサーバ１０が存在しかつそれらの更新クエリが同一トランザクションに属する場合、新しい更新クエリを仲介装置２０で保持する。そして、その応答を受信したら、新しい更新クエリをｌｅａｄｅｒのみに送信する。
（ＩＩ））仲介装置２０はその更新クエリの応答をｌｅａｄｅｒから受信したら、その更新クエリを全てのｆｏｌｌｏｗｅｒへ送信すると同時にその応答をクライアント５０へ返す。【００９５】なお、（Ｉ）におけるｌｅａｄｅｒへの送信中断は同一トランザクション内の更新クエリ同士が対象であることに注意したい。クライアント５０が複数のトランザクションを実行する場合があるが、トランザクションが異なれば（Ｉ）における送信中断はせずにトランザクションを平行実行して高性能化を実現する。【００９６】上記（Ｉ）（ＩＩ）のルールを満たすためには、図５の全体ルーチン、図７のスナップショット作成ルーチン、図９のコミット処理ルーチンは変わらないが、図６の通常ルーチンと図８の同期維持ルーチンはそれぞれ図１７と図１８に変わる。【００９７】図１７の通常処理ルーチンは多数決（ステップＳ１２）が無くなるだけである。正しい応答の一つをクライアント５０へ送信するステップＳ１３は、ｌｅａｄｅｒの応答を送信する。【００９８】図１８の同期維持ルーチンは、ｌｅａｄｅｒへ更新クエリを送信し（ステップＳ３０）、ｌｅａｄｅｒから応答を受信する（ステップＳ３１）までは同じだが、即座にｌｅａｄｅｒからの応答をクライアント５０へ送信し（ステップＳ３６）、先に送信した更新クエリがあるかどうかをチェックする（ステップＳ３７）。無い場合は全てのｆｏｌｌｏｗｅｒへ現在の更新クエリを送信し（ステップＳ３９）、ある場合は先に送信した更新クエリの応答を全て受信した（ステップＳ３８）後で、全てのｆｏｌｌｏｗｅｒへ現在の更新クエリを送信する（ステップＳ３９）。【００９９】また、ＳＥＬＥＣＴなどデータベースの状態を何も変更しないクエリの実行はいずれか一つのサーバで実行しても良い。これにより、負荷分散できるのでシステム全体の性能が向上する効果がある。具体的には、図１９に示すように、一つのサーバ１０へクエリを送信し（ステップＳ８０）、そのサーバ１０から応答を受信し（ステップＳ８１）、その応答をクライアント５０へ送信する（ステップＳ８２）。図１９の負荷分散ルーチンを使う場合は、図５の全体ルーチンを図２０のように変更する。【０１００】以上のようにして、システムの応答時間を短縮することができ、システム全体のスループットを上げることができる。また、負荷分散を導入することによって、さらにスループットを上げることができる。他の効果については第１の実施の形態と同様である。【０１０１】なお、本実施の形態は、第１の実施の形態の変形例として説明したが、第２の実施の形態において同様の変形を適用できることは言うまでもない。【０１０２】以上、本発明の実施の形態について詳述したが、上記実施の形態は例示的なものであり、本発明はこれに限定されるものではない。本発明の範囲は特許請求の範囲に示されており、この特許請求の範囲の意味に入る全ての変形例は本発明に含まれるものである。なお、以下の各変形例は適宜組み合わせて上記各実施の形態に適用できる。【０１０３】上記実施の形態では、トランザクション隔離レベルとしてＳＥＲＩＡＬＩＺＡＢＬＥについて説明してきたが、他のトランザクション隔離レベルでも良い。ＳＥＲＩＡＬＩＺＡＢＬＥは最初に一回スナップショットを作成したらそれ以降スナップショットを変更することはないが、例えば、ＲＥＡＤ  ＣＯＭＭＩＴＴＥＤの場合は、ＣＯＭＭＩＴが実行される毎にスナップショットを獲得し直すように変形すれば良い。【０１０４】また、ＳＥＲＩＡＬＩＺＡＢＬＥではリードは他のクエリとコンフリクトしないが、ライトとコンフリクトした場合、リードがライトをブロックするような、トランザクション隔離レベルでも良い。この場合、更新クエリだけでなくＳＥＬＥＣＴなど読み込みクエリも更新クエリとして扱い上記同期維持アルゴリズムで実行すれば良い。【０１０５】また、上記実施の形態では仲介装置を独立した装置として説明したが、仲介装置の機能を実現するプログラムとデータベースサーバを同一コンピュータ上で動作させても良い。これにより、仲介装置のハードウェアが必要なくなり、コストを削減する効果がある。【０１０６】また、仲介装置を複数用意しても良い。これにより、システム全体の信頼性がより高まる。【０１０７】また、上記実施例ではｌｅａｄｅｒまたはｆｏｌｌｏｗｅｒに選定されたサーバは常に変わらなかったが、変えても良い。例えば、ｌｅａｄｅｒが故障した場合、そのｌｅａｄｅｒをシステムから切り離し、ｆｏｌｌｏｗｅｒの中から新しいｌｅａｄｅｒを選定しても良い。これにより、故障に対する耐性が高まりより高信頼化が実現できる。
【産業上の利用可能性】
【０１０８】  本発明は、複数のデータベースサーバを平行動作させる高信頼化データベースシステムに適用することができる。
【図面の簡単な説明】
【０１０９】
【図１】第１の実施形態に係る高信頼化データベースシステムの構成図
【図２】ライトコンフリクトを説明する図
【図３】ｓｎａｐｓｈｏｔ  ｉｓｏｌａｔｉｏｎを説明する図
【図４】第１の実施形態に係る仲介装置の構成図
【図５】第１の実施形態に係る仲介装置の全体の動作を説明するフローチャート
【図６】第１の実施形態に係る通常ルーチンを説明するフローチャート
【図７】第１の実施形態に係るスナップショット作成ルーチンを説明するフローチャート
【図８】第１の実施形態に係る同期維持ルーチンを説明するフローチャート
【図９】第１の実施形態に係るコミット処理ルーチンを説明するフローチャート
【図１０】ライトコンフリクトする場合の動作を説明するシーケンスチャート
【図１１】ＣＯＭＭＩＴとＳＥＬＥＣＴの実行順序によってＳＥＬＥＣＴの結果が変わる場合の動作を説明するシーケンスチャート
【図１２】ＣＯＭＭＩＴとＳＥＬＥＣＴの実行順序によってＳＥＬＥＣＴの結果が変わる場合の動作を説明するシーケンスチャート
【図１３】ライトコンフリクトしない場合の動作を説明するシーケンスチャート
【図１４】第２の実施形態に係る仲介装置の構成図
【図１５】同期から外れたサーバを同期する場合の動作を説明するシーケンスチャート
【図１６】同期から外れたサーバを同期する場合の動作を説明するシーケンスチャート
【図１７】第３の実施形態に係る通常ルーチンを説明するフローチャート
【図１８】第３の実施形態に係る同期維持ルーチンを説明するフローチャート
【図１９】第３の実施形態に係る負荷分散ルーチンを説明するフローチャート
【図２０】第３の実施形態に係る仲介装置の全体の動作を説明するフローチャート
【図２１】従来の高信頼化データベースシステムの構成図
【図２２】従来の高信頼化データベースシステムの構成図
【図２３】データベースサーバが保持しているテーブルの一例
【図２４】ライトコンフリクトするトランザクションの一例
【図２５】実行順序が問題となるトランザクションの一例
【図２６】ライトコンフリクトしないトランザクションの一例
【図２７】従来の高信頼化データベースシステムのために図２６を改造したトランザクションの一例
【符号の説明】
【０１１０】１０…サーバ、２０，２３…仲介装置、２１…接続処理部、２２…制御部、２４…バックアップデータ作成部、２５…バッファ、２６…管理部、３０，４０…ネットワーク、５０…クライアント
【図１】
2009169449.tif 000003
【図２】
2009169449.tif 000004
【図３】
2009169449.tif 000005
【図４】
2009169449.tif 000006
【図５】
2009169449.tif 000007
【図６】
2009169449.tif 000008
【図７】
2009169449.tif 000009
【図９】
2009169449.tif 000010
【図２４】
2009169449.tif 000011
【図８】
2009169449.tif 000012
【図１０】
2009169449.tif 000013
【図１１】
2009169449.tif 000014
【図１２】
2009169449.tif 000015
【図２５】
2009169449.tif 000016
【図１３】
2009169449.tif 000017
【図１５】
2009169449.tif 000018
【図１６】
2009169449.tif 000019
【図１７】
2009169449.tif 000020
【図１８】
2009169449.tif 000021
【図１９】
2009169449.tif 000022
【図１４】
2009169449.tif 000023
【図２０】
2009169449.tif 000024
【図２１】
2009169449.tif 000025
【図２２】
2009169449.tif 000026
【図２３】
2009169449.tif 000027
【図２６】
2009169449.tif 000028
【図２７】
2009169449.tif 000029