Skip to content

8. Bên trong InnoDB ​

Buffer pool, redo log, undo log, binlog và doublewrite phối hợp thế nào để commit vừa nhanh vừa không mất dữ liệu khi máy sập.

Đường đi của một UPDATE ​

Chạy UPDATE accounts SET balance = 40 WHERE id = 1; COMMIT; từng bước. Khung bên dưới cho biết nếu máy sập ngay lúc đó thì sau khi khởi động lại dữ liệu ra sao.

RAMDISKbuffer poolClientUPDATE, COMMITdata pageid=1undobản cũlog bufferredo recordbinlog cachecủa sessiondoublewrite#ib_*.dblwraccounts.ibdpage 16KBredo log#innodb_redobinlogbinlog.000042
Bấm “Bước tiếp” để chạy từng bước.

Các thành phần ​

  • Buffer pool. Cache page 16KB trong RAM, thường 50–75% RAM của máy chỉ chạy DB. Danh sách LRU chia vùng young/old để một lần quét bảng không đẩy hết dữ liệu nóng (chương 1). MySQL 8 không còn query cache; cache kết quả đặt ở tầng app (Cache).
  • Redo log (WAL). Commit không cần ghi page 16KB xuống .ibd (ghi ngẫu nhiên, chậm), chỉ cần ghi tuần tự bản ghi redo nhỏ. Page được flush dần về sau; checkpoint đánh dấu tới đâu redo không còn cần.
  • Undo log. Lưu bản cũ để rollback và để MVCC đọc version cũ. Purge thread dọn undo khi không còn read view nào cần.
  • Doublewrite buffer. Page InnoDB 16KB, page của OS/disk thường 4KB. Sập giữa chừng có thể chỉ ghi được một phần page. Redo không sửa được page hỏng, nên InnoDB ghi page vào vùng doublewrite trước để luôn có một bản nguyên vẹn.
  • Redo log và binlog. Redo: của InnoDB, mô tả thay đổi trên page, dùng để khôi phục khi crash, ghi vòng tròn. Binlog: của tầng server, ghi sự kiện logic, dùng cho replication, CDC và point-in-time recovery, ghi nối tiếp. Hai log khớp nhau nhờ 2PC nội bộ (bước 5–7 ở trên).
  • Change buffer. Thay đổi trên secondary index không unique mà page chưa có trong buffer pool được ghi tạm, gộp lại sau. Index UNIQUE không dùng được vì phải đọc page để kiểm tra trùng.

Độ bền: các tham số flush ​

Thử: máy sập thì mất bao nhiêu?
Sự cố
Redo (dữ liệu InnoDB)
Không mất
Binlog (replica, PITR)
Không mất
An toàn: commit đã báo OK thì còn, binlog khớp dữ liệu. Cấu hình bắt buộc cho dữ liệu tiền.

Cặp innodb_flush_log_at_trx_commit = 1 và sync_binlog = 1 là chuẩn cho dữ liệu quan trọng. Đổi sang 2 hoặc 0 tăng throughput ghi đáng kể, đổi lại chấp nhận mất khoảng một giây giao dịch khi sập máy.

Ghi nhớ

  1. Commit = ghi tuần tự redo (và binlog), không ghi page dữ liệu.
  2. Redo và binlog khớp nhau nhờ 2PC: PREPARED mà chưa có trong binlog thì rollback, đã có thì commit.
  3. Doublewrite chống page ghi dở; undo phục vụ rollback và MVCC.
  4. innodb_flush_log_at_trx_commit=1 và sync_binlog=1 cho dữ liệu không được mất.