Operational data lives in MySQL. Analysis happens in BigQuery. Data Sync moves rows from one to the other on a schedule, without a custom pipeline.
No credit card. 14 days. Cancel in one click.
Quick answer: Open Pipelines, Build, and New Sync. Pick MySQL as the source connection and table, BigQuery as the target, and drag fields across, or use AI Map. Choose Insert, Update or Upsert, run a Dry Run to preview, then save it as a scheduled job. Pipelines tier.
Keeping a BigQuery orders table current from a MySQL source that gets updated in place as order status changes:
SELECT order_id, customer_id, status, updated_at FROM shop.orders WHERE updated_at >= NOW() - INTERVAL 1 DAY;
Target my-gcp-project.warehouse.orders, MODE Upsert, MATCH ON order_id. QueryFlow handles the MERGE into BigQuery on that key, so an order that changed status yesterday updates the existing row in BigQuery instead of adding a duplicate. Save it as a job running every hour to keep the warehouse table current without a full reload each time.
MySQL commonly represents a boolean as TINYINT(1), a plain integer that happens to only ever hold 0 or 1, while BigQuery has a real BOOL type. If a field like is_active lands in BigQuery as an integer instead of true/false, check how the target column is typed and adjust the mapping, this is a MySQL-to-BigQuery quirk specifically, not a Data Sync bug.
Run Dry Run first and read the preview before anything writes. After a real run, check the job's history: a clean run shows rows synced with no errors; a partial one lists which rows failed, usually a type mismatch.
| If you see | Fix |
|---|---|
| Choose at least one key field | Pick a MATCH ON column for Update or Upsert. |
| Duplicate key values in source | Pick MATCH ON columns that uniquely identify rows in MySQL. |
| Records synced, with errors listed | Usually a type mismatch, often the TINYINT(1)-as-boolean case above. Read the listed error for the exact field. |
Not every MySQL table gets edited in place. An append-only events or audit-log table never changes an existing row, so Insert is the right MODE, not Upsert, there's no key to match on because nothing needs updating:
SELECT event_id, user_id, event_type, created_at FROM shop.audit_log WHERE created_at >= NOW() - INTERVAL 1 HOUR;
Run that hourly with MODE Insert into a matching BigQuery table. Since the source query already filters to the last hour, re-running it on schedule naturally appends only new rows, without needing a MATCH ON column at all.
Data Sync maps the fields you tell it to map; it won't add a new MySQL column to the BigQuery target automatically. If the source table gains a column you want mirrored, add it to the BigQuery table first and update the mapping.
MySQL-to-BigQuery syncs are a common case for Upsert specifically: operational rows change in place in MySQL (a status field, an updated timestamp), and Insert alone would just accumulate duplicates in BigQuery on every run. Match on the primary key you already trust in MySQL and let the MERGE handle the rest.
An hourly sync fits an operational table like orders, where a report needs status changes reflected within an hour. A slower-moving reference table, a product catalog that changes a few times a week, doesn't need hourly runs; a nightly sync is plenty and avoids running a MERGE against BigQuery for a table that never actually changed since the last check.
Data Sync and a scheduled job's BigQuery destination solve different problems and can run side by side on the same source: use Data Sync for a mapped table that needs Update or Upsert logic, and a job's BigQuery destination (Append or Replace) for a simpler case where you're just appending a query's output or replacing a table wholesale. Both use the same underlying MySQL and BigQuery connections, so there's no double setup.
See also: Integrations Load a CSV into BigQuery on Mac Sync Databricks to BigQuery.
Either. Run it manually from Build, or save it as a job with its own schedule under Pipelines.
It uses a MERGE on the key column you set as MATCH ON, inserting new rows and updating existing ones in a single operation, the same approach BigQuery and Databricks both use as Data Sync targets.
MySQL often stores a boolean as TINYINT(1), a 0 or 1 integer under the hood, while BigQuery has a real BOOL type. Check the mapped column's type on both sides if a true/false field looks numeric on the BigQuery side.
Pipelines. Studio covers querying and the explorer; Data Sync, scheduling and Watch This are Pipelines features.
14-day free trial, no card. Both connections, one mapped sync.
No credit card. 14 days. Cancel in one click.