8.事務の浅い分析

5084 ワード

取引


トランザクションの正しい実行により、データベースがある状態から別の状態に変換されます.

トランザクションのプロパティ(ACID)


A atomicity:成功か失敗か--undo,mvcc C consistency:状態一致,データ整合性制約--開発者に対する要求I isolation:トランザクション間相互隔離,影響できない--lock,undo,mvcc D durability:トランザクションが正しくコミットされ,永続的に保持されなければならない--redo,wal

同時トランザクションの問題


ダーティリード:リードがコミットされていない、データが異なる(update)重複リード不可*:同じトランザクションが異なるデータに読み込まれる幻リード:レコードが異なる(delete/insert)

トランザクション独立性レベル


独立性レベル
汚読
繰り返し不可
まぼろし読み
read uncommit
はい
はい
はい
read commit--pgデフォルト
いいえ
はい
はい
repeatable read
いいえ
いいえ
はい
serialiable
いいえ
いいえ
いいえ
------pgは3種類実現しており、READ UNCOMMITTEDはREAD COMMITTEDと同様

pgにおけるトランザクション制御

  • begin:トランザクション
  • を開きます.
  • commit:提出
  • rollback:ロールバック
  • psql:デフォルトautocommit-set AUTOMMIT off
  • を閉じる
  • デフォルトautocommit
  • MVCC


    Multi-Version Concurrency Control:マルチバージョン同時制御pgの実現方法:update/delete既存行を保持し、sertレコードを再insertし、古いデータはvacuumでクリーンアップする

    トランザクション番号TXID

  • トランザクションがオープンするたびに、トランザクションマネージャは、トランザクションID(TXID)
  • と呼ばれる一意の識別子を割り当てる.
  • txid 32ビット符号なし整数、最大2^32
  • トランザクションの開始により、txid_が組み込まれます.Current()は、現在のtxid
  • を返します.
  • txid_Current()は現在のトランザクションIDを取得し、現在はトランザクションがなく、
  • を割り当てます.
  • txid_current_if_assigned()は同じで、現在はトランザクションがなくnull
  • を返します.

    トランザクションに関する情報


    tuple headに存在する
  • xmin:ローバージョンのトランザクションID
  • を挿入
  • xmax:この行のトランザクションID(delete/update)を削除し、クエリ>0、未commit or rollback
  • を示します.
  • cmin:insert、このトランザクションのdmlのシーケンス、0から
  • cmax:update/delete、このトランザクションのdmlのシーケンス、0から
  • ctid:oracle rowid()と同様に、ローバージョンはテーブル内の物理的な位置で、updateとvacuum fullは
  • に変更されます.

    トランザクションの実装


    各行にはxminとxmaxの2つのフィールドがあります
  • insert:xminは現在のトランザクションID、xmaxは0
  • update:実際にはinsertの新しい行で、同じです.同時に、古い行のxmaxは現在のトランザクションID
  • に設定.
  • delete:現在のローのxmaxを現在のトランザクションIDとして1ローに読み込むように設定すると、xminとxmaxに対応するトランザクションステータス:committed、aborted、in progressがクエリされ、次のローが現在のローに対して
  • が表示されるかどうかを判断します.

    トランザクションIDの増加

  • 1.無限の成長はありません最大2^32
  • 2.txidから最大値まで、また最小値3から
  • 0:InvalidXID、無効なトランザクションID
  • 1:BootstrapXIDは、システムテーブルの初期化時のトランザクションIDを表し、通常のトランザクションIDよりも古い
  • 2:FrozenXID、固定されたトランザクションID、通常のトランザクションIDよりも古い
  • 3.同じデータベースに存在する最も古いトランザクションと最新のトランザクションの間の年齢は、最大2^31
  • です.
  • pgのトランザクション番号は、最大2^32シーケンス番号の半分の
  • にすぎません.
  • pgは、データファイルの古いトランザクションIDを定期的にクリーンアップし、すべての通常のトランザクションIDよりも古い
  • にします.

    トランザクション可視性判定

  • 1.通常のトランザクションの比較方法((int 32)(id 1-id 2))<0式が真であればid 1はid 2より古く、偽であればid 1はid 2より
  • 新しい
     ID 2^32 , id 2^31 +1
    2^32 - (2^31+2) = 2147483646
     
    111 1111 1111 1111 1111 1111 1111 1110 > 0
    
     ID 2^32, , 3
    2^32 - 3 = 4294967293
     
    1111   1111  1111  1111  1111  1111  1111 1101 < 0
    
  • 2.BootstrapXIDは、FrozenXID
  • を含む他のすべてのトランザクションよりも古い.
  • 3.FrozenXIDは通常のトランザクションより古い
  • 4.データの各sqlには独自のトランザクション番号があり、このトランザクション番号はSnapshotDataに記入され、スナップショットのtxidとtupleのxminとxmaxを比較することで、現在のローが現在のトランザクションに対して表示されているかどうかを判断する.

  • トランザクションスナップショット関連関数


    txid_current_snapshot()現在のスナップショットを取得txid_snapshot_xip(txid_snapshot)スナップショットで実行中のトランザクションID txid_を取得snapshot_xmax(txid_snapshot)スナップショットのxmax txid_を取得snapshot_xmin(txid_snapshot)スナップショットのxmin txid_を取得visible_in_snapshot(bigint,txid_current_snapshot)スナップショットにトランザクションIDが表示されるかどうか(サブトランザクションIDを使用しない)txid_status(bigint)は、現在のトランザクションのステータス、committed、aborted、in progress、またはトランザクションIDが古い場合nullを取得します.

    現在のスナップショットの取得


    txid_current_snapshot()形式xmin:xmax:xip_list
  • xmin:最も早くアクティブなトランザクションID(以下、XIDと略称する)は、このXIDより早いトランザクションがコミットされて表示されるか、ロールバックされるか、破棄されるかのいずれかです.
  • xmax:最終完了トランザクション(COMMITTED/ABORTED)のトランザクションID+1.
  • xip_List:スナップショットを撮影しても進行中のトランザクションID.このリストには、xminとxmaxの間のアクティブなトランザクションIDが含まれます.

  • 要約すると、簡単に言えば、所与のXID:XID∈[1,xmin)について、過去のトランザクションは、このスナップショットに対してすべて表示される;XID∈[xmin,xmax)は、サブトランザクションの状況を考慮せず、依然としてIN_PROGRESS状態にある、非表示;COMMITED状態、可視;ABORTED状態、非表示;XID∈[xmax,∞)は、将来のトランザクションは、このスナップショットに対してすべて表示されない;
    --session 1
    testdb=# begin;
    BEGIN
    testdb=# select txid_current();
     txid_current
    --------------
             1303
    testdb=# select txid_current_snapshot();
     txid_current_snapshot
    -----------------------
     1303:1303:
    
    --session 2
    testdb=# begin;
    BEGIN
    testdb=# select txid_current();
     txid_current
    --------------
             1304
    
    --session 3
    testdb=# begin;
    BEGIN
    testdb=# select txid_current();
     txid_current
    --------------
             1305
             
    --session 4
    testdb=# begin;
    BEGIN
    testdb=# select txid_current();
     txid_current
    --------------
             1306
    
    --session 1
    testdb=# select txid_current_snapshot();
     txid_current_snapshot
    -----------------------
     1303:1303:
     
    --session 4
    testdb=# rollback;
    ROLLBACK
    
    --session 1
    testdb=# select txid_current_snapshot();
     txid_current_snapshot
    -----------------------
     1303:1307:1304,1305
    
    --session 3
    testdb=# rollback;
    ROLLBACK
    
    --session 1
    testdb=# select txid_current_snapshot();
     txid_current_snapshot
    -----------------------
     1303:1307:1304