SlideShare a Scribd company logo
CustomScan APIを使い倒して俺様DBエンジンを実装する
ヘテロDB株式会社
チーフアーキテクト 兼 CEO
海外 浩平 <kaigai@heterodb.com>
CustomScan APIとは?
postgres=# explain select sum(lo_revenue), d_year, p_brand1
from flineorder, date1, part
where lo_orderdate = d_datekey
and lo_partkey = p_partkey
and p_category = 'MFGR#12’
group by d_year, p_brand1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------
HashAggregate (cost=3656703.22..3656773.22 rows=7000 width=22)
Group Key: date1.d_year, part.p_brand1
-> Custom Scan (GpuPreAgg) (cost=3656580.72..3656650.72 rows=7000 width=22)
Reduction: GroupBy (Global+Local [nrooms: 1974])
Group keys: d_year, p_brand1
Combined GpuJoin: enabled
-> Custom Scan (GpuJoin) on flineorder (cost=16028.65..3638534.69 rows=28873638 width=18)
Outer Scan: flineorder (cost=0.00..10277198.49 rows=720040849 width=12)
Depth 1: GpuHashJoin(nrows 720040849...28873638)
HashSize: 1135.95KB
HashKeys: flineorder.lo_partkey
JoinQuals: (flineorder.lo_partkey = part.p_partkey)
Depth 2: GpuHashJoin(nrows 28873638...28873638)
HashSize: 442.11KB
HashKeys: flineorder.lo_orderdate
JoinQuals: (flineorder.lo_orderdate = date1.d_datekey)
referenced: lo_partkey, lo_orderdate, lo_revenue
files0: /opt/pgdata14/f_lineorder.arrow (read: 8.05GB, size: 81.81GB)
-> Seq Scan on part (cost=0.00..5426.00 rows=8020 width=14)
Filter: (p_category = 'MFGR#12'::bpchar)
-> Seq Scan on date1 (cost=0.00..72.56 rows=2556 width=8)
(21 rows)
見覚えのない
実行計画があるなぁ…。
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
2
CustomScan APIとは?
▌概要
 エグゼキュータの一部を拡張モジュールによる
実装で置き換えたいときに利用するAPI
 拡張モジュールの開発者が利用するもので、
SQL経由でユーザが利用するものではない。
 PostgreSQL v9.5 (2016) で最初のバージョンが
提供されるようになった。
▌利点
 独自にSQL実行エンジンを強化したい場合でも、
PostgreSQLからのフォークを行わずに済む。
 自分が興味のある部分“だけ”を置き換える事が
できるので、開発規模を抑える事ができる。
IndexScan on table-Y
CustomScan (MyScan) on table-X
CustomScan (MyJoin)
Agg (Group By)
NestLoop
SeqScan on table-Z
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
3
CustomScan APIとFDW(Foreign Data Wrapper)の違い
▌FDW: Foreign Data Wrapper
 外部のデータをあたかもPostgreSQLのテーブルで
あるかのように読み書きするためのAPI
 何を(What?)スキャンするか。
▌CustomScan API
 PostgreSQLのテーブルを異なる方法でスキャン
するためのAPI
✓ 実装上、キャッシュを参照するなどの手法もアリ
 どのように(How?)スキャンするか
Foreign
Table
Foreign
Table
Foreign
Table
Foreign
Table
CSV
mysql_fdw oracle_fdw file_fdw arrow_fdw
MySQL
データベース
Oracle
データベース
CSV
ファイル
Arrow
ファイル PostgreSQL
テーブル
SeqScan IndexScan CacheScan
FpgaScan
DpuScan
GpuScan
columnar
cache
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
4
HeteroDB社について
▌会社概要
 商号 ヘテロDB株式会社
 設立 2017年7月4日
 資本金 999万円
 所在地 品川区北品川5-5-15
大崎ブライトコア4F
 事業内容
高速データベース製品の開発・販売
GPU&DB領域の技術コンサルティング
 受賞など
✓ IPA 未踏アドバンスト事業 第一期生(2017)
✓ GPU Technology Conference Japan 2017、Inception Award受賞
✓ 東京都ベンチャー技術大賞 技術奨励賞(2022)
▌代表者プロフィール
 海外 浩平|KaiGai Kohei
OSS開発者コミュニティにおいて、
PostgreSQLやLinux kernelの開発に
15年以上従事。主にセキュリティ・
FDWなどの技術領域に貢献する。
本日のテーマ CustomScan API や、
GPUを用いたSQL高速化モジュール・PG-Stromの開発者。
筑波大学情報学類卒(2001)、同大学院経営・政策科学研究
科修了(2003)、日本電気株式会社勤務(2003-2017)の後、
HeteroDB社を創業。
 受賞など
✓ IPA未踏ソフト「天才プログラマ―」認定(2006)
✓ OSS推進フォーラム OSS貢献者賞(2014)
✓ 日本情報処理学会 喜安記念業績賞(2014)
ヘテロジニアスコンピューティング技術をデータベース領域に適用し、
誰もが使いやすく、シンプルで高速なデータ解析基盤を提供する。
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
5
CustomScan APIの利用例 – Microsoft Azure Cosmos DB
出典: https://learn.microsoft.com/ja-jp/azure/cosmos-db/postgresql/tutorial-shard
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
6
CustomScan APIの利用例 – Google AlloyDB
出典: https://cloud.google.com/blog/ja/products/databases/alloydb-for-postgresql-columnar-engine
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
7
CustomScan APIの利用例 – HeteroDB PG-Strom
postgres=# explain select sum(lo_revenue), d_year, p_brand1
from flineorder, date1, part
where lo_orderdate = d_datekey
and lo_partkey = p_partkey
and p_category = 'MFGR#12’
group by d_year, p_brand1;
QUERY PLAN
-----------------------------------------------------------------------------------------------------
HashAggregate (cost=2631106.55..2631176.55 rows=7000 width=22)
Group Key: date1.d_year, part.p_brand1
-> Custom Scan (GpuPreAgg) (cost=2630984.05..2631054.05 rows=7000 width=22)
Reduction: GroupBy (Global+Local [nrooms: 1974])
Group keys: d_year, p_brand1
Combined GpuJoin: enabled
GPU Preference: GPU0 (NVIDIA A100-PCIE-40GB)
-> Custom Scan (GpuJoin) on flineorder (cost=14190.72..2612938.03 rows=28873638 width=18)
Outer Scan: flineorder (cost=0.00..10277198.49 rows=720040849 width=12)
Depth 1: GpuHashJoin(nrows 720040849...28873638)
HashSize: 1135.95KB
HashKeys: flineorder.lo_partkey
JoinQuals: (flineorder.lo_partkey = part.p_partkey)
Depth 2: GpuHashJoin(nrows 28873638...28873638)
HashSize: 442.11KB
HashKeys: flineorder.lo_orderdate
JoinQuals: (flineorder.lo_orderdate = date1.d_datekey)
GPU Preference: GPU0 (NVIDIA A100-PCIE-40GB)
GPUDirect SQL: enabled
referenced: lo_partkey, lo_orderdate, lo_revenue
files0: /opt/pgdata14/f_lineorder.arrow (read: 8.05GB, size: 81.81GB)
-> Seq Scan on part (cost=0.00..5426.00 rows=8020 width=14)
Filter: (p_category = 'MFGR#12'::bpchar)
-> Seq Scan on date1 (cost=0.00..72.56 rows=2556 width=8)
(24 rows)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
8
CustomScan APIの利用例 – FUJITSU Software Enterprise Postgres 9.5
出典: https://software.fujitsu.com/jp/manual/manualfiles/m160008/j2ul2119/05z200/j2119-00-13-01-00.html
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
9
SamsungのSmart-SSD開発チーム(?)の講演でも
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
10
PostgreSQL向けExtensionの開発
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
11
最小構成での PostgreSQL 拡張モジュールのビルド
$ ls
Makefile
ctidscan.h
ctidscan.c
ctidscan.sql
ctidscan.control
$ cat Makefile
MODULES = ctidscan
EXTENSION = ctidscan
DATA = ctidscan.sql
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
$ cat ctidscan.control
# ctidscan extension
comment = 'example module for custom-scan api’
default_version = '1.0'
module_pathname = '$libdir/ctidscan'
relocatable = true
✓ PostgreSQL向け拡張モジュールは、メジャー
バージョン跨ぎのバイナリ互換性の保証なし。
✓ ビルド時の ./configure 次第で変わるパラメータ
例:BLCKSZの定義やAssertの有無、構造体のレイアウトも
✓ ターゲットとなるPostgreSQLに同梱の pg_config を
利用してビルドオプションの同一性を担保する。
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
12
拡張モジュールが制御を獲得するタイミング
#include “postgres.h”
:
:
void
_PG_init(void)
{
DefineCustomBoolVariable("enable_ctidscan",
"Enables use of ctidscan”,
NULL,
&enable_ctidscan,
true,
PGC_USERSET,
GUC_NOT_IN_SAMPLE,
NULL, NULL, NULL);
:
/* registration of the hook to add alternative path */
set_rel_pathlist_next = set_rel_pathlist_hook;
set_rel_pathlist_hook = SetCtidScanPath;
}
✓ PostgreSQLが拡張モジュールをロードすると、
まず _PG_init() 関数を呼び出す。
✓ 拡張モジュールをロードするタイミングは…
✓ その拡張モジュールで実装されているSQL関数の呼び出し。
✓ (shared|local|session)_preload_libraries パラメー
タによる指定。
✓ SQLのLOADコマンド
➔ CustomScan APIを使用する拡張モジュールの場合は、
*_preload_libraries パラメータを使うのが自然。
✓ 拡張モジュールで制御を獲得するには?
✓ “C”で実装されたSQL関数の実行
➔ 演算子やSQL関数、インデックスの評価やFDWなど、
大半のケースではこちら。
✓ フック、コールバックで登録されたタイミング
➔ CustomScan APIでは、一連の処理の中でSQL関数を必要と
する場面がないため、_PG_init() でフックやコールバックの
登録を済ませておく。
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
13
比較的シンプルな CustomScan のサンプル
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
14
▌https://github.com/kaigai/ctidscan
 検索条件に ctid システム列(*)に対する大小比較を含む
場合、明らかにマッチしないブロックを読み飛ばす。
 PostgreSQL v14で対応した TidRangeScan と同等だが、
CustomScan APIの提案時には 意味のある拡張モジュール
だった。
✓ (*) ctidシステム列は、タプルの存在するブロック番号と
アイテム番号を示す。
PostgreSQLはどのように実行計画を作るのか
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
15
PostgreSQLがクエリを処理する流れ
SQL Parser
Query Optimizer
Query Executor
Buffer
Manager
SQLクエリ
パース木
クエリ実行計画
クエリ 実行結果
 SQL構文を分解し、取り扱いやすい
内部データ形式(パース木)に変換
 文法エラーの検出
 統計情報を元にコスト値を算出
 最も合理的と予想される実行計画を作成する。
 クエリ実行計画に基づいて、
