でのコピー進行


PostgreSQLからYugabyteDBへの移行を評価したい場合は、次のようにします:
  • PGRANTダンプからのメタデータ( DDL )を読み込む
  • データをロードします
  • アプリケーションのテスト
  • 私がそれのために使った若干の速いスクリプトは、ここにあります.そして、JSONのHTTPエンドポイントからPostgreSQLのテーブルにデータをインポートするために何ができるかを考えることができます.

    DDL変更
    生成されるDDLpg_dump テーブルを作成し、プライマリキーを追加します.これは、テーブルがヒープテーブルであり、プライマリキーインデックスが二次インデックスであるので、PostgreSQLでは結構です.ただし、プライマリキーに従って、組織化されたLSMツリー(ハッシュ、範囲、ソートによってシャープ)に格納されます.MySQLのテーブルと同様に、SQL Serverでインデックスをクラスタ化したり、Oracleのインデックスを整理したテーブルですが、水平方向のパーティションをスケールアウトします.したがって、Create TableとALTER TABLEを実行してプライマリキーを追加すると、生成されたUUIDで作成し、テーブルを再編成します.空のテーブルでは、これは大したことではありませんが、CREATE文ですべてを行います.それをする一つの方法はyb_dump , ユベンガットのフォークpg_dump , PostgreSQLからエクスポートするにはしかし、あなたがすでに持っているならば、...SQLファイルは、次のように修正します.
    awk '
    # gather primary key definitions in pk[] and cancel lines that adds it later
    /^ALTER TABLE ONLY/{last_alter_table=$NF}
    /^ *ADD CONSTRAINT .* PRIMARY KEY /{sub(/ADD /,"");sub(/;$/,"");pk[last_alter_table]=$0",";$0=$0"\\r"}
    # second pass (i.e when NR>FNR): add primary key definition to create table
    NR > FNR && /^CREATE TABLE/{ print $0,pk[$3] > "schema_with_pk.sql" ; next}
    # disable backfill for faster create index on empty tables
    /^CREATE INDEX/ || /^CREATE UNIQUE INDEX/ { sub("INDEX","INDEX NONCONCURRENTLY") }
    NR > FNR { print > "schema_with_pk.sql" }
    ' schema.sql schema.sql
    
    これはDDLの主キー定義を取得するための迅速でダーティな2つのパスです.
    空のテーブルでそれらを作成するときに、バックフィルを無効にするようにCREATE INDEXも変更します.前のブログ記事の詳細情報はこちら

    DDLオーダー
    おそらく、ロード後のセカンダリインデックスを作成することになりますが、データを読み込む前に、DDL全体を一度実行するのが好きです.私はDDLファイルを、テーブル(主キーを持つ)だけをロードする前にロードします.

    非交流負荷
    最初の負荷については、multi-row transactional layer (酸のAとIに関して緩んでしまうことがあるので、負荷の間には誰も問い合わせません).これはysql_non_txn_copy=true tserver :

    これは負荷を2倍速くすることができますが、そのデフォルト値ysql_non_txn_copy=false 負荷の後.
    基本的にすべての行が挿入されるsingle-row transactions

    コピー進行
    その後、データのテラバイトをインポートすることができます.これには時間がかかります(これを最適化するための作業があります).我々はデフォルトですべてのrows_per_transaction ) あなたはselect count(*) しかし、それは巨大なテーブルで時間がかかります.
    私たちはタブレットサーバから多くの統計を持っていますhttp://yb1.pachot.net:9000/metrics , JSONとしてしかし、POCの場合は、統計情報のコレクションを設定していない可能性があります統計情報を簡単に見てください.
    テンポラリテーブルにすべてのタブレットメトリクスを集めるスクリプトです.
    -- create a temporary table to store the metrics:
    
    drop table if exists my_tablet_metrics;
    create temporary table if not exists my_tablet_metrics (
     table_id text,tablet_id text
     ,namespace text, table_name text
     ,metric text, value numeric
     ,tserver text
     ,timestamp timestamp default now()
    );
    
    -- gather the metrics from the tserver:
    
    do $do$ 
     declare
      tserver record;
     begin
      -- gather the list of nodes and loop on them
      for tserver in (select * from yb_servers())
       loop
        -- use COPY from wget/jq to load the metrics
        execute format($copy$
         copy my_tablet_metrics(table_id,tablet_id
         ,namespace,table_name
         ,metric,value,tserver)
         from program $program$
          wget -O- http://%s:9000/metrics | 
          jq --arg node "%s" -r '.[] 
           |select(.type=="tablet") 
           |.attributes.table_id+"\t"+.id
           +"\t"+.attributes.namespace_name
           +"\t"+.attributes.table_name
           +"\t"+(.metrics[]|select(.value>0)
           |(.name+"\t"+(.value|tostring)))
           +"\t"+$node
           '
         $program$
        with (rows_per_transaction 0)
       $copy$,tserver.host,tserver.host);
       end loop;
     end; 
    $do$;
    
    -- aggregate the per-tablet row insertion metrics:
    
    select sum(value),format('%I:%I',namespace,table_name) 
    from my_tablet_metrics where metric='rows_inserted'
    group by 2 order by 1
    ;
    
    
    私はここからプログラムのサーバー側のコピーを使用しますwget HTTPエンドポイントとjq JSON構造をタブ区切りのテキストに変換するには.
    以下はNorthwindデモスキーマの読み込み後の例です.

    データベースのバージョンを選択するには、for listのtserverノードのリストを指定します.
    for s in yb{1..2}.pachot.net # <<-- list of nodes
    do
          wget -qO- http://$s:9000/metrics | 
          jq --arg node "$s" -r '.[] 
           |select(.type=="tablet") 
           |.attributes.table_id+"\t"+.id
           +"\t"+.attributes.namespace_name
           +"\t"+.attributes.table_name
           +"\t"+(.metrics[]|select(.value>0)
           |(.name+"\t"+(.value|tostring)))
           +"\t"+$node'
    done | awk '
    /rows_inserted/{s[$3":"$4]=$(NF-1)+s[$3":"$4]}
    END{for(i in s)printf "%15d %s\n",s[i],i}
    ' | sort -n
    

    平行コピーする
    理想的には、PGSUNE READUREを使用して並列ジョブで実行するための形式でpgdelta dumpを生成しました.そうでない場合は、3つのtheadsにすばやく分割する方法を示します.
    n=3
    for i in {1..3}
    do
    awk '
    # end of data
    /^\\.$/{data=0}
    # print data only on modulo threads = thread
    data==0||(NR%threads+1==thread){print}
    # begining of data
    /^COPY/{data=NR+1}
    ' threads=$n thread=$i my_plain_text_dump.sql | psql &
    done
    time wait
    

    行をカウント
    大きなテーブルでは、count (*)はtimeoutで長時間と失敗します.もちろん、タイムアウトを増やすことができますが、行の数のアイデアを得るために最も簡単にテーブルを分析し、統計情報を照会することです.
    do $$ declare r record; begin for r in (
    select schemaname,relname,n_live_tup,last_analyze,analyze_count 
    from pg_stat_user_tables where last_analyze is null
    ) loop
    execute format('analyze %I.%I',r.schemaname,r.relname);
    end loop;
    end; $$ ;
    
    select schemaname,relname,n_live_tup,last_analyze,analyze_count
     from pg_stat_user_tables where last_analyze is not null order by 1,2;
    
     schemaname | relname | n_live_tup |         last_analyze          | analyze_count
    ------------+---------+------------+-------------------------------+---------------
     public     | orders  |   47653008 | 2021-10-29 18:39:13.788017+00 |             1
    
    あなたがあなたのPostgreSQLをYugabyteにロードするとき、どんな問題でも見つけるならば、我々に手を差し伸べてくださいhttps://www.yugabyte.com/community ) ロードマップにはたくさんのものがあります.