Lessons from Deploying MySQL GTID at Scale

Bài tóm tắt Meta 2014 3. Quy mô lớn Độ khó: Nâng cao

Meta · 2014 · 3. Quy mô lớn · Độ khó: Nâng cao — bài gốc

Bối cảnh

  • Replication MySQL truyền thống dựa trên toạ độ tương đối (tên file binlog + vị trí). GTID (MySQL 5.6) gán cho mỗi transaction một ID duy nhất, nên replica tự biết mình đã chạy tới đâu (auto-positioning).
  • Lợi ích: failover đơn giản và ít lỗi người hơn (không phải chỉ định vị trí; server tự bỏ qua transaction đã chạy); topology replication phân cấp; backup/khôi phục binlog dễ hơn; là điều kiện cho replication đa luồng an toàn khi crash.
  • Facebook bật GTID trên mọi instance MySQL production trong vài tháng (2014).

Thay đổi chính

  • Kế hoạch triển khai chính thức không dùng được: gtid_mode không đổi được lúc đang chạy và phải giống nhau giữa primary và replica, nên tài liệu bảo đặt primary read-only rồi tắt cả replica set cùng lúc, trái với yêu cầu sẵn sàng cao.

  • Họ sửa MySQL (fb-mysql): cho phép replica có GTID bật nhận dữ liệu từ primary có GTID tắt, và không gán GTID trên server read-only. Quy trình cho từng replica set:

    1. restart lần lượt từng replica để bật GTID;
    2. promote một replica lên primary như bình thường (primary cũ cố ý bị ngắt replication);
    3. restart primary cũ để bật GTID, cho nó replicate từ primary mới.

    Có đủ kiểm tra an toàn nên lúc cao điểm chạy script trên hàng trăm replica set cùng lúc.

  • Sửa bug và vấn đề hiệu năng của MySQL:

    • quét toàn bộ binlog khi replica kết nối hoặc khi khôi phục sau crash: sửa bằng cách lưu previous_gtid_event trong file index;
    • replica có GTID không an toàn khi crash với cấu hình bền vững thấp: thêm bảng transaction lưu GTID;
    • cho phép replication đa luồng cùng relay_log_recovery=1.

    Họ báo lên upstream 12 bug (danh sách trong bài).

  • Chuẩn bị: cập nhật mọi automation (đặc biệt logic promote) để dùng GTID + auto-positioning; thêm bộ đếm cho các câu lệnh không tương thích GTID, tìm ra ~20 trường hợp trong hàng nghìn workload và sửa trước; viết script trợ giúp bỏ qua một câu lệnh (cách cũ không dùng được với GTID).

  • Kết hợp GTID + semi-sync: primary crash thì promote replica trong 30 giây, không mất dữ liệu; primary cũ nếu còn nhất quán thì trỏ lại vào primary mới, không phải chép lại từ đầu.

Vì sao

Theo Facebook: failover và khôi phục nhanh, an toàn, tự động hoá được ở quy mô lớn. Công sức bỏ ra là xứng đáng.

Bài học cho SWE

  • Tính năng tốt nhưng kế hoạch triển khai chính thức có thể không dùng được ở quy mô lớn; đôi khi phải sửa phần mềm để có lộ trình nâng cấp không downtime.
  • Nâng cấp từng replica rồi promote là mẫu chung: Uber nêu đây là ưu điểm của MySQL (Uber 2016); GitHub dùng GTID trong cutover (GitHub 2021).
  • Kiểm kê trước những query không tương thích bằng bộ đếm trên production, thay vì đoán.

Liên quan