
Pgit: Tôi đã nhập hạt nhân Linux vào PostgreSQL
Pgit: I Imported the Linux Kernel into PostgreSQL
SKIP
Tôi đã nhập toàn bộ lịch sử git nhân Linux vào bộ lưu trữ PostgreSQL của pgit. 1.428.882 cam kết, 24,4 triệu phiên bản tệp, 20 năm phát triển. Đây là hạt nhân trông như thế nào khi bạn có thể hỏi.
TL;DR: Đã nhập toàn bộ lịch sử hạt nhân Linux vào pgit. 1.428.882 commit, 24,4 triệu phiên bản tệp, 20 năm phát triển, được lưu trữ trong PostgreSQL với tính năng nén delta. Dữ liệu thực tế: 2,7 GB (git gc --aggressive đạt 1,95 GB). Quá trình nhập mất 2 giờ trên một máy chủ chuyên dụng. Sau đó, tôi bắt đầu đặt các câu hỏi. 7 từ chửi thề trong 1,4 triệu tin nhắn commit (tất cả đều từ 2 người). 665 bản sửa lỗi trỏ đến một commit duy nhất. Một hệ thống tệp mất 13 năm để hợp nhất. Đây là cách hạt nhân Linux trông như thế nào dưới dạng cơ sở dữ liệu SQL.
Quá trình nhập
Bài viết này được xây dựng dựa trên pgit: Điều gì sẽ xảy ra nếu lịch sử Git của bạn là cơ sở dữ liệu SQL?. Nếu bạn chưa đọc nó, hãy bắt đầu từ đó. Phiên bản ngắn gọn: pgit là một CLI giống như Git, nơi mọi thứ nằm trong PostgreSQL thay vì hệ thống tệp. Nó sử dụng pg-xpatch để nén delta trong suốt và làm cho toàn bộ lịch sử commit của bạn có thể truy vấn bằng SQL. Sau khi bài viết về pgit lên trang đầu HN và được TLDR, console.dev và dailydev đưa tin, tôi đã "nhá hàng" rằng mình đang nhập hạt nhân Linux. Đây là những gì đã xảy ra.
Hạt nhân Linux là một trong những kho lưu trữ được phát triển tích cực lớn nhất trên thế giới. 1,4 triệu commit trải dài trong 20 năm, 171.000 tệp, 38.000 người đóng góp. Theo những gì tôi tìm hiểu được, chỉ một số ít hệ thống quản lý phiên bản (VCS) ngoài git từng thực hiện thành công việc nhập toàn bộ lịch sử của hạt nhân. Fossil (dựa trên SQLite, bởi nhóm SQLite) chưa bao giờ làm được. Darcs và Monotone đã thử nhưng gặp vấn đề nghiêm trọng về hiệu suất. Mercurial có thể làm được điều đó. Hãy sửa cho tôi nếu tôi có bất kỳ sai sót nào ở đây.
pgit đã xử lý được nó.
| Chỉ số | Giá trị |
|---|---|
| Số lượng commit | 1,428,882 |
| Phiên bản tệp (file refs) | 24,384,844 |
| Blob duy nhất | 3,089,589 |
| Đường dẫn duy nhất | 171,525 |
| Nhóm đường dẫn (chuỗi delta) | 137,600 |
| Thời gian nhập | 2 giờ 0 phút 48 giây |
Quá trình nhập chạy trên máy chủ chuyên dụng Hetzner tại Phần Lan: AMD EPYC 7401P (24 nhân / 48 luồng), 512 GB DDR4 ECC RAM, 2×1.92 TB SSD trong RAID 0. Với bộ nhớ đệm nội dung xpatch 350 GB, toàn bộ kho lưu trữ đã giải mã đều nằm gọn trong bộ nhớ.
Thiết lập máy chủ đầy đủ, git baseline và cấu hình pgit
Máy chủ
Hetzner Dedicated "Server Auction" từ trung tâm dữ liệu Phần Lan (HEL1):
| Thành phần | Thông số |
|---|---|
| CPU | AMD EPYC 7401P (24 nhân / 48 luồng) |
| RAM | 16×32 GB DDR4 ECC reg. (tổng 512 GB) |
| Lưu trữ | 2×Micron SSD SATA 1.92 TB Datacenter (RAID 0) |
| NIC | 1 Gbit Intel I350 |
| Chi phí | ~€272/tháng |
Cài đặt hệ điều hành
installimage của Hetzner với Ubuntu 24.04 LTS. Hai thay đổi so với cấu hình mặc định: RAID 0 (SWRAIDLEVEL 0) để có lưu lượng tối đa (không cần dự phòng cho công việc phân tích tạm thời) và bố cục phân vùng đơn giản:
PART /boot ext3 1024M
PART swap swap 4G
PART / ext4 all
Điều này cung cấp khoảng 3,5 TB dung lượng lưu trữ khả dụng trên hai ổ SSD 1,92 TB.
Tinh chỉnh hệ điều hành
Sau khi khởi động vào image đã cài đặt:
# --- Các gói phần mềm ---
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 (tất cả 48 luồng) ---
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
# --- Tắt các biện pháp giảm thiểu Kernel ---
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
# --- Vô hiệu hóa 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 /
# --- Tường lửa ---
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
# --- Khởi động lại để áp dụng các thay đổi ---
reboot
Container pg-xpatch
Đã tải xuống image Docker pg-xpatch mới nhất chuẩn:
docker pull ghcr.io/imgajeed76/pg-xpatch:latest
Phiên bản pgit
pgit v4 với một vài thay đổi cục bộ chưa được phát hành tại thời điểm nhập. Đến khi bạn đọc bài viết này, chúng đã được đưa vào phiên bản mới nhất, vì vậy mọi thứ ở đây đều có thể tái tạo bằng lệnh go install thông thường. Thay đổi chính là bản sửa lỗi sắp xếp seq, thay thế việc hack dấu thời gian đơn điệu bằng cột seq INTEGER NOT NULL rõ ràng để sắp xếp commit. Điều này giúp việc giải nén chuỗi delta nhanh hơn đáng kể khi quét tuần tự. Danh sách thay đổi đầy đủ:
db/schema.go— Đã thêm cộtseq INTEGER NOT NULL,order_by => 'seq'trongxpatch.configure()db/commits.go— Đã thêm trườngSeqvào struct, cập nhật tất cả các lệnh INSERT/COPYcli/import.go— Điền vàoSeq(đánh số từ 1), xóa bỏ hack dấu thời gian đơn điệurepo/commit.go—pgit committính toánMAX(seq)+1, bao gồmseqtrong INSERTcli/analyze.go— Cờ--timeout(thay thế giới hạn cứng 5 phút),ORDER BY seq ASCtrong các truy vấncli/local.go— Hiển thị image container thực tế thay vìDefaultImagecố địnhcontainer/runtime.go— HàmGetContainerImage()mới- Dọn dẹp tài liệu/văn bản trong README, sql.go, commits.go, ulid.go, config/reflect.go
Cấu hình pgit
# --- PostgreSQL core ---
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
# --- Parallelism (24c/48t EPYC 7401P) ---
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 content cache (350 GB) ---
pgit config --global container.xpatch_cache_size_mb 358400 # 350 GB
pgit config --global container.xpatch_cache_max_entries 41000000 # 31.5M cần thiết + 30%
pgit config --global container.xpatch_cache_max_entry_kb 16384 # 16 MB max cho mỗi mục
pgit config --global container.xpatch_cache_slot_size_kb 4 # mặc định, phù hợp với nhiều kích thước
pgit config --global container.xpatch_cache_partitions 24 # một cho mỗi lõi
# --- xpatch sub-caches ---
pgit config --global container.xpatch_group_cache_size_mb 256 # 85K nhóm cần 4 MB (62×)
pgit config --global container.xpatch_tid_cache_size_mb 4096 # 25.8M hàng cần 1.1 GB (3.7×)
pgit config --global container.xpatch_seq_tid_cache_size_mb 4096 # 25.8M hàng cần 1.5 GB (2.7×)
# --- xpatch insert / encoding ---
pgit config --global container.xpatch_insert_cache_slots 256 # 24 worker × nhóm đồng thời
pgit config --global container.xpatch_encode_threads 2 # ×24 worker = 48 HW threads
pgit config --global container.xpatch_warm_cache_workers 24 # một cho mỗi lõi
# --- Import ---
pgit config --global import.workers 24
Cơ sở lý luận cấu hình
| Tham số | Giá trị | Lý do |
|---|---|---|
shared_buffers | 64 GB | Tập dữ liệu ~20 GB trên đĩa, dự phòng 3×, toàn bộ DB nằm vừa trong buffer pool |
effective_cache_size | 400 GB | Gợi ý cho trình lập kế hoạch: shared_buffers + OS page cache + xpatch caches |
work_mem | 256 MB | Bộ nhớ mỗi thao tác cho sorts/hash joins; 50 kết nối × 256 MB = 12.8 GB trong trường hợp xấu nhất |
wal_buffers | 512 MB | Hấp thụ các đợt ghi tăng đột biến trong quá trình import hàng loạt |
max_wal_size | 32 GB | Trì hoãn các checkpoint trong quá trình ghi nặng |
checkpoint_timeout | 60 min | Giảm thiểu I/O stalls từ các checkpoint bắt buộc |
shm_size | 450 GB | 64 GB shared_buffers + 350 GB cache + 8 GB sub-caches + ~2 GB nội bộ ≈ 425 GB, làm tròn lên |
xpatch_cache_size_mb | 350 GB | Dung lượng giải mã ước tính ~55 GB, dự phòng 84% đảm bảo mọi thứ vừa vặn |
xpatch_cache_max_entries | 41M | 1.4M commits × 5 cột delta + 24.4M phiên bản tệp = 31.5M trong trường hợp xấu nhất, +30% đệm |
xpatch_encode_threads | 2 | ×24 worker = 48 luồng mã hóa, khớp chính xác với 48 HW threads |
import.workers | 24 | Một cho mỗi lõi vật lý |
Các chỉ số cơ sở của Git
Trước khi import, chúng tôi đã clone kernel và đo lường kho lưu trữ git gốc:
cd /root
git clone --single-branch --branch master https://github.com/torvalds/linux.git
cd /root/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 \
> /root/linux.fastexport # 17m18s, 126 GB
time git gc --aggressive --quiet && du -sb .git/objects/pack/*.pack # 24m46s, 2,093,181,079 (1.95 GB)
| Chỉ số | Giá trị |
|---|---|
| Commits | 1,428,882 |
| Dung lượng đối tượng thô chưa nén | 144.43 GB |
Packfile sau git gc | 5.79 GB |
Packfile sau git gc --aggressive | 1.95 GB |
Thời gian git gc --aggressive | 24m 46s (338m CPU) |
| Dung lượng Fast-export | 126 GB |
| Thời gian Fast-export | 17m 18s |
Quy trình import
Đã khởi động container pg-xpatch bằng pgit local start (kiểm tra khởi động bị timeout vì việc cấp phát 450 GB bộ nhớ chia sẻ mất chút thời gian, nhưng sau đó nó vẫn khởi động). Đã đợi cơ sở dữ liệu sẵn sàng bằng docker logs pgit-local -f.
cd /root/linux-analysis
pgit init
time pgit import /root/linux --branch master --fastexport /root/linux.fastexport
| Giai đoạn | Thời gian |
|---|---|
| Import Commit | 39m 57s |
| Xây dựng đồ thị commit | 13s (độ sâu tối đa 75,641) |
| Tính toán nhóm đường dẫn | 9.6s (137,600 nhóm từ 171,525 đường dẫn) |
| Import Blob | 1h 17m |
| Xây dựng lại chỉ mục | 38s |
| Tổng cộng | 2h 0m 48s (thực tế), 336m 50s CPU, 21m 12s sys |
Nén
| Dung lượng | Tỷ lệ | |
|---|---|---|
| Các đối tượng thô chưa nén | 144.43 GB | 1.0x |
| pgit (trên đĩa) | 6.6 GB | 21.9x |
| git gc (thông thường) | 5.79 GB | 24.9x |
| pgit (dữ liệu thực tế) | 2.7 GB | 53.5x |
| git gc --aggressive | 1.95 GB | 74.1x |
git gc --aggressive giành chiến thắng. 1.95 GB so với 2.7 GB dữ liệu thực tế của pgit. Nhỏ hơn khoảng 38%.
Điều này hoàn toàn dễ hiểu. Linux kernel về cơ bản là kịch bản lý tưởng của git cho việc nén delta giữa các đối tượng: tái sử dụng mã nguồn khổng lồ giữa các kiến trúc, các tiêu đề giấy phép SPDX được sao chép trong hơn 70,000 tệp, và 70% tất cả các tệp là .c/.h với các mẫu chung trên các phân hệ hoàn toàn không liên quan. Định dạng packfile của git có thể nén delta bất kỳ đối tượng nào so với bất kỳ đối tượng nào khác trong toàn bộ kho lưu trữ, bất kể đường dẫn tệp. pgit nén trong các chuỗi delta ở cấp độ tệp.
Những gì pgit đạt được: nén 114.4x chỉ tính riêng nội dung văn bản. xpatch đã nén 123 GB văn bản nguồn thành 1.1 GB. 1.6 GB còn lại là siêu dữ liệu (tệp nào nằm trong commit nào, ánh xạ đường dẫn, refs). Chỉ có 52 blob nhị phân tồn tại trong toàn bộ lịch sử kernel. Nó gần như hoàn toàn là văn bản.
Nhưng sự so sánh không thực sự nằm ở byte. git gc --aggressive mất 25 phút và cho bạn một packfile. pgit mất 2 giờ và cho bạn một cơ sở dữ liệu SQL. Câu hỏi là bạn có thể làm gì sau đó.
Phân tích chi tiết trên đĩa
| Thành phần | Dung lượng |
|---|---|
| Commits (xpatch) | 600.6 MB |
| Nội dung văn bản (xpatch) | 1.3 GB |
| Nội dung nhị phân (xpatch) | 2.0 MB |
| Tham chiếu tệp (heap) | 2.1 GB |
| Đường dẫn (heap) | 13.2 MB |
| Khác (refs, metadata, sync) | 40.0 KB |
| Chỉ mục (Indexes) | 2.7 GB |
| Tổng trên đĩa | 6.6 GB |
| Lớp | Dung lượng |
|---|---|
| xpatch (commits + text + binary) | 1.5 GB |
| Bảng thông thường (file_refs, paths, refs, metadata) | 1.2 GB |
| Dữ liệu thực tế | 2.7 GB |
| PostgreSQL overhead + chỉ mục | 3.9 GB |
Lưu ý: Bảng thứ hai đã loại bỏ overhead của PostgreSQL khỏi từng thành phần, do đó các hàng sẽ không cộng lại khớp với bảng tổng dung lượng trên đĩa ở trên.
171.525 đường dẫn được gộp thành 137.600 nhóm delta (phát hiện đổi tên/sao chép). Khử trùng lặp blob 7.9x: 24.4 triệu tham chiếu tệp chỉ trỏ đến 3.1 triệu phiên bản nội dung duy nhất.
1.4 triệu commit đã tiết lộ những gì
Mọi nội dung dưới đây đều được truy vấn trực tiếp từ PostgreSQL. Hầu hết các truy vấn hoàn thành trong dưới 10 giây. Không có materialized view, không tiền xử lý, không kịch bản nào phân tích cú pháp đầu ra của git log. Chỉ đơn thuần là SQL trên các bảng được nén delta.
38.506 tác giả. 36% không bao giờ quay lại.
Nhân (kernel) có 38.506 tác giả duy nhất (theo email) nhưng chỉ có 1.540 người thực hiện commit (committer) duy nhất. Trong quy trình gửi thư của kernel, bạn viết một bản vá và người bảo trì sẽ hợp nhất nó. Vì vậy, 38.506 người đã viết mã, nhưng chỉ 1.540 người có quyền hợp nhất. Tỷ lệ 25:1.
Gần 14.000 trong số các tác giả đó đã đóng góp đúng một bản vá và không bao giờ quay lại.
90% commit tác động đến 5 tệp trở xuống
| Số tệp tác động | Commit | % tổng số |
|---|---|---|
| 1 tệp | 875.541 | 61.3% |
| 2-5 tệp | 414.018 | 29.0% |
| 6-10 tệp | 70.951 | 5.0% |
| 11-50 tệp | 49.700 | 3.5% |
| 51+ tệp | 18.523 | 1.3% |
Quy tắc "mỗi commit một thay đổi logic" của kernel vẫn được giữ vững. Commit đơn lẻ lớn nhất đã tác động đến 53.003 tệp, nhưng cả 5 commit lớn nhất đều hóa ra là các commit hợp nhất từ những người bảo trì phân hệ. Không phải các thay đổi API quy mô lớn. Chỉ là công việc hạ tầng.
Sự liên kết tệp: những phụ thuộc ẩn
pgit analyze coupling tính toán những tệp nào luôn thay đổi cùng nhau. Đây là kiểu phân tích rất khó thực hiện với git (phân tích cú pháp đầu ra của git log, xây dựng ma trận thay đổi đồng thời, lọc nhiễu) nhưng lại vô cùng đơn giản khi lịch sử của bạn là một cơ sở dữ liệu SQL. Trên 1.4 triệu commit, nó hoàn thành trong 48 giây.
| Tệp A | Tệp B | Số lần thay đổi cùng nhau |
|---|---|---|
i915/intel_drv.h | i915/intel_display.c | 1.117 |
net/core/dev.c | include/linux/netdevice.h | 1.087 |
i915/i915_gem.c | i915/i915_drv.h | 1.072 |
arch/x86/kvm/x86.c | arch/x86/include/asm/kvm_host.h | 1.066 |
include/uapi/linux/bpf.h | tools/include/uapi/linux/bpf.h | 742 |
net/ipv4/tcp_ipv4.c | net/ipv6/tcp_ipv6.c | 739 |
Driver GPU Intel i915 chiếm vị trí đầu bảng: intel_drv.h và intel_display.c đã được thay đổi cùng nhau 1.117 lần. Driver i915 xuất hiện 8 lần trong top 30 cặp tệp liên kết chặt chẽ nhất.
Mục thú vị nhất: include/uapi/linux/bpf.h và tools/include/uapi/linux/bpf.h với 742 lần thay đổi cùng nhau. Mỗi thay đổi tiêu đề BPF của kernel đòi hỏi phải sao chép thủ công sang thư mục công cụ. Và tcp_ipv4.c với tcp_ipv6.c là 739: sửa một lỗi TCP trong IPv4 hầu như luôn đồng nghĩa với việc áp dụng cùng một bản sửa lỗi đó trong IPv6.
Toàn bộ 15 cặp liên kết hàng đầu
| Hạng | Tệp A | Tệp B | Số lần thay đổi cùng nhau |
|---|---|---|---|
| 1 | i915/intel_drv.h | i915/intel_display.c | 1.117 |
| 2 | net/core/dev.c | include/linux/netdevice.h | 1.087 |
| 3 | i915/i915_gem.c | i915/i915_drv.h | 1.072 |
| 4 | arch/x86/kvm/x86.c | arch/x86/include/asm/kvm_host.h | 1.066 |
| 5 | i915/intel_display.c | i915/i915_drv.h | 892 |
| 6 | include/net/cfg80211.h | net/wireless/nl80211.c | 783 |
| 7 | mlx5/core/en_main.c | mlx5/core/en.h | 778 |
| 8 | fs/btrfs/inode.c | fs/btrfs/ctree.h | 776 |
| 9 | fs/btrfs/ctree.h | fs/btrfs/extent-tree.c | 769 |
| 10 | fs/btrfs/disk-io.c | fs/btrfs/ctree.h | 757 |
| 11 | include/uapi/linux/bpf.h | tools/include/uapi/linux/bpf.h | 742 |
| 12 | net/ipv4/tcp_ipv4.c | net/ipv6/tcp_ipv6.c | 739 |
| 13 | i915/i915_drv.c | i915/i915_drv.h | 739 |
| 14 | sound/soc/codecs/Makefile | sound/soc/codecs/Kconfig | 674 |
| 15 | net/mac80211/ieee80211_i.h | net/mac80211/mlme.c | 670 |
Btrfs có 7 mục trong top 30, tất cả đều tỏa ra từ ctree.h. Tệp tiêu đề đó là trung tâm liên kết của toàn bộ hệ thống tệp Btrfs.
Ba người hợp nhất 22.5% tổng số commit
| Người hợp nhất (Committer) | Bản vá đã hợp nhất | Tự viết | Tỷ lệ hợp nhất |
|---|---|---|---|
| David S. Miller | 113.456 | 15.617 | 7.3x |
| Greg Kroah-Hartman | 105.733 | 7.073 | 15.0x |
| Linus Torvalds | 102.322 | 45.125 | 2.3x |
David S. Miller (mạng) là điểm hợp nhất bận rộn nhất: 7.9% tổng số commit của kernel chảy qua ông. Greg Kroah-Hartman tự viết 7 nghìn bản vá nhưng đã hợp nhất 106 nghìn. 15:1. John W. Linville thậm chí còn chênh lệch hơn: 18.9 nghìn bản hợp nhất, 1.1 nghìn bản tự viết. 16.5:1.
Bảng đầy đủ các committer (top 10)
| Người hợp nhất | Bản vá đã hợp nhất | Tự viết | Tỷ lệ hợp nhất |
|---|---|---|---|
| David S. Miller | 113.456 | 15.617 | 7.3x |
| Greg Kroah-Hartman | 105.733 | 7.073 | 15.0x |
| Linus Torvalds | 102.322 | 45.125 | 2.3x |
| Mark Brown | 49.674 | 8.759 | 5.7x |
| Mauro Carvalho Chehab | 39.869 | 6.571 | 6.1x |
| Alex Deucher | 37.053 | 4.201 | 8.8x |
| Ingo Molnar | 27.870 | 5.648 | 4.9x |
| Jakub Kicinski | 24.509 | 5.036 | 4.9x |
| Jens Axboe | 19.985 | 3.758 | 5.3x |
| John W. Linville | 18.882 | 1.146 | 16.5x |
Ai chi trả cho kernel
| Tổ chức | Commit | Tác giả | Commit/Tác giả |
|---|---|---|---|
| Intel | 83,187 | 1,704 | 49 |
| Red Hat | 72,695 | 658 | 110 |
| kernel.org | 69,451 | 227 | 306 |
| Linaro | 43,524 | 263 | 166 |
| AMD | 42,270 | 1,017 | 42 |
| SUSE | 35,711 | 222 | 161 |
| 29,276 | 809 | 36 | |
| Huawei | 24,156 | 540 | 45 |
| Amazon | 1,688 | 121 | 14 |
Intel đứng thứ 1 về khối lượng (83K commit, 1.704 kỹ sư). Red Hat đứng thứ 2 nhưng có đội ngũ năng suất nhất: 110 commit mỗi kỹ sư. Các người duy trì kernel.org (227 người) đạt trung bình 306 commit mỗi người. Đây chính là nhóm nhân sự tinh nhuệ.
Amazon nổi bật ở cuối bảng: 14 commit mỗi người. Họ tập trung vào ảo hóa Xen/KVM cho AWS, thay vì các công việc rộng hơn trên kernel. (Lưu ý: IBM chỉ hiển thị 53 commit vì kỹ sư của họ sử dụng @linux.ibm.com và @linux.vnet.ibm.com, khiến họ rơi vào nhóm "Khác". Tương tự, nhiều kỹ sư Huawei sử dụng @hisilicon.com.)
Các cá nhân đóng góp (địa chỉ Gmail, đại diện cho những người làm việc như một sở thích) đã đạt đỉnh 12% tổng số commit vào năm 2010. Đến năm 2025, con số này giảm xuống còn 8%. Số lượng tuyệt đối vẫn ổn định (~7K/năm), nhưng kernel ngày càng mang tính doanh nghiệp hơn theo thời gian.
Xu hướng Gmail so với doanh nghiệp qua thời gian
| Năm | Commit từ Gmail | Tổng số | Tỷ lệ Gmail % |
|---|---|---|---|
| 2005 | 452 | 16,696 | 2% |
| 2008 | 5,604 | 48,847 | 11% |
| 2010 | 6,091 | 49,819 | 12% (đỉnh) |
| 2014 | 8,602 | 75,659 | 11% |
| 2018 | 7,393 | 80,330 | 9% |
| 2022 | 7,438 | 86,810 | 8% |
| 2025 | 7,160 | 85,163 | 8% |
Commit "nhiều lỗi nhất" trong lịch sử Linux
Kernel có một quy ước: thẻ Fixes: trong tin nhắn commit tham chiếu đến chính xác commit đã gây ra lỗi. Đến năm 2026, hơn 1 trong 4 commit sử dụng nó (tăng từ gần như bằng 0 trước năm 2013).
Commit nào có nhiều tham chiếu Fixes: nhất? 1da177e4c3f4. Bản import git đầu tiên của Linus Torvalds. Ngày 16 tháng 4 năm 2005. 665 bản sửa lỗi trỏ về commit này.
Thực tế nó không hẳn là lỗi. Khi một lỗi đã tồn tại "mãi mãi" và không có commit cụ thể nào để đổ lỗi, các nhà phát triển trích dẫn 1da177e4c3f4 như một cách viết tắt cho "cái này đã luôn bị hỏng".
Commit được sửa nhiều thứ hai: dd08ebf6c352, việc giới thiệu driver GPU Xe của Intel. 196 bản sửa lỗi trong khoảng 2 năm. Một bản sửa lỗi mỗi 4 ngày kể từ khi driver này được tích hợp.
Commit lịch sự, code đầy giận dữ
Có 7 từ chửi thề (f-bomb) trong 1,4 triệu tin nhắn commit. Tất cả đều đến từ chính xác 2 người: Al Viro (5) và Linus Torvalds (2).
Nhưng mã nguồn lại kể một câu chuyện khác. pgit search "fuck" --path "*.c" --path "*.h" đã tìm thấy 8 kết quả khớp trong codebase hiện tại. Chạy cùng tìm kiếm đó với --all (mọi phiên bản của mọi tệp trong 20 năm lịch sử) đã tìm thấy hơn 50 kết quả trong 44 giây. Các điểm đáng chú ý:
- "Am I fucking pedantic or what?" (Tiêu đề driver SCSI, vẫn còn trong code ngày nay)
- "Ugly, ugly fucker." (Tiêu đề netfilter, hiện diện từ commit đầu tiên, đã sống sót qua 20 năm đánh giá code)
- "fucking gcc" (Tiêu đề B-tree của XFS, xuất hiện hai lần)
- "If you fuck with this, update ret_from_syscall code too" (Kiến trúc SPARC)
Thống kê đầy đủ từ ngữ tục tĩu trong tin nhắn commit
Các con số này chỉ tính từ tin nhắn commit, không phải mã nguồn. Sử dụng regex ranh giới từ của PostgreSQL (\y) để tránh kết quả dương tính giả ("ass" trùng với "class", "hell" trùng với "shell"):
| Từ | Số lượng | Ghi chú |
|---|---|---|
| workaround | 8,435 | Không phải tục tĩu, nhưng cho thấy nỗi đau: 8,435 lần ai đó không thể sửa được vấn đề thực sự |
| hack | 2,438 | Sự tự đánh giá trung thực của kernel |
| ugly | 2,161 | |
| stupid | 533 | |
| crap | 268 | |
| damn | 81 | |
| shit | 29 | |
| fuck | 7 |
Và trong mã nguồn, một số "viên ngọc" quý:
| Tệp | Bình luận |
|---|---|
sound/oss/forte.c | "FIXME HACK FROM HELL!" |
arch/powerpc/sysdev/todc.c | "XXXX BAD HACK -> FIX" (×4, và nó đã được sao chép sang arch/ppc/syslib/todc_time.c mà không được sửa) |
drivers/staging/dgap/ (5 tệp) | NOTE TO LINUX KERNEL HACKERS: DO NOT REFORMAT THIS CODE! |
Triple revert
Chỉ có 3 commit trong toàn bộ lịch sử Linux là triple revert (một lệnh revert của một lệnh revert của một lệnh revert).
Greg KH về Lustre (hệ thống tệp HPC): "Chúng ta có thể làm việc này bao nhiêu lần nữa đây..."
Linus về một cờ quản lý bộ nhớ: "Đây là một lệnh revert của một lệnh revert của một lệnh revert." Driver GPU i915 đã sử dụng một cờ không nên dùng, và việc gỡ rối nó mất ba chu kỳ revert.
Cả ba đều nằm trong phần quản lý bộ nhớ hoặc staging. Các phân hệ nơi những thay đổi có tác động sâu rộng, khó dự đoán.
Kent Overstreet: 13 năm, một hệ thống tệp
Commit kernel đầu tiên của Kent Overstreet là vào năm 2011: bcache, một lớp bộ nhớ đệm block. Đến năm 2013 nó đã có mặt trong mainline với 213 commit. Sau đó anh ấy im hơi lặng tiếng. 4 đến 34 commit mỗi năm từ 2014 đến 2017, viết lại toàn bộ mọi thứ bên ngoài cây kernel thành một hệ thống tệp hoàn chỉnh.
Năm 2023, bcachefs được hợp nhất vào mainline (kernel 6.7). 904 commit trong năm đó. 1.194 vào năm tiếp theo. Anh ấy viết code vào ngày đầu năm mới trong 3 năm khác nhau, từ 1 giờ sáng đến 4 giờ sáng. 27% commit của anh ấy là vào cuối tuần. Khi việc hợp nhất gây tranh cãi, anh ấy vẫn tiếp tục.
Thêm nhiều câu chuyện về kernel
Các chiến binh cuối tuần:
| Tác giả | Commit cuối tuần | Tổng số | Tỷ lệ cuối tuần % |
|---|---|---|---|
| Jonathan Cameron | 1,176 | 2,295 | 51.2% |
| Christophe JAILLET | 1,061 | 2,086 | 50.9% |
| Kent Overstreet | 1,415 | 5,217 | 27.1% |
| Hans de Goede | 1,394 | 4,627 | 30.1% |
| Linus Torvalds | 10,729 | 45,274 | 23.7% |
Jonathan Cameron và Christophe JAILLET thực hiện hơn một nửa công việc kernel của họ vào cuối tuần. Họ là những người đóng góp không chuyên, duy trì các driver trong thời gian rảnh rỗi.
Những người tận tụy với một tệp duy nhất:
Toàn bộ sự nghiệp kernel của Connor McAdams (89 commit) là một driver card âm thanh Creative Labs duy nhất (patch_ca0132.c). Lydia Wang (63 commit) dành trọn tâm huyết cho codec âm thanh VIA. Hai người riêng biệt, Pavel Rojtberg và Cameron Gutman, đã độc lập dành sự đóng góp kernel của họ chỉ cho driver bộ điều khiển Xbox (xpad.c).
Hành trình sự nghiệp:
James Bottomley (người duy trì SCSI) đã commit từ 19 tên miền email khác nhau trong 20 năm. Git log của anh ấy CHÍNH LÀ sơ yếu lý lịch của anh ấy: SteelEye → HP → Parallels → Odin → và nhiều hơn nữa. Linus có 12 tên miền. David S. Miller có 11.
Commit vào ngày Giáng sinh:
Kernel chưa bao giờ có một ngày Giáng sinh nào với số lượng commit bằng 0 trong suốt 21 năm qua. Năm 2008 ghi nhận 157 commit vào ngày 25 tháng 12 (trong đợt cao điểm hợp nhất x86). Ngay cả trong ngày Giáng sinh yên tĩnh nhất (năm 2005, với 1 commit), vẫn có ai đó đang làm việc.
Ngày bận rộn nhất:
Ngày 18 tháng 11 năm 2022: 662 commit. Một cá nhân (Uwe Kleine-König) đã thực hiện 583 trong số đó trong một đợt chuyển đổi kiểu trả về platform_driver hàng loạt. Ngày bận rộn thứ hai là 30 tháng 1 năm 2008 (640 commit): ba lập trình viên duy trì hơn 600 commit/ngày trong ba ngày liên tiếp trong quá trình hợp nhất x86.
Khoảng cách về văn hóa ghi chú commit (commit message):
Jeff Garzik trung bình viết 161 byte cho mỗi thông điệp commit. Filipe Manana (Btrfs) trung bình viết 1.950 byte. Một khoảng cách gấp 12 lần. Toàn bộ hệ thống con quản lý bộ nhớ (mm/) thường có xu hướng viết dài dòng: 3 người đóng góp hàng đầu đều nằm trong top 5 người viết thông điệp dài nhất. Khi các lỗi của bạn tinh vi và gây hậu quả nghiêm trọng, bạn buộc phải giải thích chi tiết.
Driver GPU là "thỏi nam châm" thu hút các lệnh hoàn tác (revert):
drm/amd/display (191 lượt revert) + drm/amdgpu (127) + drm/i915 (147) = 516 lượt revert liên quan đến GPU, chiếm gần 10% tổng số lượt revert trong toàn bộ kernel. Mã nguồn hiển thị (display code) có các tương tác phần cứng phức tạp, các máy trạng thái quản lý điện năng và các API userspace nhạy cảm với hồi quy (regression).
Hiệu suất truy vấn
Tất cả những nội dung trên đã được truy vấn trên một cơ sở dữ liệu có 1,4 triệu commit. Dưới đây là thời gian thực hiện:
| Truy vấn | Thời gian |
|---|---|
| Thống kê + thông tin nén | 2.1s |
| Churn (24.4 triệu file refs) | 2.3s |
| Hotspots | 1.8s |
| Coupling (tính toán bằng Go) | 48.3s |
| Authors (quét toàn bộ commit) | 34.3s |
| Hoạt động (hàng năm) | 9.4s |
| Ngày trong tuần / giờ trong ngày | 4.2-4.4s |
| Tìm kiếm toàn văn (file hiện tại) | 25s |
| Tìm kiếm toàn văn (toàn bộ lịch sử) | 44s |
Không có materialized view. Không tiền xử lý. Chỉ đơn giản là SQL trên PostgreSQL với phương pháp nén delta pg-xpatch.
Tất cả các lệnh SQL được sử dụng trong phân tích này
# Storage & compression (2.1s)
pgit stats --xpatch
# Churn (2.3s)
pgit analyze churn --limit 30
# Hotspots (1.8s)
pgit analyze hotspots --depth 1 --limit 25
# Authors (34.3s)
pgit analyze authors --limit 30 --timeout 60m
# Activity (9.4s)
pgit analyze activity --period year --limit 25 --timeout 60m
# Coupling (48.3s)
pgit analyze coupling --limit 30 --timeout 60m
# Merge hierarchy (4.6s)
pgit 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"
# Corporate contributions (5.4s)
pgit sql "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'
-- ... (full domain mapping)
END as org,
COUNT(*) as commits, COUNT(DISTINCT author_email) as authors
FROM pgit_commits GROUP BY org ORDER BY commits DESC"
# Fixes: tag evolution (4.5s)
pgit sql "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"
# Most-fixed commits (4.9s)
pgit sql "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"
# Profanity with word boundaries (~5s)
pgit sql "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"
# Source code search
pgit search "fuck" --path "*.c" --path "*.h"
pgit search "fuck" --path "*.c" --path "*.h" --all
# Triple reverts (5.7s)
pgit sql "SELECT author_name, authored_at::date, LEFT(message, 200)
FROM pgit_commits
WHERE message ILIKE 'Revert \"Revert \"Revert%%'"
# Kent Overstreet trajectory (4.1s)
pgit sql "SELECT EXTRACT(YEAR FROM authored_at)::int as year, COUNT(*)
FROM pgit_commits WHERE author_name = 'Kent Overstreet'
GROUP BY year ORDER BY year"
# Weekend warriors (1m 41s)
pgit sql "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"
Liên kết
pgit có thể xử lý Linux kernel. Đó là câu hỏi mà tôi muốn trả lời. Nó đã nhập, nén và giúp cho 20 năm lịch sử có thể truy vấn được trong vài giây.
Kể từ bài đăng về pgit, ripgit đã được xây dựng dựa trên xpatch: một git remote tự host được hỗ trợ bởi Cloudflare Durable Objects với bộ lưu trữ SQLite và nén delta. Thật tuyệt vời khi thấy hệ sinh thái đang phát triển.
go install github.com/imgajeed76/pgit/v4/cmd/pgit@latest
- pgit: github.com/ImGajeed76/pgit
- pg-xpatch: github.com/ImGajeed76/pg-xpatch
- xpatch: github.com/ImGajeed76/xpatch
Tác giả: ImGajeed76