Jepsen: MySQL 8.0.34
Bài tóm tắt Jepsen 2023 3. Quy mô lớn Độ khó: Khó
Jepsen · 2023 · 3. Quy mô lớn · Độ khó: Khó — bài gốc
Báo cáo kiểm thử độc lập, không phải bài của một công ty kể về hệ của mình. Jepsen tự nói: phương pháp thực nghiệm chứng minh được có bug, không chứng minh được không có bug. Báo cáo cùng loạt: Jepsen 2020.
Bối cảnh
- Định nghĩa isolation của ANSI SQL-92 dựa trên ba hiện tượng P1 (dirty read), P2 (non-repeatable read), P3 (phantom). Từ 1995 (Berenson và cộng sự) đã biết chúng mơ hồ và thiếu: không có P0 (dirty write), P3 không nói tới update/delete, chặn cả ba vẫn không ra serializable. Bảy lần sửa chuẩn sau đó không đổi.
- Tài liệu MySQL nói InnoDB có đủ bốn mức của SQL:1992, và ở Repeatable Read (mức mặc định) "mọi consistent read trong giao dịch đọc snapshot lập bởi lần đọc đầu". Một ghi chú sâu hơn lại nói snapshot áp cho
SELECT, "không nhất thiết cho câu lệnh DML", và thay đổi của giao dịch khác "trở nên thấy được" khi giao dịch hiện tại update chúng. - Jepsen test MySQL 8.0.34 InnoDB một node và cụm có replica chỉ đọc qua binlog, cùng AWS RDS MySQL cấu hình production mặc định; workload list-append (Elle kiểm chu trình phụ thuộc), non-repeatable read, monotonic atomic view; lỗi giả lập: pause, crash, partition, mất dữ liệu chưa fsync (LazyFS).
Thay đổi chính (kết quả)
- Repeatable Read cho phép G2-item (write skew) ngay trên một node khoẻ: 214 chu trình trong 40 giây; Kleppmann (Hermitage) đã báo từ 2014.
- G-single (read skew): một giao dịch vừa không thấy vừa ghi đè giao dịch khác; khoảng 140 giao dịch/giây ra 244 trường hợp trong 60 giây.
- Lost update: hai giao dịch đọc cùng một version rồi cùng ghi, cả hai commit. Checker mới tìm được 198 trường hợp trong 9.048 giao dịch, chỉ 47 nằm trong chu trình mà Elle cũ thấy. Hệ quả theo Jepsen: mẫu ORM "mở giao dịch, đọc object, sửa, ghi lại, commit" có thể âm thầm mất thay đổi đã commit dưới Repeatable Read của MySQL.
- Đọc không lặp lại được ở Repeatable Read: 126/9.048 giao dịch lỗi nhất quán nội bộ: đọc thấy rỗng, append, đọc lại thấy thêm ba phần tử của giao dịch khác; một giao dịch đọc tên người, sửa giới tính, đọc lại thấy tên đã đổi. Theo Jepsen, một lần ghi là lời mời cho giao dịch khác chen vào, trái cả tài liệu của MySQL. Dòng mới chèn có thể hiện ra giữa giao dịch; chưa thấy dòng bị xoá biến mất.
- Không monotonic atomic view: đọc thấy ghi thứ hai của một giao dịch mà không thấy ghi thứ nhất; theo Jepsen khó gọi là snapshot.
- RDS "Serializable" vi phạm serializability trên cụm khoẻ: dạng "fractured read bắc cầu" (T3 thấy T2, T2 thấy T1, T3 không thấy T1) khi đọc từ replica. Jepsen nghi do RDS mặc định
replica_preserve_commit_order=OFF(MySQL từ 8.0.27 mặc định ON); bật OFF ở cụm local cũng tái hiện. - Tin tốt: Read Uncommitted, Read Committed và Serializable của MySQL (không phải RDS) thoả PL-1, PL-2, PL-3 qua pause, crash, partition.
innodb_flush_log_at_trx_commit=1(mặc định) không mất giao dịch đã commit khi mất dữ liệu chưa fsync; đặt0thì mất. - Theo Jepsen, Repeatable Read của MySQL không phải Snapshot Isolation (trái nhận định phổ biến, kể cả trong sách Designing Data-Intensive Applications), không phải PL-2.99 Repeatable Read; nó mạnh hơn Read Committed nhưng không so được với nhiều mô hình khác. Sách và bài viết về MySQL thường mô tả sai mức này. Binlog replication tỏ ra mong manh: vài phút test làm replication của RDS dừng hẳn (
CREATE DATABASEkhông xuất hiện trên secondary sau một giờ).
Vì sao
- Chuẩn không định nghĩa chặt nên mỗi hệ gọi tên mức isolation theo cách riêng; người dùng tin vào tên.
Bài học cho SWE
- Khuyến nghị của Jepsen: cần Repeatable Read thật thì dùng Serializable của MySQL, hoặc ở Read Committed thì khoá tường minh bằng
SELECT ... FOR UPDATE. Trên RDS cần serializable thì bậtreplica_preserve_commit_order. - Đừng suy ngữ nghĩa từ tên mức isolation; mức mặc định của MySQL và PostgreSQL cùng tên "Repeatable Read" nhưng khác nhau (Jepsen 2020).
- Read-modify-write trong giao dịch không tự an toàn; phải biết mức isolation thực tế chặn lost update hay không.
- Tham số mặc định của dịch vụ managed có thể khác mặc định của bản upstream và đổi ngữ nghĩa.
Liên quan
- Giao dịch phân tán và nhất quán xuyên service · Kiểm thử độ tin cậy (chaos, fault injection, mô phỏng tất định) · Failover, replica và dự phòng dữ liệu
- Nâng cấp MySQL 5.7 → 8.0 lộ giả định ngầm của ứng dụng: Airbnb 2026
Giao dịch phân tán và nhất quán xuyên serviceKiểm thử độ tin cậy (chaos, fault injection, mô phỏng tất định)Failover, replica và dự phòng dữ liệu
#Jepsen#Elle#MySQL InnoDB#isolation level#Repeatable Read#ANSI SQL#Adya PL-2.99#G2-item#G-single#lost update#read skew#write skew#internal consistency#monotonic atomic view
Được nhắc tới trong
Chủ đề (3)
Công ty (1)
Bài tóm tắt (1)