Skip to content

MySQL

TwinCommit captures changes from MySQL by reading the binary log as a replica would. It uses row-based events with full row images and GTIDs, buffers changes per transaction and applies each committed transaction in commit order. Nothing is installed in the database.

Supported: MySQL 8.0, 8.4 LTS and 9.x · Amazon RDS for MySQL · Aurora MySQL · Azure Database for MySQL Flexible Server · Google Cloud SQL for MySQL.

# my.cnf
[mysqld]
server_id = 101
log_bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_expire_logs_seconds = 604800 # keep 7 days so a stopped pipeline can resume

On RDS and Aurora, set these through a parameter group and keep binlogs available with:

CALL mysql.rds_set_configuration('binlog retention hours', 168);
CREATE USER 'twincommit'@'%' IDENTIFIED BY '********';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'twincommit'@'%';
GRANT SELECT ON app.* TO 'twincommit'@'%'; -- for snapshots

Every replicated table needs a primary key or a non-null unique key.

source:
type: mysql
host: mysql-primary.internal
port: 3306
user: twincommit
password: ${MYSQL_PASSWORD}
server_id: 4201 # unique among all replicas of this server

Run twincommit check to confirm every setting. It prints the exact statement for anything that is missing.

  • TwinCommit registers as a replica with its own server_id and streams binlog events from the GTID recorded in its checkpoint.
  • Row events are grouped by transaction and released at XID (commit). Rolled-back transactions never appear in the binlog, so nothing partial reaches the target.
  • The snapshot runs in a consistent-read transaction and records the GTID set at its start, so streaming resumes exactly where the snapshot ends. See snapshots.
  • binlog_format = STATEMENT or MIXED is not supported.
  • binlog_row_image = MINIMAL or NOBLOB is not supported; TwinCommit needs full before and after images.
  • Tables using the MEMORY or BLACKHOLE engines are not captured.
  • DDL is detected, not propagated. See schema changes.