Đồng bộ MySQL CDC sang BigQuery: Vì sao sync định kỳ bỏ sót dữ liệu và cách binlog khắc phục
Bài viết phân tích những hạn chế của phương pháp đồng bộ dữ liệu định kỳ (periodic sync) từ MySQL sang BigQuery, như bỏ sót các thao tác xóa hoặc cập nhật trung gian. Đồng thời, bài viết giới thiệu chi tiết cách hoạt động của Change Data Capture (CDC) dựa trên binlog, các yêu cầu cấu hình cần thiết ở phía MySQL và quy trình đưa dữ liệu vào BigQuery một cách đáng tin cậy.

Đồng bộ MySQL CDC sang BigQuery: Vì sao sync định kỳ bỏ sót dữ liệu và cách binlog khắc phục
Hầu hết các pipeline đưa dữ liệu từ MySQL lên kho dữ liệu (data warehouse) đều chạy theo cùng một mô hình: một tác vụ được lên lịch định kỳ chọn dữ liệu, so sánh với trạng thái trước đó rồi ghi lại phần thay đổi. Cách này hoạt động ổn... cho đến khi nó không còn ổn nữa. Sự thật là phương pháp đồng bộ định kỳ có những lỗ hổng nghiêm trọng mà ít ai nhận ra, đặc biệt khi dữ liệu thay đổi liên tục với tần suất cao.
Sơ đồ CDC từ MySQL sang BigQuery
Những gì sync định kỳ bỏ sót
Phương pháp SELECT-based sync chỉ nhìn thấy dữ liệu tại thời điểm hiện tại. Nó không có cách nào để biết rằng một dòng dữ liệu đã tồn tại và bị xóa giữa hai lần chạy. Nó cũng không thể nhìn thấy trạng thái trung gian của một dòng khi dòng đó thay đổi nhiều lần trong khoảng thời gian đó. Chưa kể, mỗi lần quét toàn bộ bảng lớn chỉ để tìm vài dòng thay đổi sẽ tạo ra áp lực tải rất lớn lên database production của bạn.
Đây là một bài toán kinh điển mà bất kỳ ai làm data engineering tại Việt Nam — từ startup nhỏ đến doanh nghiệp lớn — đều từng gặp phải khi phát triển hệ thống báo cáo hoặc kho dữ liệu nội bộ.
CDC làm điều gì khác biệt
Change Data Capture (CDC) đọc trực tiếp từ binary log (binlog) của MySQL — cơ chế mà chính MySQL dùng để replication nội bộ. Mọi thao tác INSERT, UPDATE, và DELETE đều được ghi lại ngay khi chúng được thực thi, theo đúng thứ tự, kèm theo trạng thái đầy đủ của dòng dữ liệu. Không có gì bị suy luận bằng cách so sánh. Không có gì phụ thuộc vào thời điểm tác vụ batch chạy.
Điều quan trọng cần nhấn mạnh: vấn đề ở đây không phải là tốc độ. Một pipeline CDC chạy mỗi giờ vẫn đáng tin cậy hơn về bản chất so với một batch sync chạy mỗi phút — vì nó ghi nhận mọi thứ đã xảy ra, chứ không chỉ chụp lại trạng thái mới nhất.
Điều kiện bắt buộc ở phía MySQL
CDC qua binlog có những yêu cầu thực tế nghiêm ngặt:
-
Binary logging ở định dạng ROW với full row images. Nếu
binlog_row_imagekhông được đặt thànhFULL, các sự kiệnDELETEvàUPDATEsẽ không mang theo trạng thái đầy đủ trước/sau khi thay đổi — chỉ có phần tối thiểu cần thiết. Điều này thường không đủ cho một consumer phía sau cần toàn bộ dòng dữ liệu. -
binlog_row_value_optionskhông được đặt làPARTIAL_JSON. Nếu vi phạm, các cập nhật trên cột JSON chỉ ghi lại phần thay đổi bên trong giá trị JSON, không ghi lại toàn bộ giá trị. Lỗi này rất khó phát hiện, chỉ lộ ra khi bạn so sánh với dữ liệu nguồn. -
User replication cần quyền
REPLICATION SLAVEvàREPLICATION CLIENTđể đọc và theo dõi binlog, cộng thêmSELECT,RELOAD, vàSHOW DATABASEScho snapshot ban đầu. -
server-idduy nhất cho mỗi replication client kết nối vào database, bao gồm cả kết nối CDC. Xung đột với các replica hiện có sẽ gây lỗi âm thầm, cực kỳ khó debug. -
Thời gian lưu giữ binlog đủ dài để bao phủ thời gian gián đoạn. MySQL mặc định xóa binlog sau 30 ngày. Nếu kết nối CDC ngoại tuyến lâu hơn thời gian đó, nó sẽ không thể tiếp tục từ vị trí dừng lại — mà phải chạy lại snapshot ban đầu từ đầu.
Các bước thiết lập
GRANT SELECT, RELOAD, SHOW DATABASES, REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'your_user';
FLUSH PRIVILEGES;
Sau đó kiểm tra cấu hình binlog hiện tại:
SHOW VARIABLES LIKE 'log_bin';
SHOW VARIABLES LIKE 'binlog_format';
SHOW VARIABLES LIKE 'binlog_row_image';
Nếu các biến này chưa được đặt đúng, bạn cần chỉnh sửa trong file my.cnf và khởi động lại MySQL để áp dụng. Tài liệu đầy đủ về connector, bao gồm mọi yêu cầu và các bước xử lý sự cố, có tại docs.erathos.com/connectors/databases/mysql#cdc-setup.
Đây là lúc một nền tảng quản lý được phát huy giá trị. Các công cụ như Erathos xử lý việc chọn chế độ snapshot (snapshot ban đầu đầy đủ hoặc chỉ binlog), gán server-id và tránh xung đột, cũng như logic phục hồi khi binlog bị purge trước khi kết nối bắt kịp. Nhờ đó, người vận hành pipeline không phải tự tay xây dựng lại logic này mỗi lần kết nối một nguồn dữ liệu mới.
Đưa dữ liệu vào BigQuery
Khi CDC đã ghi nhận thay đổi chính xác, phần đích đến trở nên tương đối đơn giản: mỗi sự kiện thay đổi ánh xạ thành một thao tác hàng (row operation) trong bảng BigQuery. Điều đáng làm đúng không phải là khâu nạp dữ liệu vào BigQuery, mà là đảm bảo dữ liệu đến đó phải đầy đủ và chính xác. Một pipeline nạp dữ liệu không đầy đủ đúng giờ còn tệ hơn một pipeline thỉnh thoảng chậm vài phút nhưng không bao giờ sai.
Nếu đội ngũ của bạn vẫn đang chạy batch sync toàn bảng (full-table sync) với MySQL production, câu hỏi đáng đặt ra không phải là "làm sao để nhanh hơn" mà là "chúng ta hiện tại đang không nhìn thấy những gì." Với sự phát triển của các hệ thống dữ liệu tại Việt Nam, việc áp dụng CDC không còn là lựa chọn xa xỉ mà đang dần trở thành tiêu chuẩn cho các pipeline dữ liệu tin cậy.
Nếu muốn thử nghiệm thực tế, bạn có thể tạo tài khoản Erathos và kết nối nguồn MySQL với CDC được bật chỉ trong vài phút.