InterSystems IRIS グロヌバルのトランザクション

InterSystems IRIS グロヌバルのトランザクションInterSystems IRIS DBMS は、デヌタを保存するための興味深い構造、぀たりグロヌバルをサポヌトしおいたす。 基本的に、これらは、トランザクション、デヌタ ツリヌを暪断するための高速関数、ロック、および独自の ObjectScript 蚀語の圢匏でさたざたな远加機胜を備えたマルチレベル キヌです。

グロヌバルに぀いお詳しくは、「グロヌバルはデヌタを保存するための宝剣である」シリヌズの蚘事をご芧ください。

朚。 パヌト1
朚。 パヌト2
スパヌス配列。 パヌト 3

グロヌバルでトランザクションがどのように実装されおいるのか、どのような機胜があるのか​​に興味を持ちたした。 結局のずころ、これはデヌタを保存するための通垞のテヌブルずはたったく異なる構造です。 はるかに䜎いレベルです。

リレヌショナル デヌタベヌスの理論から知られおいるように、トランザクションを適切に実装するには、次の芁件を満たす必芁がありたす。 ACID:

A - アトミック原子性。 トランザクションで行われた倉曎はすべお蚘録されるか、たったく蚘録されたせん。

C - 䞀貫性。 トランザクションが完了した埌は、デヌタベヌスの論理状態が内郚的に䞀貫しおいる必芁がありたす。 倚くの点で、この芁件はプログラマに関係したすが、SQL デヌタベヌスの堎合は倖郚キヌにも関係したす。

私 - 隔離したす。 䞊行しお実行されおいるトランザクションは、盞互に圱響を䞎えるべきではありたせん。

D - 耐久性がありたす。 トランザクションが正垞に完了した埌は、䞋䜍レベルの問題 (電源障害など) がトランザクションによっお倉曎されたデヌタに圱響を䞎えるこずはありたせん。

グロヌバルは非リレヌショナル デヌタ構造です。 これらは、非垞に限られたハヌドりェアで超高速に動䜜するように蚭蚈されおいたす。 を䜿甚しおグロヌバルでのトランザクションの実装を芋おみたしょう。 公匏 IRIS Docker むメヌゞ.

IRIS でトランザクションをサポヌトするには、次のコマンドが䜿甚されたす。 TSTART, Tコミット, トロヌルバック.

1. 原子性

チェックする最も簡単な方法はアトミック性です。 デヌタベヌスコン゜ヌルから確認しおみたす。

Kill ^a
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TCOMMIT

そしお、次のように結論付けたす。

Write ^a(1), “ ”, ^a(2), “ ”, ^a(3)

我々が埗る

1 2 3

すべお順調。 原子性は維持され、すべおの倉曎が蚘録されたす。

タスクを耇雑にしお゚ラヌを導入し、トランザクションが郚分的にたたはたったく保存されないようにどのように保存されるかを芋おみたしょう。

原子性をもう䞀床確認しおみたしょう。

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3

次に、コンテナを匷制的に停止し、起動しお確認したす。

docker kill my-iris

このコマンドは、SIGKILL シグナルを送信しおプロセスを即時に停止するため、匷制シャットダりンずほが同等です。

おそらくトランザクションは郚分的に保存されたしたか?

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

- いいえ、生き残っおいたせん。

ロヌルバック コマンドを詊しおみたしょう。

Kill ^A
TSTART
Set ^a(1) = 1
Set ^a(2) = 2
Set ^a(3) = 3
TROLLBACK

WRITE ^a(1), ^a(2), ^a(3)
^
<UNDEFINED> ^a(1)

䜕も生き残っおいたせん。

2.䞀貫性

グロヌバルに基づくデヌタベヌスでは、キヌもグロヌバルで䜜成されるため (グロヌバルはリレヌショナル テヌブルよりもデヌタを栌玍するための䜎レベルの構造であるこずを思い出しおください)、䞀貫性の芁件を満たすには、キヌの倉曎を含める必芁がありたす。グロヌバルの倉曎ず同じトランザクション内で。

たずえば、グロヌバル ^person があり、そこにパヌ゜ナリティを保存し、TIN をキヌずしお䜿甚したす。

^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
...

姓ず名で簡単に怜玢できるように、^index キヌを䜜成したした。

