
2026/04/05 21:08
Pgit:Linux カーネルを PostgreSQL にインポートしました。
RSS: https://news.ycombinator.com/rss
要約▶
日本語訳:
概要:
20年間にわたるLinuxカーネルの歴史(1 428 882コミット)が、pgitと呼ばれるPostgreSQLベースのシステムに完全にロードされました。これはpg‑xpatchデルタ圧縮ツールを使用しています。140万件以上のコミットをインポートするには、AMD EPYCサーバーでわずか2時間しかかからず、テキスト内容は123 GBから約1.1 GB(≈53倍圧縮)に縮小しました。結果として生成されたデータベースは24 Mファイルバージョン、3.09 Mユニークブロブ、171 525パスを137 600のデルタグループに折りたたみ、ディスク上で約6.6 GB(実際のデータ量2.7 GB)を占有します。
リポジトリ指標とパターン:
- 38 506人のユニーク著者 vs 1 540人のコミッタ(25:1比)。
- コミットの90%が5つ以下のファイルに触れ、最大の単一マージは53 003ファイルに影響。
- 結合分析では頻繁な共変更(例:i915/intel_drv.h ↔ intel_display.c, 1 117回)とBPFヘッダーなどの隠れた依存関係が浮き彫りになりました。
マージ活動:
主要メンテナ3名がマージを主導しています:David S. Miller(113 k)、Greg Kroah‑Hartman(105 k)、Linus Torvalds(102 k)。彼らのマージ比率は自身のコミット数の2.3倍から7.3倍です。
企業貢献:
Intelが83 kコミットでリード、Red Hatが次点(エンジニア1人あたり110コミット)、kernel.orgメンテナは平均約306コミット/人、Amazonの寄与はごくわずか(1人あたり14コミット)。
その他の観察事項:
- 最も修正されたコミットには665件の「Fixes:」参照があり、2番目に多いものは196。
- コミットメッセージ内の不適切語数:8 435件「workaround」、2 438件「hack」、2 161件「ugly」、533件「crap」、268件「stupid」、81件「damn」、29件「shit」、7件「fuck」。完全なFバンを使用したのはAl ViroとLinus Torvaldsのみ。
- 三重リバートは3件だけで、すべてメモリ管理またはステージングサブシステムに関連しています。
パフォーマンスと将来利用:
ほとんどの分析は数秒で実行できます(例:結合解析48 s、著者解析34 s)。これはSQLが歴史的洞察を提供する力を示しています。チームはpgitをさらに深い依存関係解析に適用し、高影響ファイルペアの特定や回帰トラッキングを行いながら高速クエリ性能を維持する計画です。
インパクト:
カーネルメンテナはコミットパターンを照会してマージ戦略を洗練でき、企業はコード品質の監査やテスト対象となる重要ファイルを特定できます。このような大規模ソフトウェア履歴に対するSQLデータベースの成功は、他の大規模オープンソースプロジェクトにも同様の手法が有益であることを示唆しています。
本文
TL;DR
Linuxカーネルの全履歴を pgit に取り込んだ – 1 428 882コミット、24.4 百万ファイルバージョン、20年にわたる開発 ― を PostgreSQL 上でデルタ圧縮して保存しました。
- 実データ量:2.7 GB(
では1.95 GB)git gc --aggressive - インポート時間:専用サーバーで2 h
- コミットメッセージに含まれる f‑bomb は 1.4 百万件中 7 件(全て 2 人から)
- 665 件のバグ修正が同一コミットを指している
- ファイルシステムは 13 年かけて統合
Linuxカーネルを SQL データベースとして扱う。
インポートについて
この投稿は pgit: What If Your Git History Was a SQL Database? を踏まえて書いたものです。
簡潔に言えば pgit は Git に似た CLI で、すべてのデータをファイルシステムではなく PostgreSQL 上に置きます。
pg-xpatch を利用して透明なデルタ圧縮を行い、コミット履歴全体を SQL クエリで検索できるようにします。
HN のフロントページで Linux カーネルのインポートを発表した際、実際に何が起きたかをまとめました。
Linux カーネルは世界最大級のアクティブ開発リポジトリです。
- 1.4 百万コミット(20 年)
- 171 000 ファイル
- 38 000 コントリビュータ
私が調べた限り、git 以外でカーネル履歴全体をインポートした VCS は数少ないです。Fossil(SQLite ベース)は未実装、Darcs と Monotone はパフォーマンス問題に直面しました。Mercurial では可能ですが、私の経験では pgit が最適でした。
pgit は以下のデータを扱いました。
| 指標 | 値 |
|---|---|
| コミット数 | 1 428 882 |
| ファイルバージョン(file refs) | 24 384 844 |
| ユニークブロブ | 3 089 589 |
| ユニークパス | 171 525 |
| パスグループ(デルタチェーン) | 137 600 |
| インポート時間 | 2 h 0 m 48 s |
インポートはフィンランドの Hetzner 専用サーバーで実行。CPU は AMD EPYC 7401P、RAM 512 GB、ストレージは RAID 0 の SSD(合計 3.84 TB)です。
xpatch コンテンツキャッシュは 350 GB を確保しています。
サーバー構成・git ベースライン・pgit 設定
サーバー
CPU: AMD EPYC 7401P (24 コア / 48 スレッド) RAM: 16×32 GB DDR4 ECC (512 GB 合計) ストレージ: 2×Micron SSD SATA 1.92 TB Datacenter (RAID 0) NIC: 1 Gbps Intel I350 コスト: 約€272/月
OS インストール
- Hetzner の installimage で Ubuntu 24.04 LTS をインストール
- RAID 0 (
) でスループット最大化(冗長性不要)SWRAIDLEVEL 0 - パーティション配置
ext3, 1 GiB/boot
swap, 4 GiBswap
ext4, 残り (~3.5 TB)/
OS チューニング
# パッケージ更新・インストール apt update && apt upgrade -y apt install -y tmux btop htop iotop cpufrequtils numactl git curl wget unzip build-essential ufw linux-tools-common linux-tools-$(uname -r) # CPU governor → performance for cpu in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo performance > "$cpu"; done cat > /etc/default/cpufrequtils << 'EOF' GOVERNOR="performance" EOF systemctl enable cpufrequtils && systemctl restart cpufrequtils # カーネルミティゲーションをオフ sed -i 's/GRUB_CMDLINE_LINUX_DEFAULT="consoleblank=0"/GRUB_CMDLINE_LINUX_DEFAULT="consoleblank=0 mitigations=off"/' /etc/default/grub.d/hetzner.cfg update-grub # sysctl チューニング cat >> /etc/sysctl.conf << 'EOF' vm.swappiness = 1 vm.dirty_ratio = 5 vm.dirty_background_ratio = 2 kernel.numa_balancing = 1 EOF sysctl -p # Transparent Huge Pages を無効化 echo never > /sys/kernel/mm/transparent_hugepage/enabled echo never > /sys/kernel/mm/transparent_hugepage/defrag cat > /etc/systemd/system/disable-thp.service << 'EOF' [Unit] Description=Disable Transparent Huge Pages DefaultDependencies=no After=sysinit.target local-fs.target Before=basic.target [Service] Type=oneshot ExecStart=/bin/sh -c 'echo never > /sys/kernel/mm/transparent_hugepage/enabled && echo never > /sys/kernel/mm/transparent_hugepage/defrag' [Install] WantedBy=basic.target EOF systemctl daemon-reload && systemctl enable disable-thp # noatime を有効化 sed -i 's|relatime|noatime|g' /etc/fstab mount -o remount,noatime / # ファイアウォール設定 ufw default deny incoming ufw default allow outgoing ufw allow ssh ufw --force enable # Go 1.26.0 をインストール wget https://go.dev/dl/go1.26.0.linux-amd64.tar.gz rm -rf /usr/local/go && tar -C /usr/local -xzf go1.26.0.linux-amd64.tar.gz rm go1.26.0.linux-amd64.tar.gz echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.bashrc source ~/.bashrc # Docker をインストール apt install -y docker.io systemctl enable docker && systemctl start docker reboot
pg-xpatch コンテナ
docker pull ghcr.io/imgajeed76/pg-xpatch:latest
pgit バージョン
pgit v4 で、インポート時にまだリリースされていなかったローカル変更を加えました。主な変更点は seq 列の追加(モノトニックタイムスタンプハックを置き換)と --timeout フラグの追加です。
pgit 設定
# PostgreSQL コア設定 pgit config --global container.shared_buffers 64GB pgit config --global container.effective_cache_size 400GB pgit config --global container.work_mem 256MB pgit config --global container.wal_buffers 512MB pgit config --global container.max_wal_size 32GB pgit config --global container.checkpoint_timeout 60min pgit config --global container.max_connections 50 pgit config --global container.port 5433 pgit config --global container.shm_size 450g # 並列処理(24c/48t EPYC) pgit config --global container.max_worker_processes 28 pgit config --global container.max_parallel_workers 24 pgit config --global container.max_parallel_per_gather 12 # Xpatch コンテンツキャッシュ (350 GB) pgit config --global container.xpatch_cache_size_mb 358400 pgit config --global container.xpatch_cache_max_entries 41000000 pgit config --global container.xpatch_cache_max_entry_kb 16384 pgit config --global container.xpatch_cache_slot_size_kb 4 pgit config --global container.xpatch_cache_partitions 24 # Xpatch サブキャッシュ pgit config --global container.xpatch_group_cache_size_mb 256 pgit config --global container.xpatch_tid_cache_size_mb 4096 pgit config --global container.xpatch_seq_tid_cache_size_mb 4096 # Xpatch 挿入 / エンコード pgit config --global container.xpatch_insert_cache_slots 256 pgit config --global container.xpatch_encode_threads 2 pgit config --global container.xpatch_warm_cache_workers 24 # インポートワーカー数 pgit config --global import.workers 24
設定の根拠(概要)
| パラメータ | 値 | 理由 |
|---|---|---|
| 64 GB | ディスク上のデータセットは約20 GB、余裕を持って 3 倍に設定 |
| 400 GB | shared_buffers + OS ページキャッシュ + xpatch キャッシュ |
| 256 MB | 1 接続あたりのソート/ハッシュ結合用メモリ(50 接続 × 256 MB = 12.8 GB) |
| 512 MB | バルクインポート時の書き込みバーストを吸収 |
| 32 GB | 大量書き込み時にチェックポイント遅延 |
| 60 min | 強制チェックポイントによる I/O スタール最小化 |
| 450 GB | shared_buffers + xpatch キャッシュ + 内部構造のオーバーヘッドを考慮 |
git ベースライン測定
cd /root git clone --single-branch --branch master https://github.com/torvalds/linux.git cd linux git rev-list --count HEAD # 1,428,882 git gc --quiet && du -sb .git/objects/pack/*.pack # 6 213 222 259 (5.79 GB) git cat-file --batch-all-objects --batch-check='%(objecttype) %(objectsize)' \ | awk '{sum += $2} END {printf "%.2f GB\n", sum/1024/1024/1024}' # 144.43 GB time git fast-export --reencode=yes --show-original-ids master > linux.fastexport # 17m18s, 126 GB time git gc --aggressive --quiet && du -sb .git/objects/pack/*.pack # 2 093 181 079 (1.95 GB)
| 指標 | 値 |
|---|---|
| 未圧縮オブジェクトサイズ | 144.43 GB |
後のパックファイル | 5.79 GB |
後 | 1.95 GB |
| Fast‑export サイズ | 126 GB |
| インポート時間 | 2 h 0 m 48 s |
インポートプロセス
cd /root/linux-analysis pgit init time pgit import /root/linux --branch master --fastexport /root/linux.fastexport
| フェーズ | 時間 |
|---|---|
| コミットインポート | 39 m 57 s |
| コミットグラフ構築 | 13 s (最大深さ 75,641) |
| パスグループ計算 | 9.6 s (137,600 グループ) |
| ブロブインポート | 1 h 17 m |
| インデックス再構築 | 38 s |
| 合計 | 2 h 0 m 48 s (壁時間)、336 m 50 s CPU、21 m 12 s システム |
圧縮率
| 比率 | 値 |
|---|---|
| 未圧縮オブジェクト | 144.43 GB (1×) |
(ディスク上) | 6.6 GB (21.9×) |
通常 | 5.79 GB (24.9×) |
(実データ) | 2.7 GB (53.5×) |
| 1.95 GB (74.1×) |
git gc --aggressive が最も圧縮率が高く、1.95 GB は pgit の実データ 2.7 GB より約38 % 小さいです。Linux カーネルはコード再利用が多く、SPDX ヘッダーや
.c/.h ファイルの共通パターンが豊富なため、ファイルレベルでのデルタ圧縮に非常に適しています。
テキストのみ: 114.4× の圧縮。
xpatch は 123 GB のソーステキストを 1.1 GB に圧縮し、残り 1.6 GB はメタデータ(ファイル ↔ コミットマッピング、パスマッピング、リファレンス)です。カーネル全歴史でバイナリブロブはわずか 52 個しか存在せず、ほぼ完全にテキストです。
ディスク上の詳細
| コンポーネント | サイズ |
|---|---|
| コミット(xpatch) | 600 MB |
| テキストコンテンツ(xpatch) | 1.3 GB |
| バイナリコンテンツ(xpatch) | 2.0 MB |
| ファイル refs(ヒープ) | 2.1 GB |
| パス(ヒープ) | 13.2 M B |
| その他(refs, メタデータ, sync) | 40.0 KB |
| インデックス | 2.7 GB |
| ディスク総計 | 6.6 GB |
- 171,525 パスは 137,600 のデルタグループに圧縮(リネーム/コピー検出)
- 24.4M ファイル refs は 3.1M ユニークコンテンツバージョンを指し、7.9× のブロブ重複除去が実現
1.4 百万コミットから分かること
すべてのクエリは PostgreSQL 上で直接実行され、ほとんどは 10 秒以内に完了しました。マテリアライズドビューや事前処理は一切行っていません。
著者
- 38,506 ユニーク著者(メールアドレス)
- 1,540 のみがマージ権限を持つ(25:1 の比率)
- 約 14,000 が 1 件だけのパッチを寄与し、以後は戻っていない
コミットサイズ
| ファイル数 | コミット数 | % |
|---|---|---|
| 1 file | 875 541 | 61.3 % |
| 2–5 files | 414 018 | 29.0 % |
| 6–10 files | 70 951 | 5.0 % |
| 11–50 files | 49 700 | 3.5 % |
| 51+ files | 18 523 | 1.3 % |
「論理的変更は1コミットに収める」というカーネルの原則が守られています。最大で53,003ファイルを触ったコミットも、トップ5 の大きなコミットはサブシステムメンテナからのマージです。
ファイル結合(共変更分析)
- 最高結合ペア:
とi915/intel_drv.h
– 1,117 回共変更i915/intel_display.c - その他注目ペア:
↔include/uapi/linux/bpf.h
(742回)、tools/include/uapi/linux/bpf.h
↔net/ipv4/tcp_ipv4.c
(739回)net/ipv6/tcp_ipv6.c
マージ階層
- David S. Miller – 113 456 コミット、15 617 マージ(7.3×)
- Greg Kroah‑Hartman – 105 733 コミット、7 073 マージ(15×)
- Linus Torvalds – 102 322 コミット、4 525 マージ(2.3×)
企業貢献
| 組織 | コミット数 | 著者 |
|---|---|---|
| Intel | 83 187 | 1 704 |
| Red Hat | 72 695 | 658 |
| kernel.org | 69 451 | 227 |
| Linaro | 43 524 | 263 |
| AMD | 42 270 | 1 017 |
| SUSE | 35 711 | 222 |
| 29 276 | 809 | |
| Huawei | 24 156 | 540 |
| Amazon | 1 688 | 121 |
Intel がトップで、Red Hat チームは 1 人あたり平均110 コミットと最も生産的です。kernel.org のメンテナは平均 306 コミット。
Gmail vs 企業の傾向
- 2010 年に「ハビエリスト」コミット(Gmail)がピークで、全体の約12 %
- 2025 年までに 約8 % に減少
- 絶対数は安定(年平均7 K 件)、ただしカーネルはより企業寄与が増加
バグ修正の進化
Fixes: タグは 2013 年以前はほぼ無視されていたが、現在では >25 % のコミットに現れます。
- 最も参照されたコミット:
(Linus の初期 git インポート、2005/04/16) – 665 バグ修正がこのコミットを指す1da177e4c3f4 - 次に多いのは
(Intel Xe GPU ドライバ)、約2 年で 196 修正dd08ebf6c352
言語表現
7 件の f‑bomb がコミットメッセージに含まれ、全て Al Viro(5)と Linus Torvalds(2)から。
ソースコード内では
pgit search "fuck" で現在ファイルは 8 件、履歴全体で 50 件以上が 44 秒で検索可能。
単語頻度(コミットメッセージのみ):
| 単語 | カウント |
|---|---|
| workaround | 8 435 |
| hack | 2 438 |
| ugly | 2 161 |
| stupid | 533 |
| crap | 268 |
| damn | 81 |
| shit | 29 |
| fuck | 7 |
三重リバート
全履歴で 3 件だけが「リバートのリバートのリバート」。メモリー管理やステージングサブシステムに関係。
カーネルの物語
- 週末ワーカー: Jonathan Cameron, Christophe JAILLET など、週末に 50 % 超のコミットを行う
- 単一ファイル愛好家: Connor McAdams(89 件)や Lydia Wang(63 件)はそれぞれ 1 ファイルのみを対象
- キャリア軌跡: James Bottomley は 20 年で 19 ドメインからコミット、Linus は 12、David S. Miller は 11
- クリスマスコミット: 21 年のうち一度もゼロコミットのクリスマスはなく、2005 年でも少なくとも1件
- 最忙しい日: 2022/11/18 – 662 コミット、Uwe Kleine‑König が 583 件
クエリ性能
すべてのクエリは 1.4 百万コミットを対象に実行しました。
| クエリ | 時間 |
|---|---|
| スタッツ & 圧縮情報 | 2.1 s |
| ファイル変更量(24.4M refs) | 2.3 s |
| ホットスポット | 1.8 s |
| 結合度(Goで計算) | 48.3 s |
| 著者一覧(全スキャン) | 34.3 s |
| 年次活動 | 9.4 s |
| 現在ファイルの全文検索 | 25 s |
| 全履歴の全文検索 | 44 s |
マテリアライズドビューや前処理は一切行っていません。すべて PostgreSQL と
pg-xpatch のデルタ圧縮で実現。
分析に使用した SQL コマンド
-- ストレージ & 圧縮情報 pgit stats --xpatch -- 変更量分析 pgit analyze churn --limit 30 -- ホットスポット pgit analyze hotspots --depth 1 --limit 25 -- 著者リスト pgit analyze authors --limit 30 --timeout 60m -- 年次活動 pgit analyze activity --period year --limit 25 --timeout 60m -- 結合度分析 pgit analyze coupling --limit 30 --timeout 60m -- マージ階層(SQL) SELECT committer_name, COUNT(*) AS merged, SUM(CASE WHEN author_name = committer_name THEN 1 ELSE 0 END) AS self_authored FROM pgit_commits GROUP BY committer_name ORDER BY merged DESC LIMIT 15; -- 企業寄与 SELECT CASE WHEN author_email LIKE '%@intel.com' THEN 'Intel' WHEN author_email LIKE '%@redhat.com' THEN 'Red Hat' WHEN author_email LIKE '%@kernel.org' THEN 'kernel.org' /* … */ END AS org, COUNT(*) AS commits, COUNT(DISTINCT author_email) AS authors FROM pgit_commits GROUP BY org ORDER BY commits DESC; -- Fixes: タグの進化 SELECT EXTRACT(YEAR FROM authored_at)::int AS year, SUM(CASE WHEN message ~* 'Fixes:\s+[0-9a-f]{12}' THEN 1 ELSE 0 END) AS fixes_commits, COUNT(*) AS total FROM pgit_commits GROUP BY year ORDER BY year; -- 最も修正されたコミット SELECT SUBSTRING(message FROM 'Fixes:\s+([0-9a-f]{12})') AS broken_commit, COUNT(*) AS times_fixed FROM pgit_commits WHERE message ~* 'Fixes:\s+[0-9a-f]{12}' GROUP BY broken_commit ORDER BY times_fixed DESC LIMIT 10; -- 言語表現(ワード境界) WITH words(word) AS ( VALUES ('fuck'),('shit'),('damn'),('stupid'),('crap'), ('ugly'),('hack'),('workaround') ) SELECT w.word, COUNT(*) AS cnt FROM pgit_commits c, words w WHERE c.message ~* ('\\y' || w.word || '\\y') GROUP BY w.word ORDER BY cnt DESC; -- ソースコード検索(現在ファイル) pgit search "fuck" --path "*.c" --path "*.h" -- ソースコード検索(全履歴) pgit search "fuck" --path "*.c" --path "*.h" --all -- 三重リバート SELECT author_name, authored_at::date, LEFT(message, 200) FROM pgit_commits WHERE message ILIKE 'Revert \"Revert \"Revert%'; -- Kent Overstreet の軌跡 SELECT EXTRACT(YEAR FROM authored_at)::int AS year, COUNT(*) FROM pgit_commits WHERE author_name = 'Kent Overstreet' GROUP BY year ORDER BY year; -- 週末ワーカー SELECT author_name, COUNT(*) AS weekend_commits, (SELECT COUNT(*) FROM pgit_commits c2 WHERE c2.author_name = c.author_name) AS total FROM pgit_commits c WHERE EXTRACT(DOW FROM authored_at) IN (0, 6) GROUP BY author_name ORDER BY weekend_commits DESC LIMIT 15;
リンク
は Linux カーネルを扱えます。pgit- 投稿以降、xpatch をベースにした
が作られました:Cloudflare Durable Objects 上で動く自己ホスト型 Git リモート(SQLite + デルタ圧縮)。ripgit
go install github.com/imgajeed76/pgit/v4/cmd/pgit@latest