heterodb / pg-strom

PG-Strom - Master development repository
http://heterodb.github.io/pg-strom/
Other
1.3k stars 162 forks source link

[VTJ-JP]pg2arrow fails in parallel mode #824

Closed sakaik closed 1 month ago

sakaik commented 1 month ago

概要

pg2arrow が パラレルモードの引数 n の値を大きくしたときにエラーになりました。(今回のケースでは n=5はOK、n=6以上でエラー)

問題なくarrowファイルが出力されたコマンド例

$ pg2arrow -upostgres -dsakaitest_nvme5 -tarrowdir_tmp1 -o /out/test.arrow
$ pg2arrow -upostgres -dsakaitest_nvme5 -tarrowdir_tmp1 -n2 -o /out/test.arrow
$ pg2arrow -upostgres -dsakaitest_nvme5 -tarrowdir_tmp1 -n5 -o /out/test.arrow

エラーとなったコマンドとそのエラー内容

$ pg2arrow -upostgres -dsakaitest_nvme5 -tarrowdir_tmp1 -n6 -o /out/test.arrow
pgsql_client.c:1063  SQL query has empty results: SELECT * FROM arrowdir_tmp1 WHERE ctid >= '(163840,0)'::tid
$ pg2arrow -upostgres -dsakaitest_nvme5 -tarrowdir_tmp1 -n7 -o /out/arrowdirtest/test.
arrow
pgsql_client.c:1063  SQL query has empty results: SELECT * FROM arrowdir_tmp1 WHERE ctid >= '(196608,0)'::tid
pgsql_client.c:1063  SQL query has empty results: SELECT * FROM arrowdir_tmp1 WHERE ctid >= '(163840,0)'::tid AND ctid < '(196608,0)'::tid

再現方法

データ生成用スクリプト

データ生成のために以下のPythonスクリプトを作成します

def make_random_str(len): return ''.join(random.choices(string.ascii_letters + string.digits, k=len))

def main(id):

rows = 33554432

rows =  10000000
#rows =  10
for i in range(0, rows):
    no = i
    rand = make_random_str(18)
    x = rand[0:16]
    y = rand[1:17]
    z = rand[2:18]
    a = x[3:11]
    b = x[4:12]
    print ('%s\t%s\t%s\t%s\t%s\t%s\t%s' % (id, no, x,y,z,a,b))

if name == "main": if len(sys.argv)>1: id = sys.argv[1].zfill(5) else: id = "99999" main(id)


### データの登録
以下のコマンドラインでテーブル作成ならびにデータ登録

DB_NAME=sakaitest_nvme5 echo "CREATE TABLE mytmp (id char(5), no integer, x varchar(20), y varchar(20), z varchar(20), a varchar(20), b varchar(20));" | psql -Upostgres -d ${DB_NAME} python3 makeArrowTestData.py 1 | psql -Upostgres -d ${DB_NAME} -c "\COPY mytmp FROM STDIN"


### Arrow動作の確認
今回の手元での確認例では、 以下の n パラメタの値が 6以上でエラーとなりました。

pg2arrow -u postgres -d ${DB_NAME} -t mytmp -n12 -o ./test.arrow


結果(error)例

pgsql_client.c:1063 SQL query has empty results: SELECT FROM mytmp WHERE ctid >= '(229376,0)'::tid AND ctid < '(262144,0)'::tid pgsql_client.c:1063 SQL query has empty results: SELECT FROM mytmp WHERE ctid >= '(262144,0)'::tid AND ctid < '(294912,0)'::tid

kaigai commented 1 month ago

なるほど、『一件もデータが存在しなかった』はシングルプロセスの場合にはエラーで良い(空のApache Arrowファイルが生成される)ですが、並列モードだと 0 件を他のスレッドとマージするという操作が必要になりそうですね。

kaigai commented 1 month ago

9389fb758eab82af905543fe7a37097d6e55ca62 で修正を入れてみましたが、いかがでしょう? 本質的にはワーカーの一個で empty results になっただけのものを、全体のエラーとして扱った事が原因のようです。

sakaik commented 1 month ago

9389fb の pg2arrow で現象が発生しなくなることを確認しました。