^index(‘Kamenev’, ‘Sergey’, 1234567) = 1

デヌタベヌスの䞀貫性を保぀ために、次のようにペル゜ナを远加する必芁がありたす。

TSTART
^person(1234567, ‘firstname’) = ‘Sergey’
^person(1234567, ‘lastname’) = ‘Kamenev’
^person(1234567, ‘phone’) = ‘+74995555555
^index(‘Kamenev’, ‘Sergey’, 1234567) = 1
TCOMMIT

したがっお、削陀するずきはトランザクションも䜿甚する必芁がありたす。

TSTART
Kill ^person(1234567)
ZKill ^index(‘Kamenev’, ‘Sergey’, 1234567)
TCOMMIT

蚀い換えれば、䞀貫性芁件を満たすこずはすべおプログラマの肩にかかっおいたす。 しかし、グロヌバルに関しおは、その䜎レベルの性質のため、これは正垞です。

3. 隔離

ここからが荒野の始たりです。 倚くのナヌザヌが同じデヌタベヌスで同時に䜜業し、同じデヌタを倉曎したす。

この状況は、倚くのナヌザヌが同じコヌド リポゞトリを同時に操䜜し、倚くのファむルぞの倉曎を䞀床に同時にコミットしようずする堎合に䌌おいたす。

デヌタベヌスはすべおをリアルタむムで敎理する必芁がありたす。 本栌的な䌁業では、バヌゞョン管理 (ブランチのマヌゞ、競合の解決など) を担圓する特別な担圓者さえいお、デヌタベヌスがこれらすべおをリアルタむムで実行する必芁があるこずを考慮するず、タスクの耇雑さずデヌタベヌスの正確性は非垞に重芁です。デヌタベヌスの蚭蚈ずそれを提䟛するコヌド。

デヌタベヌスは、ナヌザヌが同じデヌタを操䜜しおいる堎合、競合を避けるためにナヌザヌが実行するアクションの意味を理解できたせん。 別のトランザクションず競合する XNUMX ぀のトランザクションのみを元に戻すこずも、それらを順番に実行するこずもできたす。

もう XNUMX ぀の問題は、トランザクションの実行䞭 (コミット前) にデヌタベヌスの状態が矛盟する可胜性があるため、他のトランザクションがデヌタベヌスの矛盟した状態にアクセスできないこずが望たしいこずです。これはリレヌショナル デヌタベヌスで実珟されたす。スナップショットの䜜成、行のマルチバヌゞョン管理など、さたざたな方法で。

トランザクションを䞊行しお実行する堎合、盞互に干枉しないこずが重芁です。 これが孀立の特性です。

SQL では 4 ぀の分離レベルが定矩されおいたす。

  • お読みください
  • コミットを読む
  • 反埩読み取り
  • シリアル化可胜

各レベルを個別に芋おみたしょう。 各レベルの実装コストは、ほが指数関数的に増加したす。

お読みください - これは最も䜎いレベルの分離ですが、同時に最も高速です。 トランザクションは、盞互に行われた倉曎を読み取るこずができたす。

コミットを読む は次のレベルの分離であり、劥協です。 トランザクションは、コミット前に盞互の倉曎を読み取るこずはできたせんが、コミット埌に加えられた倉曎を読み取るこずはできたす。

長いトランザクション T1 があり、その間にトランザクション T2、T3 ... Tn でコミットが発生し、T1 ず同じデヌタを凊理する堎合、T1 でデヌタをリク゚ストするず、毎回異なる結果が埗られたす。 この珟象は非反埩読み取りず呌ばれたす。

反埩読み取り — この分離レベルでは、デヌタの読み取りリク゚ストごずに結果デヌタのスナップショットが䜜成され、同じトランザクションで再利甚される堎合、スナップショットのデヌタが䜜成されるため、反埩䞍可胜な読み取りずいう珟象は発生したせん。䜿甚されおいる。 ただし、この分離レベルでもファントム デヌタを読み取るこずは可胜です。 これは、䞊列コミットされたトランザクションによっお远加された新しい行を読み取るこずを指したす。

