BP-01 // TỐI ƯU NHÂN ENGINE

Bộ PRAGMA Chuẩn Production Cho SQLite WAL: Xóa Sổ Lỗi SQLITE_BUSY Ở 20.000+ RPS

Tại sao cấu hình mặc định của SQLite nghẽn cổ chai ngay ngưỡng 80 request đồng thời — và 8 dòng lệnh PRAGMA + mô hình tách Pool Đọc/Ghi giúp cán mốc 20k+ RPS trên ổ NVMe.

MỤC TIÊU THÔNG LƯỢNG MÔ HÌNH
21,400 TPS
ĐẶC TÍNH ĐỌC / RPO
0.18 ms
PHÂN KHÚC MÁY CHỦ THAM CHIẾU
$24–$48 HF NVMe

Mặc định khi khởi tạo, SQLite chạy chế độ rollback DELETE cổ điển, synchronous=FULL, bộ đệm vỏn vẹn 2 MiB và busy_timeout = 0ms. Khi kích hoạt chế độ Write-Ahead Logging (WAL), khống chế kích thước tệp -wal, ánh xạ bộ nhớ zero-copy mmap_size và tách bạch Pool Ghi (1 kết nối) với Pool Đọc, một VPS NVMe đơn lẻ lập tức đạt tốc độ phản hồi dưới 1 mili-giây.

Trong bản vẽ lưu trữ BP-01 trên SQLiteEdge, mọi tham số dưới đây bám sát tài liệu SQLite 3.46 và biểu phí nhà cung cấp đối chiếu ngày 2026-11-12.

Nguyên Tắc Thiết Kế SQLiteEdge Cho Bộ PRAGMA Chuẩn Production Cho SQLite WAL: Xóa Sổ Lỗi SQLITE_BUSY Ở 20.000+ RPS

  1. Bật PRAGMA journal_mode = WAL ngay khi tạo DB để các luồng đọc SELECT không bao giờ chặn luồng ghi duy nhất và chạy song song trên toàn bộ nhân vCPU.
  2. Kết hợp PRAGMA synchronous = NORMAL với chế độ WAL: giao dịch được nối đuôi vào tệp -wal mà không ép ổ cứng dừng chờ lệnh đồng bộ vật lý mỗi dòng, tăng gấp 10 lần TPS ghi mà vẫn bảo toàn tính toàn vẹn khi ứng dụng sập.
  3. Đặt PRAGMA busy_timeout = 5000 đồng thời tách 2 nhóm kết nối: đúng 1 kết nối ghi dùng BEGIN IMMEDIATE và N = vCPU*4 kết nối chỉ đọc (read-only).
  4. Khống chế tệp -wal phình to khi tải ghi dồn dập bằng PRAGMA journal_size_limit = 67108864 (64 MiB) kết hợp checkpoint định kỳ.

Mẫu Cấu Hình SQLiteEdge: Cấu Hình Khởi Tạo Kết Nối SQLite Production (SQLite 3.46+)

Cấu Hình Khởi Tạo Kết Nối SQLite Production (SQLite 3.46+)
-- Chạy 1 lần khi khởi tạo tệp cơ sở dữ liệu
PRAGMA journal_mode = WAL;
PRAGMA auto_vacuum = INCREMENTAL;

-- Chạy trên MỌI kết nối mới khi mở Pool
PRAGMA synchronous = NORMAL;
PRAGMA busy_timeout = 5000;
PRAGMA cache_size = -2097152;         -- Bộ đệm trang 2 GiB (số âm = đơn vị KiB)
PRAGMA mmap_size = 8589934592;        -- Ánh xạ 8 GiB zero-copy qua bộ nhớ ảo OS
PRAGMA journal_size_limit = 67108864; -- Giới hạn tệp -wal ở 64 MiB sau checkpoint
PRAGMA temp_store = MEMORY;           -- Xử lý bảng tạm/ORDER BY hoàn toàn trên RAM
PRAGMA foreign_keys = ON;

-- Luôn mở giao dịch ghi bằng IMMEDIATE để xếp hàng sạch sẽ theo busy_timeout
BEGIN IMMEDIATE TRANSACTION;

Bảng Mô Hình Thông Số & Chi Phí SQLiteEdge (BP-01)

Các mức giá tham khảo cập nhật ngày 2026-11-12 từ trang công khai của hãng (giá có thể thay đổi khi thanh toán); thông số thông lượng là ước tính mô hình lý thuyết, hãy tự xác thực bằng fio trên máy chủ của bạn.

Cấu Hình Thử NghiệmTPS Ghi Đơn LuồngQPS Đọc Song SongTỷ Lệ Lỗi SQLITE_BUSY
Mặc định SQLite (DELETE + FULL + 0ms)390 TPS1,900 QPS18.4% khi dồn tải
WAL + NORMAL trên ổ mạng Cloud EBS gp31,380 TPS19,500 QPS2.1% ở đỉnh p99
WAL + NORMAL + mmap trên Hostinger EPYC NVMe11,600 TPS64,000 QPS0.00%
WAL + NORMAL + BEGIN IMMEDIATE trên Vultr 3.7GHz HF NVMe21,400 TPS112,000 QPS0.00%

Cấu Hình Máy Chủ NVMe & Kho S3 Khớp Bản Vẽ BP-01 Trên SQLiteEdge

  • Vultr High Frequency 3.5GHz+ Ổ NVMe Cục Bộ (Độ Trễ fsync Cực Thấp)
    Xung đơn nhân 3.7GHz+ & NVMe trực tiếp • fsync ~0.045ms đẩy kịch trần TPS ghi đơn luồng SQLite WAL (https://www.vultr.com/pricing/)
    Xem Gói Vultr Cho BP-01 Trên SQLiteEdge →
  • InterServer Storage $6 Khóa Giá Trọn Đời (Đích Lưu Trữ S3 / MinIO Cho Litestream)
    Chỉ $6/tháng khóa giá trọn đời cho 1TB • $0 phí lệnh PUT S3 khi stream WAL mỗi giây bằng Litestream (https://www.interserver.net/vps/)
    Xem Kho S3 InterServer Cho BP-01 Trên SQLiteEdge →

Mở kịch bản BP-01 này trong Trình Sinh PRAGMA SQLiteEdge →

Câu Hỏi Kỹ Thuật SQLiteEdge Cho Bản Vẽ BP-01

  • PRAGMA synchronous = NORMAL trong chế độ WAL có làm hỏng dữ liệu khi crash không?

    Trong chế độ WAL, synchronous = NORMAL an toàn 100% trước mọi sự cố sập tiến trình ứng dụng (OOM, panic, restart). Chỉ khi mất điện đột ngột toàn bộ máy chủ vật lý trước khi nhân Linux kịp đẩy trang bẩn xuống NVMe (~1–5 giây) mới có thể lùi lại vài giao dịch cuối nhưng tệp DB không bao giờ bị hỏng (corrupt).

  • Vì sao phải dùng BEGIN IMMEDIATE thay vì BEGIN thường dù đã đặt busy_timeout?

    Nếu mở giao dịch bằng BEGIN thường (deferred), đọc dữ liệu trước rồi mới nâng cấp lên lệnh INSERT/UPDATE khi đang có luồng khác giữ khóa ghi, SQLite sẽ trả lỗi SQLITE_BUSY ngay lập tức mà bỏ qua busy_timeout để chống deadlock. BEGIN IMMEDIATE xin khóa ghi ngay từ đầu nên luôn xếp hàng tuần tự êm ái.