Postgres Vaccum


どうやって見つけたの?


高速で記述されたコードを再記述し、以前のログを発見します.約10分ごとに100回を超えるInsert/Updateが同時に発生します.
RDSパフォーマンスヘルプでは、autovacuumというクエリが常に自動的に実行されます.

なんだと思って確認した内容△私は最近、ファイル処理を聞いていますが、今の実現と似ているので面白いです.今回の任務は大変でしたが...)

Vacuum


これはPostgres独自の内容で、SQLiteにも似たような概念があります.
Vacuumには4つの運転条件があり、そのうちの2つだけを紹介します.

空間多重化Vacuum


マルチバージョン同期制御(MVCC)の実施によるパターン概念による問題を解決する方法.(削除してコミットしたデータが別のトランザクションで使用されている場合は、この問題を解決する必要があります.)
PostgreSQLは、tupleの形式ですべてのデータを格納します.すべてのtupleはlive tupledead tupleに分けられ、参照されないtupleはdead tupleと呼ばれる.
特定のColumn、Rowを更新するトランザクションを実行する場合は、MVCCに対して次の操作を実行します.
  • FSMの可用性を確認し、ない場合はFSM(FSMファイル形式で格納)
  • を追加する.
    更新されたデータは、
  • FSMの空き領域に書き込まれ、tupleが追加される.
  • 既存のポインタを新しいtuple
  • に変換する.
  • 以前の情報についてのチュートリアルは参考にならなかったので、dead tupleになりました.
  • **仮想マシン(Visibility map):アクティブなtupleに関する情報を含む
    **Free space map(FSM):空き領域に関する情報を含む
    ここのVacuum
    dead tupleをFSMに戻して再開する操作
    すべてのUpdateは事実上Insertと同じである.Deleteまた、VacumがなければFSMに戻ったり、リポジトリから削除したりすることはなく、無限成長の問題が発生します.
    dead tupleが多すぎて、1ページのファイルを読み込むときに見つからないtupleが多くなり、より多くのI/Oが発生します.
    dead tupleが多すぎて、カーネルは直接indexを書かないでください!判断を下す.

    TupleクリーンアップにおけるVacuumの動作


    Vacuum
    テーブルまたはインデックスから削除したデータをクリーンアップしてFSMに戻すことで、オペレーティングシステムの観点から容量を解放できます.
    Full Vacuum
    資料を収集して新しい表を作成→大量の時間を費やして表ロックを作成→Depeciate表を主とする
    Autovacuum
    解析とフリーズコマンドを自動的に実行します.デフォルトでは、自動真空オプションがオンになっており、プロファイルにはデフォルトの設定値が含まれています.
  • 自動真空threshold:真空を生成するために使用されるデッドユニットの最小数.既定値は50です.
  • 自動真空scale factor:真空を生成するためのアクティブデバイスと比較して、デッドデバイスの最小割合.既定値は0.2です.
  • 100,000 건의 데이터에서 autovacuum 이 일어나기 위한 dead tuple 개수
    
    (100,000 * 0.2) + 50 = 20,050
    次のコマンドを使用して、特定のテーブルで真空が実行されたタイミングを決定します.
    SELECT relname, last_vacuum, last_autovacuum, last_analyze, last_autoanalyze
    FROM pg_stat_user_tables
    ORDER BY relname asc;

    トランザクションID管理Vacuum(真空冷凍)


    PostgreSQLでは、1つのtupleに2つのxidがあります.
  • xmin:Id
  • 、インスタンスのインストール時に後続のトランザクションを表示
  • xmax:更新、削除時の時点Id

  • 上の図に示すように、min-max間にトランザクションIDを持つユーザのみがデータを表示でき、他の場合はデータを表示できません.
    40億個のIDが使用可能で、書き終わったらIDは1です.そうなるとID 1の友達、xmin 40億の友達が自分より大きくて調べられません.
    私より年上の友達をFreeze Markと表記し、無条件にolderと見なします

    XID側のvacum

    autovacuum_freeze_max_age = 1000   vacuum_freeze_min_age = 100テーブルのageが1000に達した場合(xidが1増加するごとにageも1増加する)は、最近のxidログを100個保持し、残りは削除します.以降のageは100
    →xidで以前に作成したテーブル100個のように
    **Refrezenxid:真空操作を行うxid(実際の実行時のxid-evice freeze min age値を持つ)

    Analyze


    クエリー・アクチュエータは、各テーブルに格納された統計データを生成し、pg_statisticに格納します.このプロシージャは、analyzeを使用して生成されるか、autovacuumで自動的に実行されます.
    select * from pg_stats where tablename = 'persons' and attname = 'first_name';
    schemaname        | public
    tablename         | persons
    attname           | first_name
    inherited         | f
    null_frac         | 0
    avg_width         | 11
    n_distinct        | -0.484307
    most_common_vals  | {"John","Mary"...
    most_common_freqs | {0.00867898,0.00640832...
    histogram_bounds  | {-,"AAA"...
    correlation       | 0.00826469
    このような情報が生成されます.PGこの情報に基づいて計画を立ててクエリーを実行する

    Index


    Bツリーインデックスは、単純に平行ツリーと考えることができる.

    dead tupleが真空になったので、インデックスも一緒に更新されません.したがって,真空が出現し一定時間経過すれば,インデックスを再生し,速度を向上させることもできる.

    InnoDB purge


    PGロールバックセグメントのようなデータを格納するアドレス

    InnoDBパージコーディネータ/workerは、プロセスとして常駐し、計画と空きスペースを作成する友人です.

    リファレンス


    https://bstar36.tistory.com/308:XIDトランザクションID重複防止https://postgresql.kr/docs/9.4/routine-vacuuming.html#AUTOVACUUM:Vacuum
    https://nrise.github.io/posts/postgresql-autovacuum/#fn:2 : Vacuum