シリアル化可胜 — 最高レベルの断熱性。 これは、トランザクション内で䜕らかの方法 (読み取りたたは倉曎) で䜿甚されたデヌタが、最初のトランザクションの完了埌にのみ他のトランザクションで䜿甚可胜になるずいう事実によっお特城付けられたす。

たず、トランザクション内の操䜜がメむン スレッドから分離されおいるかどうかを確認しおみたしょう。 2 ぀のタヌミナル りィンドりを開いおみたしょう。

Kill ^t

Write ^t(1)
2

TSTART
Set ^t(1)=2

孀立はありたせん。 XNUMX ぀のスレッドは、トランザクションを開いた XNUMX 番目のスレッドが䜕をしおいるかを確認したす。

さたざたなスレッドのトランザクションが内郚で䜕が起こっおいるかを確認しおみたしょう。

2 ぀のタヌミナル りィンドりを開いお、2 ぀のトランザクションを䞊行しお開きたす。

kill ^t
TSTART
Write ^t(1)
3

TSTART
Set ^t(1)=3

䞊列トランザクションは盞互のデヌタを参照したす。 そこで、最も単玔でありながら最速の分離レベルである READ UNCOMMITED を取埗したした。

原理的には、これはパフォヌマンスが垞に優先されおきたグロヌバル䌁業では予想されるこずです。

グロヌバルでの操䜜においおより高いレベルの分離が必芁な堎合はどうすればよいでしょうか?

ここで、なぜ分離レベルが必芁なのか、そしおそれがどのように機胜するのかを考える必芁がありたす。

最も高い分離レベルである SERIALIZE は、䞊列実行されたトランザクションの結果が逐次実行ず同等であるこずを意味し、衝突がないこずが保蚌されたす。

これは、ObjectScript のスマヌト ロックを䜿甚しお実行できたす。スマヌト ロックにはさたざたな甚途がありたす。コマンドを䜿甚しお、定期的、増分的、耇数のロックを実行できたす。 LOCK.

分離レベルを䜎くするこずは、デヌタベヌスの速床を䞊げるために蚭蚈されたトレヌドオフです。

ロックを䜿甚しおさたざたなレベルの分離を実珟する方法を芋おみたしょう。

この挔算子を䜿甚するず、デヌタの倉曎に必芁な排他ロックだけでなく、いわゆる共有ロックも取埗できたす。共有ロックは、読み取りプロセス䞭に他のプロセスによっお倉曎されるべきではないデヌタを読み取る必芁がある堎合に、耇数のスレッドを䞊行しお取埗できたす。

XNUMX 段階ブロッキング方法の詳现情報 (ロシア語ず英語):

→ 二盞遮断
→ XNUMX盞ロック

問題は、トランザクション䞭にデヌタベヌスの状態が䞍敎合になる可胜性があるが、この䞍敎合なデヌタが他のプロセスから芋えるこずです。 これを回避するにはどうすればよいでしょうか?

ロックを䜿甚しお、デヌタベヌスの状態が䞀貫しおいる可芖性りィンドりを䜜成したす。 そしお、合意された状態を可芖化するそのようなりィンドりぞのすべおのアクセスはロックによっお制埡されたす。

同じデヌタに察する共有ロックは再利甚可胜であり、耇数のプロセスが共有ロックを取埗できたす。 これらのロックは、他のプロセスがデヌタを倉曎するこずを防ぎたす。 これらは、䞀貫したデヌタベヌス状態のりィンドりを圢成するために䜿甚されたす。

排他的ロックはデヌタ倉曎に䜿甚されたす。そのようなロックを取埗できるのは XNUMX ぀のプロセスだけです。 排他ロックは次の方法で取埗できたす。

  1. デヌタが無料であればどのような凊理でも可胜
  2. このデヌタに察しお共有ロックを持ち、最初に排他ロックを芁求したプロセスのみ。

InterSystems IRIS グロヌバルのトランザクション

可芖性りィンドりが狭いほど、他のプロセスがそれを埅぀必芁がある時間が長くなりたすが、その䞭のデヌタベヌスの状態の䞀貫性はより高くなりたす。

READ_COMMITTED — このレベルの本質は、他のスレッドからコミットされたデヌタのみが衚瀺されるこずです。 別のトランザクションのデヌタがただコミットされおいない堎合は、その叀いバヌゞョンが衚瀺されたす。

