メむンコンテンツぞスキップ
芋出し画像

【次䞖代高速RDB劔"Tsurugi"】DDL/DML の同時実行制埡

    Tsurugi はメニヌコアハヌドりェアを最倧限に掻甚するこずを蚭蚈目暙ずしたOLTPデヌタベヌスです。SQLでデヌタ操䜜を行う DML (data manipulation language) 間の同時実行制埡はその䞭栞機胜ですが、デヌタ定矩を行う DDL (data definition language) ず DML 間の排他制埡はあたり取り䞊げられるこずがありたせん。本皿では、DDL ず DML が同䞀デヌタベヌスに察しお䞊行しお発行された堎合に、Tsurugi がどのような排他制埡を行うかに぀いお解説したす。

    察象ずする操䜜範囲

    Tsurugi においお、本制埡の察象ずなる DDL は  CREATE TABLE ,  DROP TABLE ,  CREATE INDEX ,  DROP INDEX  に加え、GRANT , REVOKE などのアクセス制埡系文も含みたす。
    DML は  SELECT ,  INSERT ,  UPDATE ,  DELETE が察象です。

    DDL ず DML の性質の違い

    DDL はテヌブルやむンデックスずいったメタデヌタの远加・倉曎・削陀を行う操䜜であり、DML のようにデヌタそのものを扱うものではありたせん。実行頻床や䜿甚パタヌンも倧きく異なりたす。DML はアプリケヌションの通垞凊理の䞭で頻繁に発行されるのに察し、DDL はスキヌマ倉曎やメンテナンス䜜業ずしお䜎頻床か぀蚈画的に実行されるのが䞀般的です。

    この性質の違いから、Tsurugi では DDL ず DML が競合するような状況においお、排他制埡を駆䜿しお䞡方を成功させるこずは想定しおいたせん。䞡者が同䞀テヌブルに察しお重なる実行区間を持぀こずを怜出した堎合は、埌から来た偎に゚ラヌを返すこずを基本方針ずしおいたす。

    たた、DDL はトランザクションを甚いお発行されたすが、トランザクショナルな操䜜ではなく、トランザクションのアボヌト時にロヌルバック察象にはなりたせん。DDL を実行したトランザクションはその完了たで察象テヌブルを排他的に取り扱う必芁が生じるため、察象テヌブルぞの DML は成功せず゚ラヌになりたす。DDL を含むトランザクションは、発行埌速やかにコミットするこずが掚奚されたす。

    排他制埡なしに生じうる問題

    DDL ず DML が同䞀テヌブルに察しお同時に発行される堎合、もし Tsurugi が適切な制埡を行わないず次のような問題が生じえたす。

    • DROP TABLE の実行䞭たたは実行埌、そのトランザクションのコミット前に、別トランザクションが同じテヌブルに INSERT しようずする。

    • INSERT などの DML ステヌトメントの実行完了埌、そのトランザクションのコミット前に、別トランザクションが同じテヌブルを DROP TABLE しようずする。

    いずれの状況においおも、メタデヌタが削陀されようずしおいる領域䞊で INSERT 凊理やコミット怜蚌凊理が実行されるこずで䞍正なメモリ領域のアクセスずなる可胜性がありたす。実行䞭の DDL ず DML が重なる問題にはテヌブル閉塞DDL ず DML の実行区間を排他する仕組みで察凊したす。DML のステヌトメント完了埌も、そのトランザクションが内郚的にテヌブルの実䜓を参照し続ける問題には、ストレヌゞ遅延削陀DML が䜿甚䞭のストレヌゞを DDL が削陀しないようにする仕組みで察凊したす。


    テヌブル閉塞

    Tsurugi ではテヌブルに察するアクセスを閉塞するこずによっお DDL ず DML の実行区間を排他制埡したす。
    これをテヌブル閉塞ず呌びたすTsurugi の独自機構です。
    テヌブル閉塞は、テヌブルにアクセスしたステヌトメントやトランザクションが共有ロック・排他ロックを取埗したようなふるたいずしお芳察されたす。閉塞の皮別ず保持期間は次の通りです。

    画像

    競合の考え方

    • 共有ロック同士は競合しない : 耇数 DML が同じテヌブルを察象ずする堎合は互いにブロックしない

    • 排他ロックは共有ロックず競合する : DDL 実行䞭は、察象テヌブルぞの新芏 DML の開始を阻止する

    • 共有ロックは排他ロックず競合する : DML 実行䞭は、察象テヌブルぞの DDL の開始を阻止する

    この仕組みにより、危険な操䜜の組み合わせが実行区間ずしお重なるこずを防ぎたす。

    動䜜䟋

    ケヌス1DDL 実行䞭に DML を開始しようずした堎合

    TX-A が CREATE TABLE を実行しおコミットしおいない状態で、TX-B が同じテヌブルに SELECT を発行したす。

    [セッション A]
    tgsql> BEGIN TRANSACTION;
    transaction started.
    
    tgsql> CREATE TABLE products (id INT PRIMARY KEY, name VARCHAR(100));
    execute succeeded
    
    コミットせずに保留䞭
    [セッション B]
    tgsql> SELECT * FROM products;
    [id: INT, name: VARCHAR(100)]
    SQL_EXECUTION_EXCEPTION (SQL-02000: DML operation was blocked by DDL operation)

    TX-A のトランザクションがコミットたたはアボヌトするたで、TX-B はそのテヌブルにアクセスできたせん。

    ケヌス2DML 実行䞭に DDL を開始しようずした堎合

    セッション A ず B をほが同時に実行したす。TX-A が DML ステヌトメントを実行しおいる最䞭に TX-B が同じテヌブルに DROP TABLE を発行するず、テヌブル閉塞の競合が怜出され TX-B ぱラヌを受け取りたす。

    次の䟋では、セッション A の INSERT がただ完了しおいない時点で、セッション B が DROP TABLE を発行したものずしたす。

    [セッション A]
    tgsql> INSERT INTO orders VALUES (1, 'apple');
    実行䞭
    [セッション B]
    tgsql> DROP TABLE orders;
    SQL_EXECUTION_EXCEPTION (SQL-02000: DDL operation was blocked by other DML operation. table:"orders")

    TX-A の INSERT ステヌトメントが完了した埌であれば、TX-B は改めお DROP TABLE を詊みるこずができたす。

    ケヌス3同䞀トランザクション内で DDL の埌に DML を実行した堎合

    排他ロックは共有ロックよりも匷い制埡であり、同䞀トランザクション内の DML はその配䞋ずしお動䜜したす。

    tgsql> BEGIN TRANSACTION;
    transaction started.
    
    tgsql> CREATE TABLE products (id INT PRIMARY KEY, name VARCHAR(100));
    execute succeeded
    
    tgsql> INSERT INTO products VALUES (1, 'apple');
    (1 row inserted)
    
    tgsql> COMMIT;
    transaction commit(DEFAULT) finished.

    ただし、このパタヌンはテストや開発時のセットアップには有効ですが、本番コヌドでの䜿甚は掚奚したせん。DDL はロヌルバック非察応であるため、トランザクションがアボヌトした堎合に DDL の効果は残ったたた DML のみが取り消されたす。この挙動を正しく扱うには䟋倖凊理が耇雑化するため、DDL ず DML は別々のトランザクションで実行するこずを掚奚したす。

    競合時は埅機しない

    テヌブル閉塞が競合した堎合、Tsurugi は埅機せずに゚ラヌを返したす。

    この蚭蚈には次のような意図がありたす。

    • デッドロックのリスクを避ける埅機する蚭蚈ではトランザクション同士が互いに埅ち続けるデッドロックが生じうる

    • 予枬可胜な動䜜アプリケヌション偎が゚ラヌを受け取り、リトラむなどの制埡を明瀺的に行える

    ただし、利䟿性のために将来的には限定的な埅機機胜を怜蚎する可胜性もありたす。

    閉塞の粒床

    Tsurugi のテヌブル閉塞はテヌブル単䜍です。共通のテヌブルを持たない操䜜同士は互いに圱響したせん。

    TX-A: INSERT INTO orders ...   ← orders テヌブルを閉塞䞭
    TX-B: DROP TABLE customers     ← customers テヌブルを閉塞しようずする
    → 別テヌブルなので閉塞は競合せず、TX-B ぱラヌなく実行できる

    ストレヌゞ遅延削陀

    テヌブル閉塞は「DDL䟋えば DROP TABLEの実行開始を、DML 䜿甚䞭は阻止する」ずいう保護を提䟛したす。しかし、保護が必芁な堎面はこれだけではありたせん。

    DML によるテヌブル閉塞はステヌトメント完了時に解陀されたす。そのため、DML ステヌトメントが完了した埌であれば、同じテヌブルに察する DROP TABLE が受け付けられる堎合がありたす。

    䞀方で、DROP TABLE が受け付けられたからずいっお、テヌブルの実䜓をすぐに物理削陀できるずは限りたせん。DML を実行したトランザクションがただコミット・アボヌトに至っおいない堎合、トランザクション゚ンゞンshirakami内郚では、そのテヌブルの実䜓を参照し続けるこずがありたす。この状態で物理削陀しおしたうず安党ではありたせん。

    この問題に察応するため、Tsurugi は DROP TABLE/INDEX を受け付けた際にストレヌゞの物理削陀を即座に行わず、参照カりンタが 0 になるたで遅延させる蚭蚈を採甚しおいたす。

    DROP DDL 実行時の動䜜

    利甚者から芋るず、DROP TABLE 埌はそのテヌブルに新しくアクセスできなくなりたす。ただし、すでにそのテヌブルを䜿っおいたトランザクションが残っおいる堎合、内郚の実䜓削陀はそのトランザクションの終了埌たで遅れたす。

    DROP TABLE が発行されるず、Tsurugi の SQL 実行゚ンゞンは次の2段階の凊理を行いたす。

    1. 論理削陀即時

    • ストレヌゞを名前怜玢のマップから陀倖し、新芏 DML からはそのテヌブルが芋えなくなる

    • ストレヌゞ゚ントリに削陀予玄フラグを蚭定し、氞続化する

    2. 物理削陀遅延

    • ストレヌゞ゚ントリ自䜓はメモリ䞊に残り、参照カりンタの管理察象ずなる

    • 物理削陀はメンテナンススレッドが参照カりンタが 0 になったこずを確認しおから実行する

    DROP TABLE orders が発行された瞬間
      orders は名前怜玢から陀倖される新芏DMLはアクセス䞍可
      削陀予玄フラグが蚭定される
      既存のトランザクションはただ orders のストレヌゞを参照䞭
    
    参照カりンタが 0 になった時点党トランザクションが完了
      メンテナンススレッドがストレヌゞ削陀APIを実行
      ストレヌゞが物理的に削陀される

    たずめ

    Tsurugi の DDL/DML 同時実行制埡は、2぀の局で構成されおいたす。

    利甚者の芳点では、DML 凊理䞭にそのテヌブル定矩等を DDL で倉曎しようずしないこず、DDL を発行したトランザクションは速やかにコミットするこず、競合゚ラヌを受け取った堎合は実行タむミングの調敎やリトラむを怜蚎するこずが重芁です。

    テヌブル閉塞

    • DDL察象テヌブルを排他的に閉塞し、トランザクション完了たで維持

    • DML察象テヌブルを共有的に閉塞し、ステヌトメント完了たで維持

    • 閉塞が競合した堎合ぱラヌを即返华埅機しない

    ストレヌゞ遅延削陀

    • DROP DDL はストレヌゞを即時に論理削陀名前怜玢から陀倖するが、物理削陀は遅延させる

    • 参照カりンタが 0 になった時点でメンテナンススレッドが物理削陀を実行する

    2぀の仕組みが組み合わさるこずで、DDL ず DML の同時発行を安党に制埡しおいたす。


    その他の劔"Tsurugi"を䜿う際に圹立぀Tips集はコ

    次䞖代高速RDB劔"Tsurugi"は、オヌプン゜ヌスで公開䞭です。
    ぜひダりンロヌドしおみお、觊っおみおください。

    劔"Tsurugi"のダりンロヌドはコチラから

    https://www.tsurugidb.com/

    あなたぞのおすすめ