Closed 0-kaz closed 1 week ago
Fallback処理の場合、executor.c
のtryExecCpuFallbackChunks
という関数でfallback行をフェッチされるはずなので、
まずは、この関数が呼び出されているのか(⇒呼び出されてなければ、fallbackバッファが返されてない)、
呼び出されていれば、そもそも行が取り出されているのかをチェックしてみると良いかもしれません。
Memo: PG16でも発生。
SET pg_strom.enabled = on;
SET pg_strom.cpu_fallback = on;
SELECT id INTO gpuresult FROM testdata WHERE memo LIKE '%abc%';
SET pg_strom.enabled = off;
SELECT id INTO cpuresult FROM testdata WHERE memo LIKE '%abc%';
(SELECT * FROM gpuresult EXCEPT ALL SELECT * FROM cpuresult) order by id;
結果:
id
-------
573
573
6642
6656
9545
13427
15693
20634
(8 rows)
元テーブルの結果をselect→insertしているだけなのに、ユニークなはずのIDが重複している。 fallbackの過程でデータが不正な状態となっている可能性が大きい。
select * from gpuresult where id=573;
id
-----
573
573
573
(3 rows)
比較的簡単そうと思って振りましたが、めちゃくちゃエグいバグでした…。
54176d243f0a9167bac5097b9e87f91ac585aec4
で修正していますが、発生の機序はこうです。
wp->smx_row_count
を元に、各スレッドがフェッチする行を特定する。wp->smx_row_count
に係数を掛けて行インデックスを確定した後、即座にwp->smx_row_count
をインクリメントするwp->smx_row_count
に係数を掛けて行インデックスを計算するwp->smx_row_count
は更新後の値なので、通常は512行が読み飛ばされてしまう。⇒ 結果不正合ちなみに、KDS_FORMAT_BLOCK
の場合だけは、たまたま、CPU-Fallbackの可能性が無くなってからwp->smx_row_count
を更新するという構造になっていたので、pg_strom.gpudirect_enabled
のオンオフで当該現象が切り替わるというように見えていたようです。
postgres=# SET pg_strom.gpudirect_enabled = on;
SET
postgres=# SELECT count(id) FROM testdata WHERE memo LIKE '%abc%';
NOTICE: GpuPreAgg: CPU fallback 1 tuples (144B)
count
-------
164
(1 row)
postgres=# SET pg_strom.gpudirect_enabled = off;
SET
postgres=# SELECT count(id) FROM testdata WHERE memo LIKE '%abc%';
NOTICE: GpuPreAgg: CPU fallback 1 tuples (144B)
count
-------
164
(1 row)
ありがとうございます。解消確認出来ました。 PG16、PG17の両方で確認。
fallback_pgsql.sqlの動作確認で発見。
確認コミット:fd4c07d7c36dc190d9ab99b3d56d5d3b2bcd9405
以下再現クエリ。