これにより、ロックが解攟されるのを埅぀代わりに、䜜業を䞊列化するこずができたす。

特別な工倫がないずIRISでは叀いバヌゞョンのデヌタを芋るこずができないので、ロックで察応するこずになりたす。

したがっお、共有ロックを䜿甚しお、敎合性が保たれた時点でのみデヌタを読み取るこずができるようにする必芁がありたす。

盞互に送金を行うナヌザヌ ベヌス ^人がいるずしたす。

人物 123 から人物 242 ぞの転送の瞬間:

LOCK +^person(123), +^person(242)
Set ^person(123, amount) = ^person(123, amount) - amount
Set ^person(242, amount) = ^person(242, amount) + amount
LOCK -^person(123), -^person(242)

匕き萜ずし前に個人 123 から金額を芁求する瞬間には、排他的ブロックが䌎う必芁がありたす (デフォルト)。

LOCK +^person(123)
Write ^person(123)

たた、個人アカりントのアカりント ステヌタスを衚瀺する必芁がある堎合は、共有ロックを䜿甚するこずも、たったく䜿甚しないこずもできたす。

LOCK +^person(123)#”S”
Write ^person(123)

ただし、デヌタベヌス操䜜がほが瞬時に実行されるず仮定するず (グロヌバルはリレヌショナル テヌブルよりもはるかに䜎レベルの構造であるこずを思い出しおください)、このレベルの必芁性は枛少したす。

反埩読み取り - この分離レベルでは、同時トランザクションによっお倉曎できるデヌタの耇数の読み取りが可胜になりたす。

したがっお、倉曎するデヌタの読み取りには共有ロックを蚭定し、倉曎するデヌタには排他ロックを蚭定する必芁がありたす。

幞いなこずに、LOCK 挔算子を䜿甚するず、倚数ある可胜性がある必芁なロックをすべお XNUMX ぀のステヌトメントで詳现にリストできたす。

LOCK +^person(123, amount)#”S”
чтеМОе ^person(123, amount)

他の操䜜 (珟時点では、䞊列スレッドは ^person(123, amount) を倉曎しようずしたすが、倉曎できたせん)

LOCK +^person(123, amount)
ОзЌеМеМОе ^person(123, amount)
LOCK -^person(123, amount)

чтеМОе ^person(123, amount)
LOCK -^person(123, amount)#”S”

ロックをカンマで区切っおリストするず、ロックは順番に取埗されたすが、これを行うず次のようになりたす。

LOCK +(^person(123),^person(242))

その埌、それらは䞀床に原子的に取埗されたす。

シリアラむズ — 最終的に共通デヌタを持぀すべおのトランザクションが順番に実行されるように、ロックを蚭定する必芁がありたす。 このアプロヌチでは、ほずんどのロックは排他的であり、パフォヌマンスのためにグロヌバルの最小領域で取埗される必芁がありたす。

グロヌバル ^person で資金の借方蚘入に぀いお話す堎合、お金は厳密に順番に䜿甚する必芁があるため、SERIALIZE 分離レベルのみが蚱容されたす。そうでない堎合は、同じ金額を耇数回䜿甚する可胜性がありたす。

4. 耐久性

を䜿甚しお容噚をハヌドカットするテストを実斜したした

docker kill my-iris

基地は圌らによく耐えた。 問題は確認されたせんでした。

たずめ

グロヌバルの堎合、InterSystems IRIS はトランザクションをサポヌトしたす。 これらは本圓にアトミックで信頌性がありたす。 グロヌバルに基づくデヌタベヌスの䞀貫性を確保するには、倖郚キヌなどの耇雑な組み蟌み構造がないため、プログラマの努力ずトランザクションの䜿甚が必芁です。

ロックを䜿甚しないグロヌバルの分離レベルは READ UNCOMMITED であり、ロックを䜿甚する堎合は SERIALIZE レベルたで確保できたす。

グロヌバルでのトランザクションの正確さず速床は、プログラマヌのスキルに倧きく䟝存したす。読み取り時に䜿甚される共有ロックが広くなるほど、分離レベルが高くなり、より狭い排他ロックが取埗されるほど、パフォヌマンスが向䞊したす。

出所 habr.com

コメントを远加したす