ゼロ知識アボートレス並列スケジューラが存在しないことの証明
0. はじめに
過去の投稿の以下の主張の条件付き証明と条件を満たさない場合の反例の存在の証明です。
以下の4つの性質のうち、最大3つまでしか同時に満たせない、という主張。
もしくは以下の3つの性質のうち、最大2つまでしか同時に満たせないという主張。
- 失敗を引き起こさない直列化可能スケジューリング
- トランザクションの実行の並行性
- アプリケーションに対するゼロ知識
この主張のイメージ図: 。
用語は主張の説明の記事、ゼロ知識での制約は制約の説明の記事を参照してください。
タイトルの"ゼロ知識アボートレス並列スケジューラ"とは、アプリケーションに対するゼロ知識で失敗を引き起こさないトランザクションの並列実行可能なスケジューラにつけた(適当な)名前です。
1. 準備
スケジューラへの入力
複数のトランザクションのデータベースステップが1つのキューにキューイングされるとする。スケジューラはこのキューを入力とする。
スケジューラの動作
スケジューラは、入力スケジュールの先頭のデータベースステップを取り出し、それに対するアクションを実行するかまたは実行を保留するかを選択する。
トランザクションによるデータベースアイテムをreadするデータベースステップを、writeするデータベースステップをと書くことにする。マルチバージョンの場合にどのバージョンをreadするかは文中で補足する。
あるトランザクションのデータベースステップの実行を保留しても、並行する他のトランザクションのデータベースステップがキューに到着すること(保留したデータベースステップの実行を他のトランザクションが待つことがないこと)は一般に期待してよい。これは前回の記事の"トランザクション間に隠れた制約がないと仮定できない"に書いた通り。
一方で実行が保留されたデータベースステップの属するトランザクションについては、新しいデータベースステップが到着することを期待できない(保留されたステップを実行しないかぎり次のステップが決定されない)。
トランザクション間の順序に関する制約
あるトランザクションがあるデータベースアイテムにwriteした値を、別のトランザクションがreadした場合、トランザクション間の順序は という制約を満たす必要がある。この関係をreads-from関係と呼びこれによる制約をとあらわすことにする。
別のトランザクションがにwriteしようとする場合、の直列化順序上の順序は、以下のいずれかになければならない。
逆にいうと、以下の順序があり得ない
が間に割込むとはがwriteした値をreadする必要があるが、はすでにがwriteした値をreadすることが決定されているためである。
これに加えてモノバージョンの場合は、がにwriteした後にがにwriteした場合にという制約が発生する。(それ以降のreadはがwriteしたの値しか読めないため)
このようなミクロな制約(順序)全体からトランザクション単位での矛盾のない全順序が導かれる必要がある。
モノバージョン、マルチバージョン
モノバージョンでは、識別性のある最小単位であるデータベースアイテムの値は同時にただ1つしか存在できない。あるデータベースアイテムへのwriteを実行すると、writeしたトランザクションが実行中かcommit済かにかかわらず、以前の値をreadすることができない。
マルチバージョンでは、同じデータベースアイテムに対する複数の値(複数のバージョン)が同時に存在でき、readステップの実行の際にスケジューラはそれらの中から読む値を選択できる。
スケジューラの目標
アボートレススケジューラは 、一度実行したデータベースステップを直列化失敗を理由としてアボートさせない。
並列スケジューラは、完了していないあるトランザクション実行中に、他のトランザクションの(一部の)データベースステップを保留することなく実行したい。
あるデータベースステップを実行すると、将来の直列化失敗の可能性を排除できない場合、アボートレススケジューラはそのデータベースステップを実行できず保留しなければならない。
あるトランザクションの実行中において、到着する他のすべてのトランザクションのすべてのデータベースステップを保留する必要が生じる場合、ゼロ知識アボートレススケジューラはトランザクションを並列実行できないことになる。
2. 補題
2.1. 補題1
ゼロ知識アボートレススケジューラにおいてreadステップを実行すると、readを実行したトランザクションは、直列化順序においてreadした値をwriteしたトランザクションの 直後 に位置づけられる。
readを実行したトランザクションを、がreadした値をwriteしたトランザクションを、対象のデータベースアイテムをとする。
このreadの実行により、という制約が生じる。
以外のトランザクションに対する知識がない場合、これらのトランザクションがに対してwriteする可能性を排除できない。そこでこれらのトランザクションがにwriteすると仮定すると、reads-from関係の制約により、はの前かの後かのいずれかになり、決してとの間には割込まない。
この主張が完了していないすべてのトランザクションに対して成立するので、ゼロ知識アボートレススケジューラはを直列化順序上での直後に置くことしかできない。
2.2. 補題2
ゼロ知識アボートレススケジューラにおいてコミット応答済みトランザクションがwriteした値に対するreadを実行すると、readを実行したトランザクションは並行する他のすべての実行中トランザクションよりも直列化順序上において 前 となる。
readを実行したトランザクションを、がreadした値をwriteしたトランザクションをとする。
補題1よりはの直後に置かれる。はコミット応答済のトランザクションであるので、ゼロ知識スケジューラは新しいトランザクションをの前に置くことができない。よってその他の実行中トランザクションはすべてより 後 となる。
2.3. 補題3
ゼロ知識アボートレススケジューラにおいては、あるトランザクションがwriteした値をreadできる実行中トランザクションはたかだか1つである。
がwriteした値をトランザクションがreadすると、補題1よりはの直後に置かれる。もし別のトランザクションががwriteした値をreadしたとするともの直後に置かれることとなり矛盾する。
3. 証明
3.1. 証明の方針
ある静止状態(実行中のトランザクションがない状態)において、新たにデータベースステップのシーケンスが到着する状況を考える。
ゼロ知識の仮定によりコミット完了の応答を返したトランザクションの前には割込めないので、静止状態におけるデータベースアイテムの値をどのトランザクションがwriteしたかはこれ以降のスケジューリングにおいてはもはや重要ではなく、この値を書いたトランザクションを区別せずにと呼ぶことにする。
いま入力スケジュールの先頭のデータベースステップの属するトランザクションをとし、入力スケジュールの先頭からに属する連続した1つ以上のデータベースステップをそれぞれ実行完了した状況を考える。
実行完了したデータベースステップがcommitまたはabortで終了していた場合はは他のトランザクションと並列実行されなかったので、が完了した後の最初のデータベースステップの属するトランザクションを新たにと置いて議論を続ける。
以下の2通りに場合分けして証明する。
- が、がwriteした値をreadしている場合
- が、がwriteした値をreadしていない場合
1つ目は、があるデータベースアイテムへのreadステップを実行しており、かつその前にによる同じデータベースアイテムに対するwriteステップが存在しない場合で、つまりとの間にreads-from関係ができている場合である。
2つ目は、がwriteしか実行していない場合か、または実行した全てのreadステップに対してそれ以前に自身による同じデータベースアイテムに対するwriteが存在した場合である。ここではこのようなトランザクションを write先行トランザクション と呼ぶことにする。
以降ではの実行の途中で別のトランザクションのデータベースステップを取り出した場合を考える。 証明では、こののデータベースステップを実行してしまうと、直列化失敗を引き起こすような(直列化の観点では意地悪な)データベースステップの到着を排除できないこと、それゆえのデータベースステップを保留せざるを得ないことを示す。
3.2. とにreads-from関係がある場合
がwriteしがreadしたデータベースアイテムをとする。reads-from関係 が存在し、補題1によりはの直後に置かれ、補題2によりはより後になる。
のデータベースステップの実行によってがの"前”やがの"直後"となってしまう可能性が排除できない場合、アボートレススケジューラはそのデータベースステップを実行できない。
現在実行しようとしているのデータベースステップによって以下の5通りに場合分けする。
- がwriteしていないデータベースアイテムに対するread
- がwriteしたデータベースアイテムに対するread
- 以外のデータベースアイテムに対するwrite
- に対するwrite
- commit or abort
3.2.1. がwriteしていないデータベースアイテムに対するread
このデータベースアイテムをとする。
の値をwriteしたのはであるので補題3よりこのreadは実行できない。
3.2.2. がwriteしたデータベースアイテムに対するread
このデータベースアイテムをとし、このreadステップを実行したとする。
モノバージョンの場合
がwriteした値を読むことになるが、によるユーザアボートの可能性を排除できないので、スケジューラはこのreadステップを保留する必要がある。
マルチバージョンの場合
すでに実行されたと補題1,2よりはの前に位置づけられない。よってデータベースステップが読むべき値はがwriteした値(もしくはこれ以降にwriteされる値)であるが、は実行中なのでこのreadステップをスケジューラは保留する必要がある。
3.2.3. 以外のデータベースアイテムに対するwrite
がwrite先行トランザクションの場合である。 このデータベースアイテムをとする。
補題1,2よりはの後になるべきである。 よってスケジューラは基本的に、のデータベースステップは実行し、のデータベースステップは(先の順序に矛盾する可能性がある場合は)保留するように振舞う必要がある。
そこで今後のトランザクションの実行(のステップは実行可能でなければならない)に影響があるかを確認すればよい。
モノバージョンの場合
を実行したとし、その後によるへのreadステップ が到着する可能性を考える。
モノバージョンであるのでこのreadステップはのwriteした値、もしくはこれ以降に実行されたwriteの値を読むことしかできず、のwriteした値を読むことができない。
よってモノバージョンの場合は実行できない。
マルチバージョンの場合
を実行後、によるへのreadステップ が到着する可能性を考えたとしても、はがwriteした値をreadすることができる。
よって着目していたデータベースステップの実行による矛盾は生じない。よってマルチバージョンの場合は実行が可能である(反例1)。
3.2.4. に対するwrite
がwrite先行トランザクションの場合である。
モノバージョンの場合
が再びをreadする可能性を考えると、モノバージョンであるため、のwriteステップを保留する必要がある。
一度readしたデータベースアイテムの値をアプリケーションローカルなストレージに保存することで回避できるが、これは限定的なマルチバージョンであると解釈される*1。
マルチバージョンの場合
を実行したとしても、これ以降到着する可能性のあるトランザクションのデータベースステップの実行に影響を与えない。
具体的には、これ以降にトランザクションによるreadステップが到着したとしても、トランザクションはがwriteした値をreadすることが可能である。
よってマルチバージョンの場合は実行が可能である(反例1)。
3.2.5. commit or abort
トランザクションが空の場合であるが、のデータベースステップを実行することができる(反例2)。
3.3. とにreads-from関係がない場合
がwrite先行トランザクションの場合である。
がwriteしたデータベースアイテムをとする。
現在実行しようとしているのデータベースステップによって以下の5通りに場合分けする。
- がwriteしていないデータベースアイテムに対するread
- がwriteしたデータベースアイテムに対するread
- がwriteしていないデータベースアイテムに対するwrite
- がwriteしたデータベースアイテムに対するwrite
- commit or abort
3.3.1. がwriteしていないデータベースアイテムに対するread
がreadしたデータベースアイテムをとする。
このreadステップを実行したとすると、reads-from関係と補題1によりはの直後に置かれ、補題2によりはより後に置かれる。
よってこれ以降スケジューラは基本的に、のデータベースステップを実行し、のデータベースステップを保留するよう振舞う必要がある。
そこで、今後のトランザクションのデータベースステップの実行(のステップは実行可能でなければならない)に影響を与えるかを確認すればよい。
モノバージョンの場合
この後、によるがwiteしてしまったデータベースアイテムに対するreadステップが到着すると、上の制約を満たすためにははがwriteした値をreadする必要がある。しかしモノバージョンの場合は上書きされているためreadできない。
よってスケジューラはを保留しなければならない。
マルチバージョンの場合
がより前に位置づけられたが、既に実行されているのデータベースステップによっても、今後のの実行は妨げられない。なぜならばはまだデータベースの値を参照していない*2ため以降の任意の順序に位置づけすることが可能であり、またマルチバージョンであるためすでに行われたwriteステップものread/writeの実行に影響を与えないためである。
よってマルチバージョンの場合は、このreadステップを実行可能である(反例1)。
3.3.2. がwriteしたデータベースアイテムに対するread
モノバージョンの場合
モノバージョンなのではがwriteした値をreadするしか選択肢がないが、が実行中のためスケジューラはこのステップを保留する。
マルチバージョンの場合
マルチバージョンなのではがwriteした値を読むことを選択できる。 このときreads-from関係が得られ補題1よりはの直後に、補題2よりはの後に置かれる。
よってこれ以降スケジューラは基本的に、のデータベースステップを実行し、のデータベースステップを保留するよう振舞う必要がある。しかし3.3.1のマルチバージョンの場合と同じ議論により、マルチバージョンの場合はこれ以降ののデータベースステップは実行に影響を与えない。
よってこのreadステップは実行可能である(反例1)。
3.3.3 がwriteしていないデータベースアイテムに対するwrite
もwrite先行トランザクションの場合である。 がwriteしたデータベースアイテムをとする。
モノバージョンの場合
と実行したとする。
これ以降にによるへのreadが到着すると、のユーザアボートの可能性を考慮してこのreadをの完了まで保留する必要がある。
同様にによるへのreadが到着すると、のユーザアボートの可能性を考慮してこのreadをの完了まで保留する必要がある。
両者が到着した場合、スケジューラはどちらかを実行しないといけないが、その場合失敗の可能性を排除できない。
以上よりスケジューラはの実行を保留する必要がある。
マルチバージョンの場合
と実行したとしても現時点ではとの間の順序には何の制約もない。
よってこれ以降到着するのデータベースステップの実行によってはじめて生じる順序関係の制約に従い、前に位置づけられるトランザクションのデータベースステップが実行可能かを確認すればよい。
前の議論と同様にマルチバージョンであるので、すでに実行されたwriteステップは以降のデータベースステップの実行に影響を与えない。よって今着目しているデータベースステップは実行可能である(反例1)。
3.3.4. がwriteしたデータベースアイテムに対するwrite
モノバージョンの場合
を実行したとする。これ以降にによるのreadが到着すると、モノバージョンであるため、がwriteした値を読めなくなってしまう。よってこのデータベースステップは実行はできない。
マルチバージョンの場合
3.3.3のマルチバージョンの場合と同じ議論によりこのデータベースステップは実行可能である(反例1)。
3.3.5. commit or abort
3.2.5と同じく実行することができる(反例2)。
3.4 保留されたデータベースステップの解除条件
最後に、一度保留したのデータベースステップが保留を解除され実行可能と判断されるためには、が完了する(完了が保証される)、かつその時に限ることを示す。
ざっくりいうと、保留を解除するためには、(やその他のトランザクション)がこれ以降xxxをしないことが保証されること、もしくは他のトランザクションが必ずyyyをすることが保証されることが必要である*3。
yyyは他のトランザクションのユーザアボートを考慮すると保証は得られない。xxxしないことはトランザクションの完了を持ってしか保証できない。
トランザクションの完了を待ってから実行可能となるということは、インターリーブされないということであり、結局並列実行できないということになる。
ただしの完了が保証される場合には以下も含まれる。
のいくつかのデータベースステップを実行し、のデータベースステップの実行を保留した段階で、のcommit/abortを受け取った場合である。
このとき、の完了(commit/abort)を保留して、保留されているの(一部の)データベースステップを実行することができる(反例2)。
4. まとめ
反例1は、マルチバージョンにおいてwrite先行トランザクションと並列実行しようとする場合である。
マルチバージョンの場合の順序の制約はreads-from関係によってしか生まれないので、write先行トランザクションは、先行するwrite(とそれに隠れるread)ステップを実行しても制約を生成しない。
そのため、通常のトランザクションと1つ以上のwrite先行トランザクション(の先行するwrite部分)をインターリーブして実行することができる。
反例2は、commit/abortをデータベースステップの一部であると解釈する場合に、read/writeステップと最後のcommit/abortステップの境界に限りインターリーブした実行が可能というものである。
"トランザクションが並列に実行されている"とみなす範囲を、read/writeステップだけに限定すれば反例2は反例でなくなる。
このようにすれば、モノバージョンにおいては当初の主張"ゼロ知識アボートレス並列スケジューラは存在しない"は成立する。