Turso , một dự án đầy tham vọng nhằm viết lại SQLite từ đầu bằng ngôn ngữ Rust , gần đây đã gặp phải một vấn đề hỏng dữ liệu khó hiểu khiến cộng đồng lập trình viên tranh cãi gay gắt. Lỗi này xuất hiện mỗi khi cơ sở dữ liệu vượt qua mốc 1GB, dẫn đến việc kiểm tra tính toàn vẹn trong SQLite gốc bị thất bại. Điều tưởng như là một lỗi nghiêm trọng trong phiên bản viết lại của họ hóa ra lại là một tính năng được ghi chép của SQLite mà nhóm đã bỏ qua.
Tổng quan dự án Turso:
- Ngôn ngữ: Viết lại SQLite bằng Rust
- Trạng thái: Hiện đang trong giai đoạn alpha
- Tính năng mới: CDC, ghi đồng thời, mã hóa
- Kiểm thử: Sử dụng Deterministic Simulation Testing (DST)
- Mô hình kinh doanh: Mã nguồn mở với dịch vụ cloud thương mại
Bí ẩn của lỗi hỏng dữ liệu ở mốc 1GB
Vấn đề đầu tiên xuất hiện khi các kỹ sư Turso phát hiện ra rằng bất kỳ cơ sở dữ liệu nào vượt qua 1GB sẽ kích hoạt cảnh báo hỏng dữ liệu trong các kiểm tra tính toàn vẹn của SQLite . Thời điểm này rất chính xác - không phải xung quanh 1GB, mà chính xác tại ngưỡng 1GB. Dù dữ liệu đến từ một blob lớn duy nhất hay hàng nghìn lần chèn nhỏ cũng không quan trọng. Tính nhất quán này khiến lỗi vừa có thể dự đoán được vừa khó hiểu.
Phương pháp kiểm thử tinh vi của nhóm, dựa chủ yếu vào Deterministic Simulation Testing, đã hoàn toàn bỏ sót vấn đề này. Các bài kiểm thử fault injection của họ, được thiết kế để mô phỏng các lỗi thực tế, đã ngăn cơ sở dữ liệu phát triển đủ lớn để đạt đến mốc 1GB. Chỉ khi họ thêm các lần chạy kiểm thử không có lỗi mô phỏng thì mô hình này mới xuất hiện rõ ràng.
Cộng đồng chỉ trích về việc nghiên cứu cơ bản
Phản ứng của cộng đồng lập trình viên diễn ra nhanh chóng và gay gắt. Nhiều người đặt câu hỏi làm thế nào một nhóm tuyên bố xây dựng một hệ thống tương thích lại có thể bỏ sót một khía cạnh cơ bản như vậy trong kiến trúc của SQLite . Những lời chỉ trích tập trung vào điều mà nhiều người coi là thất bại trong việc thực hiện nghiên cứu cơ bản trước khi cố gắng viết lại một cách đầy tham vọng như vậy.
Làm sao các bạn có thể viết một bản sao của SQLite mà không đọc mô tả về định dạng tệp của nó?
Trang lock-byte tại mốc 1GB không phải là kiến thức ẩn - nó được ghi chép rõ ràng trong tài liệu định dạng tệp chính thức của SQLite và đã tồn tại hơn một thập kỷ. Tính năng này tồn tại để xử lý các cơ chế khóa tệp, nhưng việc triển khai của Turso không tính đến điều này, dẫn đến các vấn đề tương thích.
![]() |
---|
Một cuộc trò chuyện kỹ thuật số giữa các nhà phát triển thảo luận về các vấn đề liên quan đến gỡ lỗi cơ sở dữ liệu và kiểm tra tính toàn vẹn |
Vấn đề thực sự đằng sau lỗi
Nguyên nhân gốc rễ thực sự không phải là hỏng dữ liệu trong cơ sở dữ liệu của Turso . Các kiểm tra tính toàn vẹn của chính họ cho thấy cơ sở dữ liệu hoàn toàn ổn. Vấn đề là SQLite mong đợi một pending byte cụ thể tại mốc 1GB cho cơ chế khóa của nó. Không có tính năng này được triển khai đúng cách, SQLite diễn giải các cơ sở dữ liệu là bị hỏng, mặc dù bản thân dữ liệu vẫn còn nguyên vẹn.
Khám phá này làm nổi bật một mối quan tâm rộng lớn hơn trong cộng đồng về những thách thức trong việc tạo ra các hệ thống thực sự tương thích. Khi phần mềm gốc có nhiều thập kỷ tích lũy các hành vi và trường hợp đặc biệt, ngay cả những tính năng được ghi chép đầy đủ cũng có thể dễ dàng bị bỏ qua trong quá trình triển khai lại.
Chi tiết trang Lock-Byte của SQLite:
- Vị trí: Chính xác tại mốc 1GB trong tệp cơ sở dữ liệu
- Mục đích: Cơ chế khóa tệp cho việc truy cập đồng thời
- Tài liệu: Có sẵn trong đặc tả định dạng tệp chính thức của SQLite
- Tác động: Bắt buộc để tương thích với SQLite, gây ra lỗi kiểm tra tính toàn vẹn nếu bị thiếu
Bài học cho tính tương thích cơ sở dữ liệu
Sự cố này đặt ra những câu hỏi quan trọng về cách tiếp cận viết lại các hệ thống đã được thiết lập. Trong khi các mục tiêu của Turso về việc thêm các tính năng như CDC (Change Data Capture), ghi đồng thời và mã hóa là có giá trị, cuộc tranh luận trong cộng đồng cho thấy rằng việc xem xét tài liệu kỹ lưỡng nên được thực hiện trước các nỗ lực triển khai.
Bản sửa lỗi tự nó khá đơn giản khi vấn đề được xác định - triển khai cơ chế trang lock-byte mà SQLite mong đợi. Tuy nhiên, quá trình khám phá đã phơi bày những khoảng trống trong phương pháp kiểm thử và thực hành nghiên cứu có thể ảnh hưởng đến các khía cạnh tương thích khác của dự án.
Ghi chú: CDC (Change Data Capture) là một kỹ thuật để theo dõi các thay đổi trong cơ sở dữ liệu để các ứng dụng có thể phản hồi với những thay đổi đó trong thời gian thực.
Tham khảo: An adventure in writing compatible systems