ScanやJoin、Sortなどの処理を実行する。
 PostgreSQL内部のインフラを使用
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
16
Transaction
Control
Resource
Management
IPC, Shared
Memory
クエリの実行をサポートする
多種多様な内部インフラが
用意されている。
PostgreSQLはどのように実行計画を作るか
t0 JOIN t1の候補パス
Scan
t0
Scan
t1
Join
t0,t1
統計情報)
nrows: 120万行
width: 80
インデックス:なし
候補パス
HashJoin
cost=4000
候補パス
MergeJoin
cost=12000
候補パス
NestLoop
cost=99999
候補パス
Parallel
Hash Join
cost=3000
候補パス
GpuJoin
cost=2500
WINNER!
PostgreSQLビルトインの実行パス
拡張モジュールによる提案
(PostgreSQL v9.5以降)
(PostgreSQL v9.6以降)
GpuJoin
t0,t1
統計情報)
nrows: 4000行
width: 120
インデックス:id列
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
17
PostgreSQLがクエリを処理する流れ
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
18
▌リレーション(Scan, Join, ...)に紐づいた
候補パス(Path構造体)を作成する。
✓ Pathには実行コストや、実行結果の出力順
(ソートされているか否か)などを保持する。
✓ ビルトインの実行計画の他に CustomPath を作成
する事ができれば、ここに突っ込む。
▌オプティマイザは最もコストの安い候補パスを
選択し、Path ⇒ Plan 構造体に変換する。
✓ Pathと異なり、Plan構造体は copyObject などの
内部APIを用いて操作できる。
▌式表現の書き換え
✓ 場合によっては、オプティマイザにヒントを与える
必要がある(custom_scan_tlist)
SQL Parser
Query Optimizer
Query Executor
SQLクエリ
パース木
クエリ実行計画
クエリ 実行結果
set_rel_pathlist_hook による実行計画の登録
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
19
/* Hook for plugins to get control in set_rel_pathlist() */
typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root,
RelOptInfo *rel,
Index rti,
RangeTblEntry *rte);
extern PGDLLIMPORT set_rel_pathlist_hook_type
set_rel_pathlist_hook;
static void
SetCtidScanPath(PlannerInfo *root, RelOptInfo *baserel,
Index rtindex, RangeTblEntry *rte)
{
/* call the secondary custom-scan provider */
if (set_rel_pathlist_next)
set_rel_pathlist_next(root, baserel, rtindex, rte);
:
/*
* 1. リレーション種別や検索条件をチェック
* 2. CustomPathを作成し、CustomPathMethods を登録
* 3. add_path()を使ってパスを登録
*/
✓ set_rel_pathlist_hook はいつ呼ばれるのか?
➔ 特定のテーブルに対して、オプティマイザが
スキャンする方法を検討するタイミング。
✓ ビルトインのスキャン方法
• SeqScan
• IndexScan
• BitmapHeapScan
• TidScan
• ForeignScan
➔ ここに割り込んで、『俺々CustomScan』の方が
より効率的にこのテーブルをスキャンできると
いう事を教えてやる。
CustomPath構造体
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
20
typedef struct Path
{
NodeTag type;
NodeTag pathtype;
RelOptInfo *parent;
PathTarget *pathtarget;
ParamPathInfo *param_info;
:
Cardinality rows;
Cost startup_cost;
Cost total_cost;
List *pathkeys;
} Path;
typedef struct CustomPath
{
Path path;
uint32 flags;
List *custom_paths;
List *custom_private;
const struct CustomPathMethods *methods;
} CustomPath;
▌CustomPath構造体
 『俺ならこれぐらいの処理コストで実行できる』を
PostgreSQLのオプティマイザに教えてやるための
データ構造。
 Path中の rows, startup_cost, total_cost で
処理コストを表現する。
 methods には、次工程で Path --> Plan への変換を
行うコールバック関数などを設定する。
 flagsには当該パスの特徴を指定することができる。
✓ CUSTOMPATH_SUPPORT_BACKWARD_SCAN
✓ CUSTOMPATH_SUPPORT_MARK_RESTORE
✓ CUSTOMPATH_SUPPORT_PROJECTION
RelOptInfoから条件句を抜き出す
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
21
static void
SetCtidScanPath(PlannerInfo *root,
RelOptInfo *baserel,
Index rtindex, RangeTblEntry *rte)
{
:
/* walk on the restrict info */
foreach (lc, baserel->baserestrictinfo)
{
RestrictInfo *rinfo = lfirst(lc);
if (IS_SUPPORTED_EXPR(rino->clause))
dev_quals = lappend(dev_quals, rinfo);
}
if (dev_quals == NIL)
return;
:
cpath = makeNode(CustomPath);
cpath->custom_private = ctid_quals;
cpath->methods = &ctidscan_path_methods;
:
add_path(baserel, (Path *)cpath);
}
▌RelOptInfo
 FROM行に列挙されたリレーションを表現する構造体
 このリレーションをスキャンする Path の一覧
 基本的な統計情報
✓ ブロック数、レコード数、ALL_VISIBLEの割合
 検索に利用できるインデックスの情報
 リレーションをスキャンする条件句
 被参照列のビットマップ
 パーティションの子テーブル一覧
選ばれた Path から Plan を生成する(1/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
22
typedef struct CustomPathMethods
{
:
Plan *(*PlanCustomPath)(PlannerInfo *root,
RelOptInfo *rel,
CustomPath *best_path,
List *tlist,
List *clauses,
List *custom_plans);
:
}
typedef struct CustomScan
{
Scan scan;
uint32 flags;
List *custom_plans; /* list of Plan nodes */
List *custom_exprs; /* expressions nodes */
List *custom_private; /* private data */
List *custom_scan_tlist; /* optional tlist */
Bitmapset *custom_relids; /* RTIs by this can */
const struct CustomScanMethods *methods;
} CustomScan;
 PathからPlanを生成する
✓ 先に登録した CustomPath のコストが最も小さく、
オプティマイザに選択された場合、method に登録
した PlanCustomPath 関数がコールされる。
✓ CustomPathの内容をベースに、CustomPlanを作成する。
 オプティマイザから渡される情報
✓ tlist ターゲットリスト
✓ clauses 検索条件句
✓ custom_plans 既に Plan に変換された下位ノード
(custom_pathsをセットした場合)
 CustomScanに含めるもの
✓ 疑似ターゲットリスト(custom_scan_tlist)
✓ プライベートデータ(expressionとそれ以外)
✓ CustomScan --> CustomScanState に変換するための関数
コールバック
custom_scan_tlist の使い方(1/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
23
postgres=# explain verbose
select count(*), sum(lo_revenue), lo_orderdate % 10000
from lineorder
where lo_orderdate between 19950101 and 19950331
group by 3;
QUERY PLAN
-----------------------------------------------------------------------------------------------------
HashAggregate (cost=1155141.38..1155177.47 rows=2406 width=44)
Output: count(*), sum(lo_revenue), ((lo_orderdate % 10000))
Group Key: ((lineorder.lo_orderdate % 10000))
-> Custom Scan (GpuScan) on public.lineorder (cost=11355.56..1140071.00 rows=2009384 width=10)
Output: ((lo_orderdate % 10000)), lo_revenue
GPU Projection: (lineorder.lo_orderdate % 10000), lineorder.lo_revenue
GPU Filter: ((lineorder.lo_orderdate >= 19950101) AND (lineorder.lo_orderdate <= 19950331))
GPU Preference: GPU0 (NVIDIA A100-PCIE-40GB)
Kernel Source: /var/lib/pgdata/pgsql_tmp/pgsql_tmp_strom_3737600.12.gpu
(9 rows)
custom_scan_tlist の使い方(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
24
tuple tuple
SeqScan
Projection
CustomScan
Projection
tuple
CustomScan
Projection’
次工程(JOIN、GROUP BYなど)
tuple”
tuple
tuple
tuple” tuple” tuple”
テーブル定義通りの
データ構造を持つタプル
EXPLAIN VERBOSEコマンドで
Output: に表示された列から
構成されるタプル
GPU Device Projection
CPU
GPU
SSD
Smart-SSD
2種類のプライベート領域 custom_exprs と custom_privates
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
25
▌後工程での式表現(expression)書き換え
 式表現がある場合や、複数の入力から入ってきた
データの取扱いを簡便にするため、実行計画を作成
した後に setrefs.c で式表現の書き換えを行う。
 例えば、「tbl_x の a列」「tbl_y.b % 1000の計算結果」と
いう形で表現されていた式表現を「INNER側の0番目」
「OUTER側の0番目」といった形に書き換える。
▌CustomScanのプライベート領域に式表現を
含める場合
 setrefs.c による書き換えを行ってほしい場合
➔ custom_exprs に保存する
 setrefs.c による書き換えを行わない場合
➔ custom_privates に保存する
SeqScan
CustomScan
JOIN tbl_x.a = tbl_y.b % 1000
on tbl_x
on tbl_y
output: tbl_y.b % 1000, tbl_y.c
output: tbl_x.a, tbl_y.c
SeqScan
CustomScan
JOIN INNER[0] = OUTER[0]
on tbl_x
on tbl_y
output: tbl_y.b % 1000, tbl_y.c
output: INNER[0], OUTER[1]
setrefs.c
による書き換え
パラレルスキャン用の CustomPath
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
26
▌パラレルスキャンに必要な事
✓ 条件句に出現する関数・演算子が、ワーカーノードでも
動作するものとして宣言されている。
(immutable or stable かつ parallel_safe)
✓ テーブル上のスキャンすべきブロックを、他のワーカー
と協調して特定する事ができる。
 重複して同じブロックを読み出さない
 共有メモリ(後述のDSM)を利用して、ワーカーノードと
読出し位置を調整する。
▌CustomPathに必要な事
✓ parallel_safe = true
✓ parallel_aware = true
✓ parallel_workers > 0
✓ add_partial_path() を用いて登録する。
PG backend PG worker-1 PG worker-2
エグゼキュータを理解する
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
27
PostgreSQLがクエリを処理する流れ
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
28
▌実行計画(Plan)を元に、
実行時情報(PlanState)を生成する。
▌上位のノードから呼び出されたら、
有効な1行、またはNULLを返す。
▌実行終了時にリソースを開放する。
▌パラレルクエリの場合、共有メモリ(DSM: Dynamic
Shared Memory)の初期化とアタッチを行う。
SQL Parser
Query Optimizer
Query Executor
SQLクエリ
パース木
クエリ実行計画
クエリ 実行結果
実行時情報の生成(1/3)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
29
typedef struct CustomScan
{
Scan scan;
uint32 flags;
List *custom_plans; /* list of Plan nodes */
List *custom_exprs; /* expressions nodes */
List *custom_private; /* private data */
List *custom_scan_tlist; /* optional tlist */
Bitmapset *custom_relids; /* RTIs by this can */
const struct CustomScanMethods *methods;
} CustomScan;
typedef struct CustomScanMethods
{
const char *CustomName;
Node *(*CreateCustomScanState)(CustomScan *cscan);
} CustomScanMethods;
 CreateCustomScanState
➔ CustomScanに紐づく唯一のコールバック
 役割:CustomScanを元に、CustomScanStateまたは
構造体の先頭にCustomScanStateを含む実行時情報
を割り当てる。
MyOwnScanState
それ以外に独自に
必要な実行時情報
CustomScanState
カスタムスキャンに
必要な実行時情報
ScanState
テーブルスキャンに
必要な実行時情報
PlanState
全ての実行ノードに
共通のフィールド
⚫ Estate(共通の実行時情報)の参照
⚫ 入力行 ➔ 出力行の変換(Projection)
⚫ 出力行の型定義
⚫ INNER/OUTERノードへの参照
⚫ オープンしている Relation ハンドラ
⚫ 現在のスキャン位置情報
⚫ 実行時に呼び出されるコールバック
関数(methods)
⚫ 下位ノードのリスト(あれば)
⚫ その他、実行時に必要な情報
(GPUのデバイス管理情報、
ワーカースレッドのID、など)
実行時情報の生成(2/3)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
30
typedef struct CustomExecMethods
{
const char *CustomName;
/* Required executor methods */
void (*BeginCustomScan) (CustomScanState *node,
EState *estate,
int eflags);
TupleTableSlot *
(*ExecCustomScan)(CustomScanState *node);
void (*EndCustomScan) (CustomScanState *node);
void (*ReScanCustomScan) (CustomScanState *node);
:
:
void (*ExplainCustomScan) (CustomScanState *node,
List *ancestors,
ExplainState *es);
} CustomExecMethods;
▌BeginCustomScan
 出力行/入力行の型定義情報を初期化
 入力行 ➔ 出力行への変換(Projection)を初期化
 その他の実行時情報を初期化
▌ExecCustomScan
 初回実行時に
 実行結果から一行を返却する。
もしくは終端に達した場合はNULL
▌EndCustomScan
 リソースを開放する。
▌ReScanCustomScan
 もう一度スキャンをやり直す。
▌ExplainCustomScan
 EXPLAINで追加的な情報を出力する場合、
ここで追加する。
実行時情報の生成(3/3)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
31
void ExecInitCustomScan(...)
{
if (scanrelid > 0) {
scan_rel = ExecOpenScanRelation(...);
css->ss.ss_currentRelation = scan_rel;
}
:
if (cscan->custom_scan_tlist != NIL || scan_rel == NULL) {
scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist);
ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc,
&TTSOpsVirtual);
tlistvarno = INDEX_VAR;
} else {
ExecInitScanTupleSlot(estate, &css->ss,
RelationGetDescr(scan_rel),
&TTSOpsVirtual);
tlistvarno = scanrelid;
}
:
/* Init result slot, type and projection */
ExecInitResultTupleSlotTL(&css->ss.ps, &TTSOpsVirtual);
ExecAssignScanProjectionInfoWithVarno(&css->ss,
tlistvarno);
:
css->methods->BeginCustomScan(css, estate, eflags);
}
tuple
CustomScan
Projection’
tuple”
GPU Device Projection
tuple
CustomScan
Projection
tuple
次工程(JOIN、GROUP BYなど)
tuple” tuple”
custom_scan_tlist なしの
初期化パターン
custom_scan_tlist ありの
初期化パターン
※ 結局、自前で初期化を
やり直す方が多いが…。
TupleTableSlot構造体について
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
32
typedef struct TupleTableSlot
{
NodeTag type;
uint16 tts_flags; /* Boolean states */
AttrNumber tts_nvalid; /* # of valid values */
const TupleTableSlotOps *const tts_ops;
TupleDesc tts_tupleDescriptor; /* 列定義情報 */
Datum *tts_values; /* 列ごとの値 */
bool *tts_isnull; /* NULL値フラグ */
MemoryContext tts_mcxt;
ItemPointerData tts_tid; /* stored tuple's tid */
Oid tts_tableOid; /* table oid of tuple */
} TupleTableSlot;
typedef struct HeapTupleTableSlot
{
TupleTableSlot base;
HeapTuple tuple; /* physical tuple */
uint32 off; /* state for deforming */
HeapTupleData tupdata; /* optional workspace */
} HeapTupleTableSlot;
▌TupleTableSlot構造体の役割
 列定義情報(TupleDesc)と、そのデータ形式に沿った
一行分のデータを保持する。
➔ 各実行ノード間でデータの受け渡しに用いる。
 PostgreSQL v12 のプラガブルストレージ機構のマージと
共に、多様なデータ構造を定義できるようになった。
▌TTSOpsVirtualの場合
 有効長tts_nvalid の配列tts_values/tts_isnullに
列単位で展開された値が入る。
 最も汎用的な形式である一方、物理テーブルをスキャン
した場合、タプルを展開しないといけない。
▌物理タプルをそのまま使う場合は?
 HeapTupleTableSlot か、さらに Buffer へのポインタを
付加した BufferHeapTupleTableSlot を利用すれば、
TupleTableSlot に物理タプルを格納できる。
 table_slot_callbacks(relation) を使えば、
テーブルの TupleTableSlotOps を取得できる。
(v12以降、特定の物理タプル形式を前提にできない)
エグゼキュータの構造
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
33
BeginCustomScan
ExecutorStart
initPlan
上位ノードの初期化
ExecInitCustomScan
ExecCustomScan
ExecutorRun
ExecutePlan
上位ノードの実行
ExecCustomScan
EndCustomScan
ExecutorEnd
ExecEndPlan
上位ノードの終了処理
ExecEndCustomScan
拡張モジュールで
実装すべき箇所
どのような実装手段でも構わないので、
✓ 指定されたテーブルを読み出す
✓ 条件句に合致したタプルだけを返す
✓ 直上のノードが「入力値」として
期待するデータ型のタプルを返す。
ことを守っていればよい。
GPU
列キャッシュ
SIMD命令
量子
コンピュータ
Smart-SSD
パラレルクエリの対応(1/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
34
postgres=# explain verbose
select count(*), lo_orderdate % 10000
from lineorder
where lo_orderdate between 19950101 and 19950331
group by 2;
QUERY PLAN
--------------------------------------------------------------------------------------------
Finalize HashAggregate (cost=726605.39..726635.47 rows=2406 width=12)
Output: count(*), ((lo_orderdate % 10000))
Group Key: ((lineorder.lo_orderdate % 10000))
-> Gather (cost=726070.06..726581.33 rows=4812 width=12)
Output: ((lo_orderdate % 10000)), (PARTIAL count(*))
Workers Planned: 2
-> Partial HashAggregate (cost=725070.06..725100.13 rows=2406 width=12)
Output: ((lo_orderdate % 10000)), PARTIAL count(*)
Group Key: ((lineorder.lo_orderdate % 10000))
-> Parallel Custom Scan (GpuScan) on public.lineorder (cost=29652.44..720883.84 rows=837243 width=4)
Output: ((lo_orderdate % 10000))
GPU Projection: (lineorder.lo_orderdate % 10000)
GPU Filter: ((lineorder.lo_orderdate >= 19950101) AND (lineorder.lo_orderdate <= 19950331))
GPU Preference: GPU0 (NVIDIA A100-PCIE-40GB)
Kernel Source: /var/lib/pgdata/pgsql_tmp/pgsql_tmp_strom_3870445.12.gpu
Kernel Binary: /var/lib/pgdata/pgsql_tmp/pgsql_tmp_strom_3870445.13.ptx
(16 rows)
Gatherがワーカーを立ち上げ、
ワーカーから返された結果も含め、
上位ノードへ結果を返す。
パラレルクエリの対応(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
35
typedef struct CustomExecMethods
{
const char *CustomName;
:
/* optional: needed if parallel execution */
Size (*EstimateDSMCustomScan)(CustomScanState *node,
ParallelContext *pcxt);
void (*InitializeDSMCustomScan)(CustomScanState *node,
ParallelContext *pcxt,
void *coordinate);
void (*ReInitializeDSMCustomScan)(CustomScanState *node,
ParallelContext *pcxt,
void *coordinate);
void (*InitializeWorkerCustomScan)(CustomScanState *node,
shm_toc *toc,
void *coordinate);
void (*ShutdownCustomScan) (CustomScanState *node);
:
} CustomExecMethods;
Gatherノードの動き
① 下位ノードの共有メモリ(DSM)必要量を計算
✓ EstimateDSMCustomScanが呼ばれる
② IPC用の共有メモリを確保し、各ノードごとに初期化
✓ InitializeDSMCustomScanが呼ばれる
③ Partial Aggregate以下を実行するワーカプロセスを起動
④ 各ワーカで初期化済みの共有メモリをアタッチする。
✓ InitializeWorkerCustomScan が呼ばれる
⑤ バックエンド・各ワーカーで終端までスキャンを行う
⑥ 各ワーカープロセスの終了
⑦ 共有メモリを開放する前に、 シャットダウン処理を実行
✓ ShutdownCustomScan が呼ばれる。
⑧ エグゼキュータの終了処理
✓ EndCustomScanが呼ばれる
Gather
Partial Aggregate
Hash Join
CustomScan
SeqScan
Partial Aggregate
Hash Join
CustomScan
SeqScan
Partial Aggregate
Hash Join
CustomScan
SeqScan
共有メモリ
(DSM)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
36
JOINとGROUP BY
JOINとGROUP BY(1/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
37
HashJoin
Projection
CustomScan
Projection
tuple
tuple
tuple
tuple
tuple” tuple”
次工程(他のJOIN、GROUP BYなど)
どのような実装手段でも構わないので、
✓ 要求された下位ノードからタプルを読み出す。
✓ 結合条件に従ってJOIN処理を行い、直上のノードが
「入力値」として期待するデータ型のタプルを返す。
✓ 集約式に従ってGROUP BY処理を行い、直上のノードが
「入力値」として期待するデータ型のタプルを返す。
ことを守っていればよい。
JOINとGROUP BY(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
38
/* Hook for plugins to get control in
add_paths_to_joinrel() */
typedef void (*set_join_pathlist_hook_type)
(PlannerInfo *root,
RelOptInfo *joinrel,
RelOptInfo *outerrel,
RelOptInfo *innerrel,
JoinType jointype,
JoinPathExtraData *extra);
extern PGDLLIMPORT set_join_pathlist_hook_type
set_join_pathlist_hook;
/* Hook for plugins to get control when
grouping_planner() plans upper rels */
typedef void (*create_upper_paths_hook_type)
(PlannerInfo *root,
UpperRelationKind stage,
RelOptInfo *input_rel,
RelOptInfo *output_rel,
void *extra);
extern PGDLLIMPORT create_upper_paths_hook_type
create_upper_paths_hook;
▌JOINに対する Path の追加
 set_join_pathlist_hook を利用する。
 joinrelは、outerrelとinnerrelを結合した表を
意味する RelOptInfo で、ここに CustomPath を追加す
る。
▌GROUP BYに対する Path の追加
 SCAN/JOINが一通り終わった後、より上位の実行計画を
積み上げるという意味で UPPER-PATH と呼んでいる。
 create_upper_paths_hookを利用する。
 UpperRelationKindは以下の8種類
✓ UPPERREL_SETOP
✓ UPPERREL_PARTIAL_GROUP_AGG
✓ UPPERREL_GROUP_AGG
✓ UPPERREL_WINDOW
✓ UPPERREL_PARTIAL_DISTINCT
✓ UPPERREL_DISTINCT
✓ UPPERREL_ORDERED
✓ UPPERREL_FINAL
下位ノードを持つ CustomPath の作成
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
39
typedef struct CustomPath
{
Path path;
uint32 flags; /* mask of CUSTOMPATH_* flags */
List *custom_paths; /* list of child Path */
List *custom_private;
const struct CustomPathMethods *methods;
} CustomPath;
typedef struct CustomPathMethods
{
const char *CustomName;
/* Convert Path to a Plan */
Plan *(*PlanCustomPath) (PlannerInfo *root,
RelOptInfo *rel,
CustomPath *best_path,
List *tlist,
List *clauses,
List *custom_plans);
:
}
typedef struct CustomScan
{
Scan scan;
uint32 flags;
List *custom_plans; /* list of Plan nodes */
List *custom_exprs;
List *custom_private;
List *custom_scan_tlist;
Bitmapset *custom_relids;
CustomScanMethods *methods;
} CustomScan;
void
BeginCustomScan(CustomScanState *node, ...)
{
CustomScan *cscan = (CustomScan *)node->ss.ps->plan;
foreach (lc, cscan->custom_plans)
{
Plan *child_plan = lfirst(lc);
child_ps = ExecInitNode(child_plan, ...);
:
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
40
CustomScan APIの拡張 ~ 非同期APIへの対応
FDWにおける非同期API(1/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
41
子テーブル①
(Foreign Table)
子テーブル②
(Foreign Table)
子テーブル③
(Foreign Table)
子テーブル④
(Foreign Table)
リモートサーバー
Gather
Append
Foreign Scan on ①
Foreign Scan on ②
Foreign Scan on ③
Foreign Scan on ④
パーティションテーブル
nworkers=2
backend
worker-1
worker-2
FDWにおける非同期API(1/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
42
子テーブル①
(Foreign Table)
子テーブル②
(Foreign Table)
子テーブル③
(Foreign Table)
子テーブル④
(Foreign Table)
リモートサーバー
Gather
Append
Foreign Scan on ①
Foreign Scan on ②
Foreign Scan on ③
Foreign Scan on ④
パーティションテーブル
nworkers=2
worker-1
FDWにおける非同期API(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
43
/* Support functions for asynchronous execution */
bool IsForeignPathAsyncCapable(ForeignPath *path);
ForeignPathが非同期実行をサポートしているかどうかを
オプティマイザに通知する
void ForeignAsyncRequest(AsyncRequest *areq);
リモートサーバから非同期に受け取ったタプルを一つ、
呼び出し元へ返す、またはareq->callback_pending=trueを
セットして結果待ちである事を呼び出し元に知らせる、あるい
はスロットにNULLをセットして終端に達した事を知らせる。
void ForeignAsyncConfigureWait(AsyncRequest *areq);
結果待ちである場合、WaitEventSetWait()の対象となる
ファイルディスクリプタを追加する。
(読み出し可能となった時点でプロセスが起床する)
void ForeignAsyncNotify(AsyncRequest *areq);
新たにリモートから処理結果を受け取ったら、そのタプルを
一つ、呼び出し元へ返す。
① ForeignAsyncRequest(初回)を通じて、リモートサーバに
実行開始のリクエスト。
Append
Foreign Scan on ①
Foreign Scan on ②
Foreign Scan on ③
SeqScan on ④
FDWにおける非同期API(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
44
/* Support functions for asynchronous execution */
bool IsForeignPathAsyncCapable(ForeignPath *path);
ForeignPathが非同期実行をサポートしているかどうかを
オプティマイザに通知する
void ForeignAsyncRequest(AsyncRequest *areq);
リモートサーバから非同期に受け取ったタプルを一つ、
呼び出し元へ返す、またはareq->callback_pending=trueを
セットして結果待ちである事を呼び出し元に知らせる、あるい
はスロットにNULLをセットして終端に達した事を知らせる。
void ForeignAsyncConfigureWait(AsyncRequest *areq);
結果待ちである場合、WaitEventSetWait()の対象となる
ファイルディスクリプタを追加する。
(読み出し可能となった時点でプロセスが起床する)
void ForeignAsyncNotify(AsyncRequest *areq);
新たにリモートから処理結果を受け取ったら、そのタプルを
一つ、呼び出し元へ返す。
① ForeignAsyncRequest(初回)を通じて、リモートサーバに
実行開始のリクエスト。
② ForeignAsyncConfigureWaitにより同期イベントをセット
Append
Foreign Scan on ①
Foreign Scan on ②
Foreign Scan on ③
SeqScan on ④
FDWにおける非同期API(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
45
/* Support functions for asynchronous execution */
bool IsForeignPathAsyncCapable(ForeignPath *path);
ForeignPathが非同期実行をサポートしているかどうかを
オプティマイザに通知する
void ForeignAsyncRequest(AsyncRequest *areq);
リモートサーバから非同期に受け取ったタプルを一つ、
呼び出し元へ返す、またはareq->callback_pending=trueを
セットして結果待ちである事を呼び出し元に知らせる、あるい
はスロットにNULLをセットして終端に達した事を知らせる。
void ForeignAsyncConfigureWait(AsyncRequest *areq);
結果待ちである場合、WaitEventSetWait()の対象となる
ファイルディスクリプタを追加する。
(読み出し可能となった時点でプロセスが起床する)
void ForeignAsyncNotify(AsyncRequest *areq);
新たにリモートから処理結果を受け取ったら、そのタプルを
一つ、呼び出し元へ返す。
① ForeignAsyncRequest(初回)を通じて、リモートサーバに
実行開始のリクエスト。
② ForeignAsyncConfigureWaitにより同期イベントをセット
③ リモート実行中に、同期実行できるものを実行
Append
Foreign Scan on ①
Foreign Scan on ②
Foreign Scan on ③
SeqScan on ④
FDWにおける非同期API(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
46
/* Support functions for asynchronous execution */
bool IsForeignPathAsyncCapable(ForeignPath *path);
ForeignPathが非同期実行をサポートしているかどうかを
オプティマイザに通知する
void ForeignAsyncRequest(AsyncRequest *areq);
リモートサーバから非同期に受け取ったタプルを一つ、
呼び出し元へ返す、またはareq->callback_pending=trueを
セットして結果待ちである事を呼び出し元に知らせる、あるい
はスロットにNULLをセットして終端に達した事を知らせる。
void ForeignAsyncConfigureWait(AsyncRequest *areq);
結果待ちである場合、WaitEventSetWait()の対象となる
ファイルディスクリプタを追加する。
(読み出し可能となった時点でプロセスが起床する)
void ForeignAsyncNotify(AsyncRequest *areq);
新たにリモートから処理結果を受け取ったら、そのタプルを
一つ、呼び出し元へ返す。
① ForeignAsyncRequest(初回)を通じて、リモートサーバに
実行開始のリクエスト。
② ForeignAsyncConfigureWaitにより同期イベントをセット
③ リモート実行中に、同期実行できるものを実行
④ 結果が返ってきていれば、ForeignAsyncNotifyを通じ
て結果を取得。一行を返す。
Append
Foreign Scan on ①
Foreign Scan on ②
Foreign Scan on ③
SeqScan on ④
CustomScan APIにおける非同期処理APIの追加(1/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
47
▌ForeignScan の非同期APIとの違いは?
 ほとんどない。
 CustomScanが非同期APIをサポートするかどうか、
CUSTOMPATH_SUPPORT_ASYNC_EXECUTIONフラグを用いてオプ
(専用のコールバックは設けていない)
▌追加するコールバックは
 void CustomScanAsyncRequest(AsyncRequest *areq);
 void CustomScanAsyncConfigureWait(AsyncRequest *areq);
 void CustomScanAsyncNotify(AsyncRequest *areq);
➔ 使い方は FDW のケースと全く同一
CustomScan APIにおける非同期処理APIの追加(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
48
Computational Storage
SSDドライブ上にFPGAやARMプロセッサを
搭載し、ストレージドライブ上でユーザの
開発したソフトウェアを実行する事ができる。
Flashストレージの業界では最もホットな話題の一つ。
仮に2U/24ドライブのサーバにフル実装したら、
24ノードのワーカーが走っているのと同じ。☺
子テーブル①
(Heap Table)
子テーブル②
(Heap Table)
子テーブル③
(Heap Table)
子テーブル④
(Heap Table)
パーティションテーブル
shared
buffer
Filesystem
NVME
Block
System
参照
SELECT + Index
書き込み
INSERT/UPDATE/DELETE
CustomScan APIにおける非同期処理APIの追加(2/2)
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
49
Computational Storage
SSDドライブ上にFPGAやARMプロセッサを
搭載し、ストレージドライブ上でユーザの
開発したソフトウェアを実行する事ができる。
Flashストレージの業界では最もホットな話題の一つ。
仮に2U/24ドライブのサーバにフル実装したら、
24ノードのワーカーが走っているのと同じ。☺
子テーブル①
(Heap Table)
子テーブル②
(Heap Table)
子テーブル③
(Heap Table)
子テーブル④
(Heap Table)
パーティションテーブル
shared
buffer
Filesystem
NVME
Block
System
検索・集計
SELECT + Scan
まとめ
 CustomScan APIとは
✓ FDWが「何を」テーブルとして見せるのかに対して、テーブルを「どのように」処理するかを
プラガブルにするための機構。
✓ PostgreSQL v9.5でサポート。PostgreSQLを母体とするソリューションで割と使われている。
 オプティマイザ
✓ set_rel_pathlist_hook やset_join_pathlist_hookを用いて、独自の CustomPath を追加する。
✓ 上位ノードに結果を返す際の列定義情報(custom_scan_tlist)に注意する。
 エグゼキュータ
✓ BeginCustomScanで初期化、ExecCustomScanで実行、EndCustomScanで終了
✓ 上位ノードに結果を返す際の列定義情報(TupleDesc)に注意。必ず一致していないとダメ。
✓ 本来の SCAN や JOIN の処理と同じ結果を返しさえすれば、どのような方法で実装してもよい。
✓ パラレルクエリの場合は、共有メモリ(DSM)を介して他のワーカーと協調する。
 今後の機能強化
✓ ForeignScan同様の非同期処理用のAPIを提案中
✓ Smart-SSDやSmart-NICでSQLを処理する際に、非同期処理を記述できるようになる。
PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~
50
オモシロ技術を、カタチにする。

More Related Content

What's hot

PostgreSQLレプリケーション徹底紹介
PostgreSQLレプリケーション徹底紹介PostgreSQLレプリケーション徹底紹介
PostgreSQLレプリケーション徹底紹介
NTT DATA OSS Professional Services
 
Grafana Dashboards as Code
Grafana Dashboards as CodeGrafana Dashboards as Code
Grafana Dashboards as Code
Takuhiro Yoshida
 
祝!PostgreSQLレプリケーション10周年!徹底紹介!!
祝!PostgreSQLレプリケーション10周年!徹底紹介!!祝!PostgreSQLレプリケーション10周年!徹底紹介!!
祝!PostgreSQLレプリケーション10周年!徹底紹介!!
NTT DATA Technology & Innovation
 
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
PostgreSQL開発コミュニティに参加しよう! ~2022年版~(Open Source Conference 2022 Online/Kyoto 発...
PostgreSQL開発コミュニティに参加しよう! ~2022年版~(Open Source Conference 2022 Online/Kyoto 発...PostgreSQL開発コミュニティに参加しよう! ~2022年版~(Open Source Conference 2022 Online/Kyoto 発...
PostgreSQL開発コミュニティに参加しよう! ~2022年版~(Open Source Conference 2022 Online/Kyoto 発...
NTT DATA Technology & Innovation
 
PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)
PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)
PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)
NTT DATA Technology & Innovation
 
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(PostgreSQL Conference Japa...
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(PostgreSQL Conference Japa...PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(PostgreSQL Conference Japa...
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(PostgreSQL Conference Japa...
NTT DATA Technology & Innovation
 
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
NTT DATA Technology & Innovation
 
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
PostgreSQLによるデータ分析ことはじめ
PostgreSQLによるデータ分析ことはじめPostgreSQLによるデータ分析ことはじめ
PostgreSQLによるデータ分析ことはじめ
Ohyama Masanori
 
NTT DATA と PostgreSQL が挑んだ総力戦
NTT DATA と PostgreSQL が挑んだ総力戦NTT DATA と PostgreSQL が挑んだ総力戦
NTT DATA と PostgreSQL が挑んだ総力戦
NTT DATA OSS Professional Services
 
VirtualBox と Rocky Linux 8 で始める Pacemaker ~ VirtualBox でも STONITH 機能が試せる! Vi...
VirtualBox と Rocky Linux 8 で始める Pacemaker  ~ VirtualBox でも STONITH 機能が試せる! Vi...VirtualBox と Rocky Linux 8 で始める Pacemaker  ~ VirtualBox でも STONITH 機能が試せる! Vi...
VirtualBox と Rocky Linux 8 で始める Pacemaker ~ VirtualBox でも STONITH 機能が試せる! Vi...
ksk_ha
 
PostgreSQL 13でのpg_stat_statementsの改善について(第12回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQL 13でのpg_stat_statementsの改善について(第12回PostgreSQLアンカンファレンス@オンライン 発表資料)PostgreSQL 13でのpg_stat_statementsの改善について(第12回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQL 13でのpg_stat_statementsの改善について(第12回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)
押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)
押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)
NTT DATA Technology & Innovation
 
PostgreSQL - C言語によるユーザ定義関数の作り方
PostgreSQL - C言語によるユーザ定義関数の作り方PostgreSQL - C言語によるユーザ定義関数の作り方
PostgreSQL - C言語によるユーザ定義関数の作り方Satoshi Nagayasu
 
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
NTT DATA Technology & Innovation
 
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
NTT DATA Technology & Innovation
 
あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界
Yoshinori Nakanishi
 

What's hot (20)

PostgreSQLレプリケーション徹底紹介
PostgreSQLレプリケーション徹底紹介PostgreSQLレプリケーション徹底紹介
PostgreSQLレプリケーション徹底紹介
 
Grafana Dashboards as Code
Grafana Dashboards as CodeGrafana Dashboards as Code
Grafana Dashboards as Code
 
祝!PostgreSQLレプリケーション10周年!徹底紹介!!
祝!PostgreSQLレプリケーション10周年!徹底紹介!!祝!PostgreSQLレプリケーション10周年!徹底紹介!!
祝!PostgreSQLレプリケーション10周年!徹底紹介!!
 
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
pg_bigmで全文検索するときに気を付けたい5つのポイント(第23回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
PostgreSQL開発コミュニティに参加しよう! ~2022年版~(Open Source Conference 2022 Online/Kyoto 発...
PostgreSQL開発コミュニティに参加しよう! ~2022年版~(Open Source Conference 2022 Online/Kyoto 発...PostgreSQL開発コミュニティに参加しよう! ~2022年版~(Open Source Conference 2022 Online/Kyoto 発...
PostgreSQL開発コミュニティに参加しよう! ~2022年版~(Open Source Conference 2022 Online/Kyoto 発...
 
PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
PGCon 2023 参加報告(第42回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)
PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)
PostgreSQL開発コミュニティに参加しよう!(PostgreSQL Conference Japan 2021 発表資料)
 
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
フックを使ったPostgreSQLの拡張機能を作ってみよう!(第33回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(PostgreSQL Conference Japa...
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(PostgreSQL Conference Japa...PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(PostgreSQL Conference Japa...
PostgreSQLのバグとの付き合い方 ~バグの調査からコミュニティへの報告、修正パッチ投稿まで~(PostgreSQL Conference Japa...
 
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
速習!論理レプリケーション ~基礎から最新動向まで~(PostgreSQL Conference Japan 2022 発表資料)
 
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
統計情報のリセットによるautovacuumへの影響について(第39回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
PostgreSQLによるデータ分析ことはじめ
PostgreSQLによるデータ分析ことはじめPostgreSQLによるデータ分析ことはじめ
PostgreSQLによるデータ分析ことはじめ
 
NTT DATA と PostgreSQL が挑んだ総力戦
NTT DATA と PostgreSQL が挑んだ総力戦NTT DATA と PostgreSQL が挑んだ総力戦
NTT DATA と PostgreSQL が挑んだ総力戦
 
VirtualBox と Rocky Linux 8 で始める Pacemaker ~ VirtualBox でも STONITH 機能が試せる! Vi...
VirtualBox と Rocky Linux 8 で始める Pacemaker  ~ VirtualBox でも STONITH 機能が試せる! Vi...VirtualBox と Rocky Linux 8 で始める Pacemaker  ~ VirtualBox でも STONITH 機能が試せる! Vi...
VirtualBox と Rocky Linux 8 で始める Pacemaker ~ VirtualBox でも STONITH 機能が試せる! Vi...
 
PostgreSQL 13でのpg_stat_statementsの改善について(第12回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQL 13でのpg_stat_statementsの改善について(第12回PostgreSQLアンカンファレンス@オンライン 発表資料)PostgreSQL 13でのpg_stat_statementsの改善について(第12回PostgreSQLアンカンファレンス@オンライン 発表資料)
PostgreSQL 13でのpg_stat_statementsの改善について(第12回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)
押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)
押さえておきたい、PostgreSQL 13 の新機能!!(Open Source Conference 2021 Online/Hokkaido 発表資料)
 
PostgreSQL - C言語によるユーザ定義関数の作り方
PostgreSQL - C言語によるユーザ定義関数の作り方PostgreSQL - C言語によるユーザ定義関数の作り方
PostgreSQL - C言語によるユーザ定義関数の作り方
 
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
レプリケーション遅延の監視について(第40回PostgreSQLアンカンファレンス@オンライン 発表資料)
 
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
速習! PostgreSQL専用HAソフトウェア: Patroni(PostgreSQL Conference Japan 2023 発表資料)
 
あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界あなたの知らないPostgreSQL監視の世界
あなたの知らないPostgreSQL監視の世界
 

Similar to 20221111_JPUG_CustomScan_API

PostgreSQL v9.5の新機能~CustomScan/Join Interface
PostgreSQL v9.5の新機能~CustomScan/Join InterfacePostgreSQL v9.5の新機能~CustomScan/Join Interface
PostgreSQL v9.5の新機能~CustomScan/Join Interface
Kohei KaiGai
 
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
Google Cloud Platform - Japan
 
20180920_DBTS_PGStrom_JP
20180920_DBTS_PGStrom_JP20180920_DBTS_PGStrom_JP
20180920_DBTS_PGStrom_JP
Kohei KaiGai
 
Azure Cosmos DB を使った クラウドネイティブアプリケーションの 設計パターン
Azure Cosmos DB を使った クラウドネイティブアプリケーションの 設計パターンAzure Cosmos DB を使った クラウドネイティブアプリケーションの 設計パターン
Azure Cosmos DB を使った クラウドネイティブアプリケーションの 設計パターン
Kazuyuki Miyake
 
SSDとGPUがPostgreSQLを加速する【OSC.Enterprise】
SSDとGPUがPostgreSQLを加速する【OSC.Enterprise】SSDとGPUがPostgreSQLを加速する【OSC.Enterprise】
SSDとGPUがPostgreSQLを加速する【OSC.Enterprise】
Kohei KaiGai
 
Cosmos DB 入門 multi model multi API編
Cosmos DB 入門 multi model multi API編Cosmos DB 入門 multi model multi API編
Cosmos DB 入門 multi model multi API編
Takekazu Omi
 
20170127 JAWS HPC-UG#8
20170127 JAWS HPC-UG#820170127 JAWS HPC-UG#8
20170127 JAWS HPC-UG#8
Kohei KaiGai
 
Azure Database for MySQL PostgreSQLを使って運用の手間を省きませんか?
Azure Database for MySQL PostgreSQLを使って運用の手間を省きませんか?Azure Database for MySQL PostgreSQLを使って運用の手間を省きませんか?
Azure Database for MySQL PostgreSQLを使って運用の手間を省きませんか?
Suguru Ito
 
20181212 - PGconf.ASIA - LT
20181212 - PGconf.ASIA - LT20181212 - PGconf.ASIA - LT
20181212 - PGconf.ASIA - LT
Kohei KaiGai
 
PostgreSQL 12の話
PostgreSQL 12の話PostgreSQL 12の話
PostgreSQL 12の話
Masahiko Sawada
 
Azure Cosmos DB を使った高速分散アプリケーションの設計パターン
Azure Cosmos DB を使った高速分散アプリケーションの設計パターンAzure Cosmos DB を使った高速分散アプリケーションの設計パターン
Azure Cosmos DB を使った高速分散アプリケーションの設計パターン
Kazuyuki Miyake
 
[Japan Tech summit 2017] DAL 005
[Japan Tech summit 2017] DAL 005[Japan Tech summit 2017] DAL 005
[Japan Tech summit 2017] DAL 005
Microsoft Tech Summit 2017
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
Toru Yamaguchi
 
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsPL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
Kohei KaiGai
 
機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編
Daiyu Hatakeyama
 
CDP Night #1 静的コンテンツ配信編
CDP Night #1 静的コンテンツ配信編CDP Night #1 静的コンテンツ配信編
CDP Night #1 静的コンテンツ配信編
Akio Katayama
 
RailsエンジニアのためのSQLチューニング速習会
RailsエンジニアのためのSQLチューニング速習会RailsエンジニアのためのSQLチューニング速習会
RailsエンジニアのためのSQLチューニング速習会
Nao Minami
 
オープンソースのIoT向けスケールアウト型データベース GridDB 〜性能ベンチマーク結果とOSSを利用したビッグデータ分析環境〜
オープンソースのIoT向けスケールアウト型データベース GridDB 〜性能ベンチマーク結果とOSSを利用したビッグデータ分析環境〜オープンソースのIoT向けスケールアウト型データベース GridDB 〜性能ベンチマーク結果とOSSを利用したビッグデータ分析環境〜
オープンソースのIoT向けスケールアウト型データベース GridDB 〜性能ベンチマーク結果とOSSを利用したビッグデータ分析環境〜
griddb
 
Infrastructure as code for azure
Infrastructure as code for azureInfrastructure as code for azure
Infrastructure as code for azure
Keiji Kamebuchi
 
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
Kohei KaiGai
 

Similar to 20221111_JPUG_CustomScan_API (20)

PostgreSQL v9.5の新機能~CustomScan/Join Interface
PostgreSQL v9.5の新機能~CustomScan/Join InterfacePostgreSQL v9.5の新機能~CustomScan/Join Interface
PostgreSQL v9.5の新機能~CustomScan/Join Interface
 
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
[Cloud OnAir] 最新アップデート Google Cloud データ関連ソリューション 2020年5月14日 放送
 
20180920_DBTS_PGStrom_JP
20180920_DBTS_PGStrom_JP20180920_DBTS_PGStrom_JP
20180920_DBTS_PGStrom_JP
 
Azure Cosmos DB を使った クラウドネイティブアプリケーションの 設計パターン
Azure Cosmos DB を使った クラウドネイティブアプリケーションの 設計パターンAzure Cosmos DB を使った クラウドネイティブアプリケーションの 設計パターン
Azure Cosmos DB を使った クラウドネイティブアプリケーションの 設計パターン
 
SSDとGPUがPostgreSQLを加速する【OSC.Enterprise】
SSDとGPUがPostgreSQLを加速する【OSC.Enterprise】SSDとGPUがPostgreSQLを加速する【OSC.Enterprise】
SSDとGPUがPostgreSQLを加速する【OSC.Enterprise】
 
Cosmos DB 入門 multi model multi API編
Cosmos DB 入門 multi model multi API編Cosmos DB 入門 multi model multi API編
Cosmos DB 入門 multi model multi API編
 
20170127 JAWS HPC-UG#8
20170127 JAWS HPC-UG#820170127 JAWS HPC-UG#8
20170127 JAWS HPC-UG#8
 
Azure Database for MySQL PostgreSQLを使って運用の手間を省きませんか?
Azure Database for MySQL PostgreSQLを使って運用の手間を省きませんか?Azure Database for MySQL PostgreSQLを使って運用の手間を省きませんか?
Azure Database for MySQL PostgreSQLを使って運用の手間を省きませんか?
 
20181212 - PGconf.ASIA - LT
20181212 - PGconf.ASIA - LT20181212 - PGconf.ASIA - LT
20181212 - PGconf.ASIA - LT
 
PostgreSQL 12の話
PostgreSQL 12の話PostgreSQL 12の話
PostgreSQL 12の話
 
Azure Cosmos DB を使った高速分散アプリケーションの設計パターン
Azure Cosmos DB を使った高速分散アプリケーションの設計パターンAzure Cosmos DB を使った高速分散アプリケーションの設計パターン
Azure Cosmos DB を使った高速分散アプリケーションの設計パターン
 
[Japan Tech summit 2017] DAL 005
[Japan Tech summit 2017] DAL 005[Japan Tech summit 2017] DAL 005
[Japan Tech summit 2017] DAL 005
 
Inside mobage platform
Inside mobage platformInside mobage platform
Inside mobage platform
 
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database AnalyticsPL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
PL/CUDA - Fusion of HPC Grade Power with In-Database Analytics
 
機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編機械学習 / Deep Learning 大全 (5) Tool編
機械学習 / Deep Learning 大全 (5) Tool編
 
CDP Night #1 静的コンテンツ配信編
CDP Night #1 静的コンテンツ配信編CDP Night #1 静的コンテンツ配信編
CDP Night #1 静的コンテンツ配信編
 
RailsエンジニアのためのSQLチューニング速習会
RailsエンジニアのためのSQLチューニング速習会RailsエンジニアのためのSQLチューニング速習会
RailsエンジニアのためのSQLチューニング速習会
 
オープンソースのIoT向けスケールアウト型データベース GridDB 〜性能ベンチマーク結果とOSSを利用したビッグデータ分析環境〜
オープンソースのIoT向けスケールアウト型データベース GridDB 〜性能ベンチマーク結果とOSSを利用したビッグデータ分析環境〜オープンソースのIoT向けスケールアウト型データベース GridDB 〜性能ベンチマーク結果とOSSを利用したビッグデータ分析環境〜
オープンソースのIoT向けスケールアウト型データベース GridDB 〜性能ベンチマーク結果とOSSを利用したビッグデータ分析環境〜
 
Infrastructure as code for azure
Infrastructure as code for azureInfrastructure as code for azure
Infrastructure as code for azure
 
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
GPUとSSDがPostgreSQLを加速する~クエリ処理スループット10GB/sへの挑戦~ [DB Tech Showcase Tokyo/2017]
 

More from Kohei KaiGai

20221116_DBTS_PGStrom_History
20221116_DBTS_PGStrom_History20221116_DBTS_PGStrom_History
20221116_DBTS_PGStrom_History
Kohei KaiGai
 
20211112_jpugcon_gpu_and_arrow
20211112_jpugcon_gpu_and_arrow20211112_jpugcon_gpu_and_arrow
20211112_jpugcon_gpu_and_arrow
Kohei KaiGai
 
20210928_pgunconf_hll_count
20210928_pgunconf_hll_count20210928_pgunconf_hll_count
20210928_pgunconf_hll_count
Kohei KaiGai
 
20210731_OSC_Kyoto_PGStrom3.0
20210731_OSC_Kyoto_PGStrom3.020210731_OSC_Kyoto_PGStrom3.0
20210731_OSC_Kyoto_PGStrom3.0
Kohei KaiGai
 
20210511_PGStrom_GpuCache
20210511_PGStrom_GpuCache20210511_PGStrom_GpuCache
20210511_PGStrom_GpuCache
Kohei KaiGai
 
20210301_PGconf_Online_GPU_PostGIS_GiST_Index
20210301_PGconf_Online_GPU_PostGIS_GiST_Index20210301_PGconf_Online_GPU_PostGIS_GiST_Index
20210301_PGconf_Online_GPU_PostGIS_GiST_Index
Kohei KaiGai
 
20201128_OSC_Fukuoka_Online_GPUPostGIS
20201128_OSC_Fukuoka_Online_GPUPostGIS20201128_OSC_Fukuoka_Online_GPUPostGIS
20201128_OSC_Fukuoka_Online_GPUPostGIS
Kohei KaiGai
 
20201113_PGconf_Japan_GPU_PostGIS
20201113_PGconf_Japan_GPU_PostGIS20201113_PGconf_Japan_GPU_PostGIS
20201113_PGconf_Japan_GPU_PostGIS
Kohei KaiGai
 
20201006_PGconf_Online_Large_Data_Processing
20201006_PGconf_Online_Large_Data_Processing20201006_PGconf_Online_Large_Data_Processing
20201006_PGconf_Online_Large_Data_Processing
Kohei KaiGai
 
20200828_OSCKyoto_Online
20200828_OSCKyoto_Online20200828_OSCKyoto_Online
20200828_OSCKyoto_Online
Kohei KaiGai
 
20200806_PGStrom_PostGIS_GstoreFdw
20200806_PGStrom_PostGIS_GstoreFdw20200806_PGStrom_PostGIS_GstoreFdw
20200806_PGStrom_PostGIS_GstoreFdw
Kohei KaiGai
 
20200424_Writable_Arrow_Fdw
20200424_Writable_Arrow_Fdw20200424_Writable_Arrow_Fdw
20200424_Writable_Arrow_Fdw
Kohei KaiGai
 
20191211_Apache_Arrow_Meetup_Tokyo
20191211_Apache_Arrow_Meetup_Tokyo20191211_Apache_Arrow_Meetup_Tokyo
20191211_Apache_Arrow_Meetup_Tokyo
Kohei KaiGai
 
20191115-PGconf.Japan
20191115-PGconf.Japan20191115-PGconf.Japan
20191115-PGconf.Japan
Kohei KaiGai
 
20190926_Try_RHEL8_NVMEoF_Beta
20190926_Try_RHEL8_NVMEoF_Beta20190926_Try_RHEL8_NVMEoF_Beta
20190926_Try_RHEL8_NVMEoF_Beta
Kohei KaiGai
 
20190925_DBTS_PGStrom
20190925_DBTS_PGStrom20190925_DBTS_PGStrom
20190925_DBTS_PGStrom
Kohei KaiGai
 
20190909_PGconf.ASIA_KaiGai
20190909_PGconf.ASIA_KaiGai20190909_PGconf.ASIA_KaiGai
20190909_PGconf.ASIA_KaiGai
Kohei KaiGai
 
20190516_DLC10_PGStrom
20190516_DLC10_PGStrom20190516_DLC10_PGStrom
20190516_DLC10_PGStrom
Kohei KaiGai
 
20190418_PGStrom_on_ArrowFdw
20190418_PGStrom_on_ArrowFdw20190418_PGStrom_on_ArrowFdw
20190418_PGStrom_on_ArrowFdw
Kohei KaiGai
 
20190314 PGStrom Arrow_Fdw
20190314 PGStrom Arrow_Fdw20190314 PGStrom Arrow_Fdw
20190314 PGStrom Arrow_Fdw
Kohei KaiGai
 

More from Kohei KaiGai (20)

20221116_DBTS_PGStrom_History
20221116_DBTS_PGStrom_History20221116_DBTS_PGStrom_History
20221116_DBTS_PGStrom_History
 
20211112_jpugcon_gpu_and_arrow
20211112_jpugcon_gpu_and_arrow20211112_jpugcon_gpu_and_arrow
20211112_jpugcon_gpu_and_arrow
 
20210928_pgunconf_hll_count
20210928_pgunconf_hll_count20210928_pgunconf_hll_count
20210928_pgunconf_hll_count
 
20210731_OSC_Kyoto_PGStrom3.0
20210731_OSC_Kyoto_PGStrom3.020210731_OSC_Kyoto_PGStrom3.0
20210731_OSC_Kyoto_PGStrom3.0
 
20210511_PGStrom_GpuCache
20210511_PGStrom_GpuCache20210511_PGStrom_GpuCache
20210511_PGStrom_GpuCache
 
20210301_PGconf_Online_GPU_PostGIS_GiST_Index
20210301_PGconf_Online_GPU_PostGIS_GiST_Index20210301_PGconf_Online_GPU_PostGIS_GiST_Index
20210301_PGconf_Online_GPU_PostGIS_GiST_Index
 
20201128_OSC_Fukuoka_Online_GPUPostGIS
20201128_OSC_Fukuoka_Online_GPUPostGIS20201128_OSC_Fukuoka_Online_GPUPostGIS
20201128_OSC_Fukuoka_Online_GPUPostGIS
 
20201113_PGconf_Japan_GPU_PostGIS
20201113_PGconf_Japan_GPU_PostGIS20201113_PGconf_Japan_GPU_PostGIS
20201113_PGconf_Japan_GPU_PostGIS
 
20201006_PGconf_Online_Large_Data_Processing
20201006_PGconf_Online_Large_Data_Processing20201006_PGconf_Online_Large_Data_Processing
20201006_PGconf_Online_Large_Data_Processing
 
20200828_OSCKyoto_Online
20200828_OSCKyoto_Online20200828_OSCKyoto_Online
20200828_OSCKyoto_Online
 
20200806_PGStrom_PostGIS_GstoreFdw
20200806_PGStrom_PostGIS_GstoreFdw20200806_PGStrom_PostGIS_GstoreFdw
20200806_PGStrom_PostGIS_GstoreFdw
 
20200424_Writable_Arrow_Fdw
20200424_Writable_Arrow_Fdw20200424_Writable_Arrow_Fdw
20200424_Writable_Arrow_Fdw
 
20191211_Apache_Arrow_Meetup_Tokyo
20191211_Apache_Arrow_Meetup_Tokyo20191211_Apache_Arrow_Meetup_Tokyo
20191211_Apache_Arrow_Meetup_Tokyo
 
20191115-PGconf.Japan
20191115-PGconf.Japan20191115-PGconf.Japan
20191115-PGconf.Japan
 
20190926_Try_RHEL8_NVMEoF_Beta
20190926_Try_RHEL8_NVMEoF_Beta20190926_Try_RHEL8_NVMEoF_Beta
20190926_Try_RHEL8_NVMEoF_Beta
 
20190925_DBTS_PGStrom
20190925_DBTS_PGStrom20190925_DBTS_PGStrom
20190925_DBTS_PGStrom
 
20190909_PGconf.ASIA_KaiGai
20190909_PGconf.ASIA_KaiGai20190909_PGconf.ASIA_KaiGai
20190909_PGconf.ASIA_KaiGai
 
20190516_DLC10_PGStrom
20190516_DLC10_PGStrom20190516_DLC10_PGStrom
20190516_DLC10_PGStrom
 
20190418_PGStrom_on_ArrowFdw
20190418_PGStrom_on_ArrowFdw20190418_PGStrom_on_ArrowFdw
20190418_PGStrom_on_ArrowFdw
 
20190314 PGStrom Arrow_Fdw
20190314 PGStrom Arrow_Fdw20190314 PGStrom Arrow_Fdw
20190314 PGStrom Arrow_Fdw
 

Recently uploaded

協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
Osaka University
 
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
ARISE analytics
 
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobodyロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
azuma satoshi
 
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMMハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
osamut
 
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライドHumanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
tazaki1
 
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
嶋 是一 (Yoshikazu SHIMA)
 
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
sugiuralab
 
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
Yuki Miyazaki
 
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
Osaka University
 

Recently uploaded (9)

協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
協働AIがもたらす業務効率革命 -日本企業が押さえるべきポイント-Collaborative AI Revolutionizing Busines...
 
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
【JSAI2024】LLMエージェントの人間との対話における反芻的返答の親近感向上効果_v1.1.pdf
 
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobodyロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
ロジックから状態を分離する技術/設計ナイト2024 by わいとん @ytnobody
 
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMMハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
ハイブリッドクラウド研究会_Hyper-VとSystem Center Virtual Machine Manager セッションMM
 
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライドHumanoid Virtual Athletics Challenge2024 技術講習会 スライド
Humanoid Virtual Athletics Challenge2024 技術講習会 スライド
 
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
「進化するアプリ イマ×ミライ ~生成AIアプリへ続く道と新時代のアプリとは~」Interop24Tokyo APPS JAPAN B1-01講演
 
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
ヒアラブルへの入力を想定したユーザ定義型ジェスチャ調査と IMUセンサによる耳タッチジェスチャの認識
 
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
無形価値を守り育てる社会における「デー タ」の責務について - Atlas, Inc.
 
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
生成AIがもたらすコンテンツ経済圏の新時代  The New Era of Content Economy Brought by Generative AI
 

20221111_JPUG_CustomScan_API

  • 2. CustomScan APIとは? postgres=# explain select sum(lo_revenue), d_year, p_brand1 from flineorder, date1, part where lo_orderdate = d_datekey and lo_partkey = p_partkey and p_category = 'MFGR#12’ group by d_year, p_brand1; QUERY PLAN ----------------------------------------------------------------------------------------------------- HashAggregate (cost=3656703.22..3656773.22 rows=7000 width=22) Group Key: date1.d_year, part.p_brand1 -> Custom Scan (GpuPreAgg) (cost=3656580.72..3656650.72 rows=7000 width=22) Reduction: GroupBy (Global+Local [nrooms: 1974]) Group keys: d_year, p_brand1 Combined GpuJoin: enabled -> Custom Scan (GpuJoin) on flineorder (cost=16028.65..3638534.69 rows=28873638 width=18) Outer Scan: flineorder (cost=0.00..10277198.49 rows=720040849 width=12) Depth 1: GpuHashJoin(nrows 720040849...28873638) HashSize: 1135.95KB HashKeys: flineorder.lo_partkey JoinQuals: (flineorder.lo_partkey = part.p_partkey) Depth 2: GpuHashJoin(nrows 28873638...28873638) HashSize: 442.11KB HashKeys: flineorder.lo_orderdate JoinQuals: (flineorder.lo_orderdate = date1.d_datekey) referenced: lo_partkey, lo_orderdate, lo_revenue files0: /opt/pgdata14/f_lineorder.arrow (read: 8.05GB, size: 81.81GB) -> Seq Scan on part (cost=0.00..5426.00 rows=8020 width=14) Filter: (p_category = 'MFGR#12'::bpchar) -> Seq Scan on date1 (cost=0.00..72.56 rows=2556 width=8) (21 rows) 見覚えのない 実行計画があるなぁ…。 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 2
  • 3. CustomScan APIとは? ▌概要  エグゼキュータの一部を拡張モジュールによる 実装で置き換えたいときに利用するAPI  拡張モジュールの開発者が利用するもので、 SQL経由でユーザが利用するものではない。  PostgreSQL v9.5 (2016) で最初のバージョンが 提供されるようになった。 ▌利点  独自にSQL実行エンジンを強化したい場合でも、 PostgreSQLからのフォークを行わずに済む。  自分が興味のある部分“だけ”を置き換える事が できるので、開発規模を抑える事ができる。 IndexScan on table-Y CustomScan (MyScan) on table-X CustomScan (MyJoin) Agg (Group By) NestLoop SeqScan on table-Z PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 3
  • 4. CustomScan APIとFDW(Foreign Data Wrapper)の違い ▌FDW: Foreign Data Wrapper  外部のデータをあたかもPostgreSQLのテーブルで あるかのように読み書きするためのAPI  何を(What?)スキャンするか。 ▌CustomScan API  PostgreSQLのテーブルを異なる方法でスキャン するためのAPI ✓ 実装上、キャッシュを参照するなどの手法もアリ  どのように(How?)スキャンするか Foreign Table Foreign Table Foreign Table Foreign Table CSV mysql_fdw oracle_fdw file_fdw arrow_fdw MySQL データベース Oracle データベース CSV ファイル Arrow ファイル PostgreSQL テーブル SeqScan IndexScan CacheScan FpgaScan DpuScan GpuScan columnar cache PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 4
  • 5. HeteroDB社について ▌会社概要  商号 ヘテロDB株式会社  設立 2017年7月4日  資本金 999万円  所在地 品川区北品川5-5-15 大崎ブライトコア4F  事業内容 高速データベース製品の開発・販売 GPU&DB領域の技術コンサルティング  受賞など ✓ IPA 未踏アドバンスト事業 第一期生(2017) ✓ GPU Technology Conference Japan 2017、Inception Award受賞 ✓ 東京都ベンチャー技術大賞 技術奨励賞(2022) ▌代表者プロフィール  海外 浩平|KaiGai Kohei OSS開発者コミュニティにおいて、 PostgreSQLやLinux kernelの開発に 15年以上従事。主にセキュリティ・ FDWなどの技術領域に貢献する。 本日のテーマ CustomScan API や、 GPUを用いたSQL高速化モジュール・PG-Stromの開発者。 筑波大学情報学類卒(2001)、同大学院経営・政策科学研究 科修了(2003)、日本電気株式会社勤務(2003-2017)の後、 HeteroDB社を創業。  受賞など ✓ IPA未踏ソフト「天才プログラマ―」認定(2006) ✓ OSS推進フォーラム OSS貢献者賞(2014) ✓ 日本情報処理学会 喜安記念業績賞(2014) ヘテロジニアスコンピューティング技術をデータベース領域に適用し、 誰もが使いやすく、シンプルで高速なデータ解析基盤を提供する。 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 5
  • 6. CustomScan APIの利用例 – Microsoft Azure Cosmos DB 出典: https://learn.microsoft.com/ja-jp/azure/cosmos-db/postgresql/tutorial-shard PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 6
  • 7. CustomScan APIの利用例 – Google AlloyDB 出典: https://cloud.google.com/blog/ja/products/databases/alloydb-for-postgresql-columnar-engine PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 7
  • 8. CustomScan APIの利用例 – HeteroDB PG-Strom postgres=# explain select sum(lo_revenue), d_year, p_brand1 from flineorder, date1, part where lo_orderdate = d_datekey and lo_partkey = p_partkey and p_category = 'MFGR#12’ group by d_year, p_brand1; QUERY PLAN ----------------------------------------------------------------------------------------------------- HashAggregate (cost=2631106.55..2631176.55 rows=7000 width=22) Group Key: date1.d_year, part.p_brand1 -> Custom Scan (GpuPreAgg) (cost=2630984.05..2631054.05 rows=7000 width=22) Reduction: GroupBy (Global+Local [nrooms: 1974]) Group keys: d_year, p_brand1 Combined GpuJoin: enabled GPU Preference: GPU0 (NVIDIA A100-PCIE-40GB) -> Custom Scan (GpuJoin) on flineorder (cost=14190.72..2612938.03 rows=28873638 width=18) Outer Scan: flineorder (cost=0.00..10277198.49 rows=720040849 width=12) Depth 1: GpuHashJoin(nrows 720040849...28873638) HashSize: 1135.95KB HashKeys: flineorder.lo_partkey JoinQuals: (flineorder.lo_partkey = part.p_partkey) Depth 2: GpuHashJoin(nrows 28873638...28873638) HashSize: 442.11KB HashKeys: flineorder.lo_orderdate JoinQuals: (flineorder.lo_orderdate = date1.d_datekey) GPU Preference: GPU0 (NVIDIA A100-PCIE-40GB) GPUDirect SQL: enabled referenced: lo_partkey, lo_orderdate, lo_revenue files0: /opt/pgdata14/f_lineorder.arrow (read: 8.05GB, size: 81.81GB) -> Seq Scan on part (cost=0.00..5426.00 rows=8020 width=14) Filter: (p_category = 'MFGR#12'::bpchar) -> Seq Scan on date1 (cost=0.00..72.56 rows=2556 width=8) (24 rows) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 8
  • 9. CustomScan APIの利用例 – FUJITSU Software Enterprise Postgres 9.5 出典: https://software.fujitsu.com/jp/manual/manualfiles/m160008/j2ul2119/05z200/j2119-00-13-01-00.html PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 9
  • 10. SamsungのSmart-SSD開発チーム(?)の講演でも PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 10
  • 11. PostgreSQL向けExtensionの開発 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 11
  • 12. 最小構成での PostgreSQL 拡張モジュールのビルド $ ls Makefile ctidscan.h ctidscan.c ctidscan.sql ctidscan.control $ cat Makefile MODULES = ctidscan EXTENSION = ctidscan DATA = ctidscan.sql PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) $ cat ctidscan.control # ctidscan extension comment = 'example module for custom-scan api’ default_version = '1.0' module_pathname = '$libdir/ctidscan' relocatable = true ✓ PostgreSQL向け拡張モジュールは、メジャー バージョン跨ぎのバイナリ互換性の保証なし。 ✓ ビルド時の ./configure 次第で変わるパラメータ 例:BLCKSZの定義やAssertの有無、構造体のレイアウトも ✓ ターゲットとなるPostgreSQLに同梱の pg_config を 利用してビルドオプションの同一性を担保する。 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 12
  • 13. 拡張モジュールが制御を獲得するタイミング #include “postgres.h” : : void _PG_init(void) { DefineCustomBoolVariable("enable_ctidscan", "Enables use of ctidscan”, NULL, &enable_ctidscan, true, PGC_USERSET, GUC_NOT_IN_SAMPLE, NULL, NULL, NULL); : /* registration of the hook to add alternative path */ set_rel_pathlist_next = set_rel_pathlist_hook; set_rel_pathlist_hook = SetCtidScanPath; } ✓ PostgreSQLが拡張モジュールをロードすると、 まず _PG_init() 関数を呼び出す。 ✓ 拡張モジュールをロードするタイミングは… ✓ その拡張モジュールで実装されているSQL関数の呼び出し。 ✓ (shared|local|session)_preload_libraries パラメー タによる指定。 ✓ SQLのLOADコマンド ➔ CustomScan APIを使用する拡張モジュールの場合は、 *_preload_libraries パラメータを使うのが自然。 ✓ 拡張モジュールで制御を獲得するには? ✓ “C”で実装されたSQL関数の実行 ➔ 演算子やSQL関数、インデックスの評価やFDWなど、 大半のケースではこちら。 ✓ フック、コールバックで登録されたタイミング ➔ CustomScan APIでは、一連の処理の中でSQL関数を必要と する場面がないため、_PG_init() でフックやコールバックの 登録を済ませておく。 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 13
  • 14. 比較的シンプルな CustomScan のサンプル PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 14 ▌https://github.com/kaigai/ctidscan  検索条件に ctid システム列(*)に対する大小比較を含む 場合、明らかにマッチしないブロックを読み飛ばす。  PostgreSQL v14で対応した TidRangeScan と同等だが、 CustomScan APIの提案時には 意味のある拡張モジュール だった。 ✓ (*) ctidシステム列は、タプルの存在するブロック番号と アイテム番号を示す。
  • 15. PostgreSQLはどのように実行計画を作るのか PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 15
  • 16. PostgreSQLがクエリを処理する流れ SQL Parser Query Optimizer Query Executor Buffer Manager SQLクエリ パース木 クエリ実行計画 クエリ 実行結果  SQL構文を分解し、取り扱いやすい 内部データ形式(パース木)に変換  文法エラーの検出  統計情報を元にコスト値を算出  最も合理的と予想される実行計画を作成する。  クエリ実行計画に基づいて、 ScanやJoin、Sortなどの処理を実行する。  PostgreSQL内部のインフラを使用 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 16 Transaction Control Resource Management IPC, Shared Memory クエリの実行をサポートする 多種多様な内部インフラが 用意されている。
  • 17. PostgreSQLはどのように実行計画を作るか t0 JOIN t1の候補パス Scan t0 Scan t1 Join t0,t1 統計情報) nrows: 120万行 width: 80 インデックス:なし 候補パス HashJoin cost=4000 候補パス MergeJoin cost=12000 候補パス NestLoop cost=99999 候補パス Parallel Hash Join cost=3000 候補パス GpuJoin cost=2500 WINNER! PostgreSQLビルトインの実行パス 拡張モジュールによる提案 (PostgreSQL v9.5以降) (PostgreSQL v9.6以降) GpuJoin t0,t1 統計情報) nrows: 4000行 width: 120 インデックス:id列 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 17
  • 18. PostgreSQLがクエリを処理する流れ PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 18 ▌リレーション(Scan, Join, ...)に紐づいた 候補パス(Path構造体)を作成する。 ✓ Pathには実行コストや、実行結果の出力順 (ソートされているか否か)などを保持する。 ✓ ビルトインの実行計画の他に CustomPath を作成 する事ができれば、ここに突っ込む。 ▌オプティマイザは最もコストの安い候補パスを 選択し、Path ⇒ Plan 構造体に変換する。 ✓ Pathと異なり、Plan構造体は copyObject などの 内部APIを用いて操作できる。 ▌式表現の書き換え ✓ 場合によっては、オプティマイザにヒントを与える 必要がある(custom_scan_tlist) SQL Parser Query Optimizer Query Executor SQLクエリ パース木 クエリ実行計画 クエリ 実行結果
  • 19. set_rel_pathlist_hook による実行計画の登録 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 19 /* Hook for plugins to get control in set_rel_pathlist() */ typedef void (*set_rel_pathlist_hook_type) (PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry *rte); extern PGDLLIMPORT set_rel_pathlist_hook_type set_rel_pathlist_hook; static void SetCtidScanPath(PlannerInfo *root, RelOptInfo *baserel, Index rtindex, RangeTblEntry *rte) { /* call the secondary custom-scan provider */ if (set_rel_pathlist_next) set_rel_pathlist_next(root, baserel, rtindex, rte); : /* * 1. リレーション種別や検索条件をチェック * 2. CustomPathを作成し、CustomPathMethods を登録 * 3. add_path()を使ってパスを登録 */ ✓ set_rel_pathlist_hook はいつ呼ばれるのか? ➔ 特定のテーブルに対して、オプティマイザが スキャンする方法を検討するタイミング。 ✓ ビルトインのスキャン方法 • SeqScan • IndexScan • BitmapHeapScan • TidScan • ForeignScan ➔ ここに割り込んで、『俺々CustomScan』の方が より効率的にこのテーブルをスキャンできると いう事を教えてやる。
  • 20. CustomPath構造体 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 20 typedef struct Path { NodeTag type; NodeTag pathtype; RelOptInfo *parent; PathTarget *pathtarget; ParamPathInfo *param_info; : Cardinality rows; Cost startup_cost; Cost total_cost; List *pathkeys; } Path; typedef struct CustomPath { Path path; uint32 flags; List *custom_paths; List *custom_private; const struct CustomPathMethods *methods; } CustomPath; ▌CustomPath構造体  『俺ならこれぐらいの処理コストで実行できる』を PostgreSQLのオプティマイザに教えてやるための データ構造。  Path中の rows, startup_cost, total_cost で 処理コストを表現する。  methods には、次工程で Path --> Plan への変換を 行うコールバック関数などを設定する。  flagsには当該パスの特徴を指定することができる。 ✓ CUSTOMPATH_SUPPORT_BACKWARD_SCAN ✓ CUSTOMPATH_SUPPORT_MARK_RESTORE ✓ CUSTOMPATH_SUPPORT_PROJECTION
  • 21. RelOptInfoから条件句を抜き出す PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 21 static void SetCtidScanPath(PlannerInfo *root, RelOptInfo *baserel, Index rtindex, RangeTblEntry *rte) { : /* walk on the restrict info */ foreach (lc, baserel->baserestrictinfo) { RestrictInfo *rinfo = lfirst(lc); if (IS_SUPPORTED_EXPR(rino->clause)) dev_quals = lappend(dev_quals, rinfo); } if (dev_quals == NIL) return; : cpath = makeNode(CustomPath); cpath->custom_private = ctid_quals; cpath->methods = &ctidscan_path_methods; : add_path(baserel, (Path *)cpath); } ▌RelOptInfo  FROM行に列挙されたリレーションを表現する構造体  このリレーションをスキャンする Path の一覧  基本的な統計情報 ✓ ブロック数、レコード数、ALL_VISIBLEの割合  検索に利用できるインデックスの情報  リレーションをスキャンする条件句  被参照列のビットマップ  パーティションの子テーブル一覧
  • 22. 選ばれた Path から Plan を生成する(1/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 22 typedef struct CustomPathMethods { : Plan *(*PlanCustomPath)(PlannerInfo *root, RelOptInfo *rel, CustomPath *best_path, List *tlist, List *clauses, List *custom_plans); : } typedef struct CustomScan { Scan scan; uint32 flags; List *custom_plans; /* list of Plan nodes */ List *custom_exprs; /* expressions nodes */ List *custom_private; /* private data */ List *custom_scan_tlist; /* optional tlist */ Bitmapset *custom_relids; /* RTIs by this can */ const struct CustomScanMethods *methods; } CustomScan;  PathからPlanを生成する ✓ 先に登録した CustomPath のコストが最も小さく、 オプティマイザに選択された場合、method に登録 した PlanCustomPath 関数がコールされる。 ✓ CustomPathの内容をベースに、CustomPlanを作成する。  オプティマイザから渡される情報 ✓ tlist ターゲットリスト ✓ clauses 検索条件句 ✓ custom_plans 既に Plan に変換された下位ノード (custom_pathsをセットした場合)  CustomScanに含めるもの ✓ 疑似ターゲットリスト(custom_scan_tlist) ✓ プライベートデータ(expressionとそれ以外) ✓ CustomScan --> CustomScanState に変換するための関数 コールバック
  • 23. custom_scan_tlist の使い方(1/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 23 postgres=# explain verbose select count(*), sum(lo_revenue), lo_orderdate % 10000 from lineorder where lo_orderdate between 19950101 and 19950331 group by 3; QUERY PLAN ----------------------------------------------------------------------------------------------------- HashAggregate (cost=1155141.38..1155177.47 rows=2406 width=44) Output: count(*), sum(lo_revenue), ((lo_orderdate % 10000)) Group Key: ((lineorder.lo_orderdate % 10000)) -> Custom Scan (GpuScan) on public.lineorder (cost=11355.56..1140071.00 rows=2009384 width=10) Output: ((lo_orderdate % 10000)), lo_revenue GPU Projection: (lineorder.lo_orderdate % 10000), lineorder.lo_revenue GPU Filter: ((lineorder.lo_orderdate >= 19950101) AND (lineorder.lo_orderdate <= 19950331)) GPU Preference: GPU0 (NVIDIA A100-PCIE-40GB) Kernel Source: /var/lib/pgdata/pgsql_tmp/pgsql_tmp_strom_3737600.12.gpu (9 rows)
  • 24. custom_scan_tlist の使い方(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 24 tuple tuple SeqScan Projection CustomScan Projection tuple CustomScan Projection’ 次工程(JOIN、GROUP BYなど) tuple” tuple tuple tuple” tuple” tuple” テーブル定義通りの データ構造を持つタプル EXPLAIN VERBOSEコマンドで Output: に表示された列から 構成されるタプル GPU Device Projection CPU GPU SSD Smart-SSD
  • 25. 2種類のプライベート領域 custom_exprs と custom_privates PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 25 ▌後工程での式表現(expression)書き換え  式表現がある場合や、複数の入力から入ってきた データの取扱いを簡便にするため、実行計画を作成 した後に setrefs.c で式表現の書き換えを行う。  例えば、「tbl_x の a列」「tbl_y.b % 1000の計算結果」と いう形で表現されていた式表現を「INNER側の0番目」 「OUTER側の0番目」といった形に書き換える。 ▌CustomScanのプライベート領域に式表現を 含める場合  setrefs.c による書き換えを行ってほしい場合 ➔ custom_exprs に保存する  setrefs.c による書き換えを行わない場合 ➔ custom_privates に保存する SeqScan CustomScan JOIN tbl_x.a = tbl_y.b % 1000 on tbl_x on tbl_y output: tbl_y.b % 1000, tbl_y.c output: tbl_x.a, tbl_y.c SeqScan CustomScan JOIN INNER[0] = OUTER[0] on tbl_x on tbl_y output: tbl_y.b % 1000, tbl_y.c output: INNER[0], OUTER[1] setrefs.c による書き換え
  • 26. パラレルスキャン用の CustomPath PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 26 ▌パラレルスキャンに必要な事 ✓ 条件句に出現する関数・演算子が、ワーカーノードでも 動作するものとして宣言されている。 (immutable or stable かつ parallel_safe) ✓ テーブル上のスキャンすべきブロックを、他のワーカー と協調して特定する事ができる。  重複して同じブロックを読み出さない  共有メモリ(後述のDSM)を利用して、ワーカーノードと 読出し位置を調整する。 ▌CustomPathに必要な事 ✓ parallel_safe = true ✓ parallel_aware = true ✓ parallel_workers > 0 ✓ add_partial_path() を用いて登録する。 PG backend PG worker-1 PG worker-2
  • 27. エグゼキュータを理解する PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 27
  • 28. PostgreSQLがクエリを処理する流れ PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 28 ▌実行計画(Plan)を元に、 実行時情報(PlanState)を生成する。 ▌上位のノードから呼び出されたら、 有効な1行、またはNULLを返す。 ▌実行終了時にリソースを開放する。 ▌パラレルクエリの場合、共有メモリ(DSM: Dynamic Shared Memory)の初期化とアタッチを行う。 SQL Parser Query Optimizer Query Executor SQLクエリ パース木 クエリ実行計画 クエリ 実行結果
  • 29. 実行時情報の生成(1/3) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 29 typedef struct CustomScan { Scan scan; uint32 flags; List *custom_plans; /* list of Plan nodes */ List *custom_exprs; /* expressions nodes */ List *custom_private; /* private data */ List *custom_scan_tlist; /* optional tlist */ Bitmapset *custom_relids; /* RTIs by this can */ const struct CustomScanMethods *methods; } CustomScan; typedef struct CustomScanMethods { const char *CustomName; Node *(*CreateCustomScanState)(CustomScan *cscan); } CustomScanMethods;  CreateCustomScanState ➔ CustomScanに紐づく唯一のコールバック  役割:CustomScanを元に、CustomScanStateまたは 構造体の先頭にCustomScanStateを含む実行時情報 を割り当てる。 MyOwnScanState それ以外に独自に 必要な実行時情報 CustomScanState カスタムスキャンに 必要な実行時情報 ScanState テーブルスキャンに 必要な実行時情報 PlanState 全ての実行ノードに 共通のフィールド ⚫ Estate(共通の実行時情報)の参照 ⚫ 入力行 ➔ 出力行の変換(Projection) ⚫ 出力行の型定義 ⚫ INNER/OUTERノードへの参照 ⚫ オープンしている Relation ハンドラ ⚫ 現在のスキャン位置情報 ⚫ 実行時に呼び出されるコールバック 関数(methods) ⚫ 下位ノードのリスト(あれば) ⚫ その他、実行時に必要な情報 (GPUのデバイス管理情報、 ワーカースレッドのID、など)
  • 30. 実行時情報の生成(2/3) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 30 typedef struct CustomExecMethods { const char *CustomName; /* Required executor methods */ void (*BeginCustomScan) (CustomScanState *node, EState *estate, int eflags); TupleTableSlot * (*ExecCustomScan)(CustomScanState *node); void (*EndCustomScan) (CustomScanState *node); void (*ReScanCustomScan) (CustomScanState *node); : : void (*ExplainCustomScan) (CustomScanState *node, List *ancestors, ExplainState *es); } CustomExecMethods; ▌BeginCustomScan  出力行/入力行の型定義情報を初期化  入力行 ➔ 出力行への変換(Projection)を初期化  その他の実行時情報を初期化 ▌ExecCustomScan  初回実行時に  実行結果から一行を返却する。 もしくは終端に達した場合はNULL ▌EndCustomScan  リソースを開放する。 ▌ReScanCustomScan  もう一度スキャンをやり直す。 ▌ExplainCustomScan  EXPLAINで追加的な情報を出力する場合、 ここで追加する。
  • 31. 実行時情報の生成(3/3) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 31 void ExecInitCustomScan(...) { if (scanrelid > 0) { scan_rel = ExecOpenScanRelation(...); css->ss.ss_currentRelation = scan_rel; } : if (cscan->custom_scan_tlist != NIL || scan_rel == NULL) { scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist); ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc, &TTSOpsVirtual); tlistvarno = INDEX_VAR; } else { ExecInitScanTupleSlot(estate, &css->ss, RelationGetDescr(scan_rel), &TTSOpsVirtual); tlistvarno = scanrelid; } : /* Init result slot, type and projection */ ExecInitResultTupleSlotTL(&css->ss.ps, &TTSOpsVirtual); ExecAssignScanProjectionInfoWithVarno(&css->ss, tlistvarno); : css->methods->BeginCustomScan(css, estate, eflags); } tuple CustomScan Projection’ tuple” GPU Device Projection tuple CustomScan Projection tuple 次工程(JOIN、GROUP BYなど) tuple” tuple” custom_scan_tlist なしの 初期化パターン custom_scan_tlist ありの 初期化パターン ※ 結局、自前で初期化を やり直す方が多いが…。
  • 32. TupleTableSlot構造体について PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 32 typedef struct TupleTableSlot { NodeTag type; uint16 tts_flags; /* Boolean states */ AttrNumber tts_nvalid; /* # of valid values */ const TupleTableSlotOps *const tts_ops; TupleDesc tts_tupleDescriptor; /* 列定義情報 */ Datum *tts_values; /* 列ごとの値 */ bool *tts_isnull; /* NULL値フラグ */ MemoryContext tts_mcxt; ItemPointerData tts_tid; /* stored tuple's tid */ Oid tts_tableOid; /* table oid of tuple */ } TupleTableSlot; typedef struct HeapTupleTableSlot { TupleTableSlot base; HeapTuple tuple; /* physical tuple */ uint32 off; /* state for deforming */ HeapTupleData tupdata; /* optional workspace */ } HeapTupleTableSlot; ▌TupleTableSlot構造体の役割  列定義情報(TupleDesc)と、そのデータ形式に沿った 一行分のデータを保持する。 ➔ 各実行ノード間でデータの受け渡しに用いる。  PostgreSQL v12 のプラガブルストレージ機構のマージと 共に、多様なデータ構造を定義できるようになった。 ▌TTSOpsVirtualの場合  有効長tts_nvalid の配列tts_values/tts_isnullに 列単位で展開された値が入る。  最も汎用的な形式である一方、物理テーブルをスキャン した場合、タプルを展開しないといけない。 ▌物理タプルをそのまま使う場合は?  HeapTupleTableSlot か、さらに Buffer へのポインタを 付加した BufferHeapTupleTableSlot を利用すれば、 TupleTableSlot に物理タプルを格納できる。  table_slot_callbacks(relation) を使えば、 テーブルの TupleTableSlotOps を取得できる。 (v12以降、特定の物理タプル形式を前提にできない)
  • 33. エグゼキュータの構造 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 33 BeginCustomScan ExecutorStart initPlan 上位ノードの初期化 ExecInitCustomScan ExecCustomScan ExecutorRun ExecutePlan 上位ノードの実行 ExecCustomScan EndCustomScan ExecutorEnd ExecEndPlan 上位ノードの終了処理 ExecEndCustomScan 拡張モジュールで 実装すべき箇所 どのような実装手段でも構わないので、 ✓ 指定されたテーブルを読み出す ✓ 条件句に合致したタプルだけを返す ✓ 直上のノードが「入力値」として 期待するデータ型のタプルを返す。 ことを守っていればよい。 GPU 列キャッシュ SIMD命令 量子 コンピュータ Smart-SSD
  • 34. パラレルクエリの対応(1/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 34 postgres=# explain verbose select count(*), lo_orderdate % 10000 from lineorder where lo_orderdate between 19950101 and 19950331 group by 2; QUERY PLAN -------------------------------------------------------------------------------------------- Finalize HashAggregate (cost=726605.39..726635.47 rows=2406 width=12) Output: count(*), ((lo_orderdate % 10000)) Group Key: ((lineorder.lo_orderdate % 10000)) -> Gather (cost=726070.06..726581.33 rows=4812 width=12) Output: ((lo_orderdate % 10000)), (PARTIAL count(*)) Workers Planned: 2 -> Partial HashAggregate (cost=725070.06..725100.13 rows=2406 width=12) Output: ((lo_orderdate % 10000)), PARTIAL count(*) Group Key: ((lineorder.lo_orderdate % 10000)) -> Parallel Custom Scan (GpuScan) on public.lineorder (cost=29652.44..720883.84 rows=837243 width=4) Output: ((lo_orderdate % 10000)) GPU Projection: (lineorder.lo_orderdate % 10000) GPU Filter: ((lineorder.lo_orderdate >= 19950101) AND (lineorder.lo_orderdate <= 19950331)) GPU Preference: GPU0 (NVIDIA A100-PCIE-40GB) Kernel Source: /var/lib/pgdata/pgsql_tmp/pgsql_tmp_strom_3870445.12.gpu Kernel Binary: /var/lib/pgdata/pgsql_tmp/pgsql_tmp_strom_3870445.13.ptx (16 rows) Gatherがワーカーを立ち上げ、 ワーカーから返された結果も含め、 上位ノードへ結果を返す。
  • 35. パラレルクエリの対応(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 35 typedef struct CustomExecMethods { const char *CustomName; : /* optional: needed if parallel execution */ Size (*EstimateDSMCustomScan)(CustomScanState *node, ParallelContext *pcxt); void (*InitializeDSMCustomScan)(CustomScanState *node, ParallelContext *pcxt, void *coordinate); void (*ReInitializeDSMCustomScan)(CustomScanState *node, ParallelContext *pcxt, void *coordinate); void (*InitializeWorkerCustomScan)(CustomScanState *node, shm_toc *toc, void *coordinate); void (*ShutdownCustomScan) (CustomScanState *node); : } CustomExecMethods; Gatherノードの動き ① 下位ノードの共有メモリ(DSM)必要量を計算 ✓ EstimateDSMCustomScanが呼ばれる ② IPC用の共有メモリを確保し、各ノードごとに初期化 ✓ InitializeDSMCustomScanが呼ばれる ③ Partial Aggregate以下を実行するワーカプロセスを起動 ④ 各ワーカで初期化済みの共有メモリをアタッチする。 ✓ InitializeWorkerCustomScan が呼ばれる ⑤ バックエンド・各ワーカーで終端までスキャンを行う ⑥ 各ワーカープロセスの終了 ⑦ 共有メモリを開放する前に、 シャットダウン処理を実行 ✓ ShutdownCustomScan が呼ばれる。 ⑧ エグゼキュータの終了処理 ✓ EndCustomScanが呼ばれる Gather Partial Aggregate Hash Join CustomScan SeqScan Partial Aggregate Hash Join CustomScan SeqScan Partial Aggregate Hash Join CustomScan SeqScan 共有メモリ (DSM)
  • 36. PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 36 JOINとGROUP BY
  • 37. JOINとGROUP BY(1/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 37 HashJoin Projection CustomScan Projection tuple tuple tuple tuple tuple” tuple” 次工程(他のJOIN、GROUP BYなど) どのような実装手段でも構わないので、 ✓ 要求された下位ノードからタプルを読み出す。 ✓ 結合条件に従ってJOIN処理を行い、直上のノードが 「入力値」として期待するデータ型のタプルを返す。 ✓ 集約式に従ってGROUP BY処理を行い、直上のノードが 「入力値」として期待するデータ型のタプルを返す。 ことを守っていればよい。
  • 38. JOINとGROUP BY(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 38 /* Hook for plugins to get control in add_paths_to_joinrel() */ typedef void (*set_join_pathlist_hook_type) (PlannerInfo *root, RelOptInfo *joinrel, RelOptInfo *outerrel, RelOptInfo *innerrel, JoinType jointype, JoinPathExtraData *extra); extern PGDLLIMPORT set_join_pathlist_hook_type set_join_pathlist_hook; /* Hook for plugins to get control when grouping_planner() plans upper rels */ typedef void (*create_upper_paths_hook_type) (PlannerInfo *root, UpperRelationKind stage, RelOptInfo *input_rel, RelOptInfo *output_rel, void *extra); extern PGDLLIMPORT create_upper_paths_hook_type create_upper_paths_hook; ▌JOINに対する Path の追加  set_join_pathlist_hook を利用する。  joinrelは、outerrelとinnerrelを結合した表を 意味する RelOptInfo で、ここに CustomPath を追加す る。 ▌GROUP BYに対する Path の追加  SCAN/JOINが一通り終わった後、より上位の実行計画を 積み上げるという意味で UPPER-PATH と呼んでいる。  create_upper_paths_hookを利用する。  UpperRelationKindは以下の8種類 ✓ UPPERREL_SETOP ✓ UPPERREL_PARTIAL_GROUP_AGG ✓ UPPERREL_GROUP_AGG ✓ UPPERREL_WINDOW ✓ UPPERREL_PARTIAL_DISTINCT ✓ UPPERREL_DISTINCT ✓ UPPERREL_ORDERED ✓ UPPERREL_FINAL
  • 39. 下位ノードを持つ CustomPath の作成 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 39 typedef struct CustomPath { Path path; uint32 flags; /* mask of CUSTOMPATH_* flags */ List *custom_paths; /* list of child Path */ List *custom_private; const struct CustomPathMethods *methods; } CustomPath; typedef struct CustomPathMethods { const char *CustomName; /* Convert Path to a Plan */ Plan *(*PlanCustomPath) (PlannerInfo *root, RelOptInfo *rel, CustomPath *best_path, List *tlist, List *clauses, List *custom_plans); : } typedef struct CustomScan { Scan scan; uint32 flags; List *custom_plans; /* list of Plan nodes */ List *custom_exprs; List *custom_private; List *custom_scan_tlist; Bitmapset *custom_relids; CustomScanMethods *methods; } CustomScan; void BeginCustomScan(CustomScanState *node, ...) { CustomScan *cscan = (CustomScan *)node->ss.ps->plan; foreach (lc, cscan->custom_plans) { Plan *child_plan = lfirst(lc); child_ps = ExecInitNode(child_plan, ...); :
  • 40. PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 40 CustomScan APIの拡張 ~ 非同期APIへの対応
  • 41. FDWにおける非同期API(1/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 41 子テーブル① (Foreign Table) 子テーブル② (Foreign Table) 子テーブル③ (Foreign Table) 子テーブル④ (Foreign Table) リモートサーバー Gather Append Foreign Scan on ① Foreign Scan on ② Foreign Scan on ③ Foreign Scan on ④ パーティションテーブル nworkers=2 backend worker-1 worker-2
  • 42. FDWにおける非同期API(1/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 42 子テーブル① (Foreign Table) 子テーブル② (Foreign Table) 子テーブル③ (Foreign Table) 子テーブル④ (Foreign Table) リモートサーバー Gather Append Foreign Scan on ① Foreign Scan on ② Foreign Scan on ③ Foreign Scan on ④ パーティションテーブル nworkers=2 worker-1
  • 43. FDWにおける非同期API(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 43 /* Support functions for asynchronous execution */ bool IsForeignPathAsyncCapable(ForeignPath *path); ForeignPathが非同期実行をサポートしているかどうかを オプティマイザに通知する void ForeignAsyncRequest(AsyncRequest *areq); リモートサーバから非同期に受け取ったタプルを一つ、 呼び出し元へ返す、またはareq->callback_pending=trueを セットして結果待ちである事を呼び出し元に知らせる、あるい はスロットにNULLをセットして終端に達した事を知らせる。 void ForeignAsyncConfigureWait(AsyncRequest *areq); 結果待ちである場合、WaitEventSetWait()の対象となる ファイルディスクリプタを追加する。 (読み出し可能となった時点でプロセスが起床する) void ForeignAsyncNotify(AsyncRequest *areq); 新たにリモートから処理結果を受け取ったら、そのタプルを 一つ、呼び出し元へ返す。 ① ForeignAsyncRequest(初回)を通じて、リモートサーバに 実行開始のリクエスト。 Append Foreign Scan on ① Foreign Scan on ② Foreign Scan on ③ SeqScan on ④
  • 44. FDWにおける非同期API(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 44 /* Support functions for asynchronous execution */ bool IsForeignPathAsyncCapable(ForeignPath *path); ForeignPathが非同期実行をサポートしているかどうかを オプティマイザに通知する void ForeignAsyncRequest(AsyncRequest *areq); リモートサーバから非同期に受け取ったタプルを一つ、 呼び出し元へ返す、またはareq->callback_pending=trueを セットして結果待ちである事を呼び出し元に知らせる、あるい はスロットにNULLをセットして終端に達した事を知らせる。 void ForeignAsyncConfigureWait(AsyncRequest *areq); 結果待ちである場合、WaitEventSetWait()の対象となる ファイルディスクリプタを追加する。 (読み出し可能となった時点でプロセスが起床する) void ForeignAsyncNotify(AsyncRequest *areq); 新たにリモートから処理結果を受け取ったら、そのタプルを 一つ、呼び出し元へ返す。 ① ForeignAsyncRequest(初回)を通じて、リモートサーバに 実行開始のリクエスト。 ② ForeignAsyncConfigureWaitにより同期イベントをセット Append Foreign Scan on ① Foreign Scan on ② Foreign Scan on ③ SeqScan on ④
  • 45. FDWにおける非同期API(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 45 /* Support functions for asynchronous execution */ bool IsForeignPathAsyncCapable(ForeignPath *path); ForeignPathが非同期実行をサポートしているかどうかを オプティマイザに通知する void ForeignAsyncRequest(AsyncRequest *areq); リモートサーバから非同期に受け取ったタプルを一つ、 呼び出し元へ返す、またはareq->callback_pending=trueを セットして結果待ちである事を呼び出し元に知らせる、あるい はスロットにNULLをセットして終端に達した事を知らせる。 void ForeignAsyncConfigureWait(AsyncRequest *areq); 結果待ちである場合、WaitEventSetWait()の対象となる ファイルディスクリプタを追加する。 (読み出し可能となった時点でプロセスが起床する) void ForeignAsyncNotify(AsyncRequest *areq); 新たにリモートから処理結果を受け取ったら、そのタプルを 一つ、呼び出し元へ返す。 ① ForeignAsyncRequest(初回)を通じて、リモートサーバに 実行開始のリクエスト。 ② ForeignAsyncConfigureWaitにより同期イベントをセット ③ リモート実行中に、同期実行できるものを実行 Append Foreign Scan on ① Foreign Scan on ② Foreign Scan on ③ SeqScan on ④
  • 46. FDWにおける非同期API(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 46 /* Support functions for asynchronous execution */ bool IsForeignPathAsyncCapable(ForeignPath *path); ForeignPathが非同期実行をサポートしているかどうかを オプティマイザに通知する void ForeignAsyncRequest(AsyncRequest *areq); リモートサーバから非同期に受け取ったタプルを一つ、 呼び出し元へ返す、またはareq->callback_pending=trueを セットして結果待ちである事を呼び出し元に知らせる、あるい はスロットにNULLをセットして終端に達した事を知らせる。 void ForeignAsyncConfigureWait(AsyncRequest *areq); 結果待ちである場合、WaitEventSetWait()の対象となる ファイルディスクリプタを追加する。 (読み出し可能となった時点でプロセスが起床する) void ForeignAsyncNotify(AsyncRequest *areq); 新たにリモートから処理結果を受け取ったら、そのタプルを 一つ、呼び出し元へ返す。 ① ForeignAsyncRequest(初回)を通じて、リモートサーバに 実行開始のリクエスト。 ② ForeignAsyncConfigureWaitにより同期イベントをセット ③ リモート実行中に、同期実行できるものを実行 ④ 結果が返ってきていれば、ForeignAsyncNotifyを通じ て結果を取得。一行を返す。 Append Foreign Scan on ① Foreign Scan on ② Foreign Scan on ③ SeqScan on ④
  • 47. CustomScan APIにおける非同期処理APIの追加(1/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 47 ▌ForeignScan の非同期APIとの違いは?  ほとんどない。  CustomScanが非同期APIをサポートするかどうか、 CUSTOMPATH_SUPPORT_ASYNC_EXECUTIONフラグを用いてオプ (専用のコールバックは設けていない) ▌追加するコールバックは  void CustomScanAsyncRequest(AsyncRequest *areq);  void CustomScanAsyncConfigureWait(AsyncRequest *areq);  void CustomScanAsyncNotify(AsyncRequest *areq); ➔ 使い方は FDW のケースと全く同一
  • 48. CustomScan APIにおける非同期処理APIの追加(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 48 Computational Storage SSDドライブ上にFPGAやARMプロセッサを 搭載し、ストレージドライブ上でユーザの 開発したソフトウェアを実行する事ができる。 Flashストレージの業界では最もホットな話題の一つ。 仮に2U/24ドライブのサーバにフル実装したら、 24ノードのワーカーが走っているのと同じ。☺ 子テーブル① (Heap Table) 子テーブル② (Heap Table) 子テーブル③ (Heap Table) 子テーブル④ (Heap Table) パーティションテーブル shared buffer Filesystem NVME Block System 参照 SELECT + Index 書き込み INSERT/UPDATE/DELETE
  • 49. CustomScan APIにおける非同期処理APIの追加(2/2) PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 49 Computational Storage SSDドライブ上にFPGAやARMプロセッサを 搭載し、ストレージドライブ上でユーザの 開発したソフトウェアを実行する事ができる。 Flashストレージの業界では最もホットな話題の一つ。 仮に2U/24ドライブのサーバにフル実装したら、 24ノードのワーカーが走っているのと同じ。☺ 子テーブル① (Heap Table) 子テーブル② (Heap Table) 子テーブル③ (Heap Table) 子テーブル④ (Heap Table) パーティションテーブル shared buffer Filesystem NVME Block System 検索・集計 SELECT + Scan
  • 50. まとめ  CustomScan APIとは ✓ FDWが「何を」テーブルとして見せるのかに対して、テーブルを「どのように」処理するかを プラガブルにするための機構。 ✓ PostgreSQL v9.5でサポート。PostgreSQLを母体とするソリューションで割と使われている。  オプティマイザ ✓ set_rel_pathlist_hook やset_join_pathlist_hookを用いて、独自の CustomPath を追加する。 ✓ 上位ノードに結果を返す際の列定義情報(custom_scan_tlist)に注意する。  エグゼキュータ ✓ BeginCustomScanで初期化、ExecCustomScanで実行、EndCustomScanで終了 ✓ 上位ノードに結果を返す際の列定義情報(TupleDesc)に注意。必ず一致していないとダメ。 ✓ 本来の SCAN や JOIN の処理と同じ結果を返しさえすれば、どのような方法で実装してもよい。 ✓ パラレルクエリの場合は、共有メモリ(DSM)を介して他のワーカーと協調する。  今後の機能強化 ✓ ForeignScan同様の非同期処理用のAPIを提案中 ✓ Smart-SSDやSmart-NICでSQLを処理する際に、非同期処理を記述できるようになる。 PostgreSQL Conference Japan 2022 ~CustomScan APIを使い倒して俺様DBエンジンを実装する~ 50