sluice

Migrating from AWS RDS MySQL with sluice

The detect-first binlog-retention advisory (what the WARN means and the one-line SQL remedy), 8.0-family parameter groups, the platform-blocked FTWRL, and the regional truststore bundle.

AWS RDS for MySQL works with sluice's vanilla mysql engine — cold copy and the CDC handoff were validated live (2026-07-16, MySQL 8.4.9 on a db.t4g.micro). Aurora MySQL shares the endpoint suffix and the retention procedure below. Like DigitalOcean, the headline is binlog retention — but on RDS the truth is SQL-visible, so sluice can check it for you instead of warning blind.

Binlogs purge in ~5–11 minutes on defaults #

With no retention configured, RDS purges each binlog file on a ~5-minute sweep once automated backups have uploaded it — observed lifetime ~5–11 minutes per file — while @@binlog_expire_logs_seconds reads 30 days. The server variable does not govern the RDS purger (same class as DigitalOcean), but unlike DO the real setting is visible in SQL: CALL mysql.rds_show_configurationbinlog retention hours, default NULL (“as soon as possible”). A CDC position older than the window is unrecoverable, and a cold copy longer than it can livelock auto-resnapshot — and RDS's window is tighter than DO's ~13–16 minutes: plan for the ~5-minute floor, not the ceiling.

Before sync start or backup, run this on the source (master user, plain SQL, effective immediately, no restart):

CALL mysql.rds_set_configuration('binlog retention hours', 24);  -- range 1..168 (7 days max)
CALL mysql.rds_show_configuration;                               -- verify: binlog retention hours = 24

The details that matter, all live-proven:

What the WARN means. sluice's advisory here is detect-first: on sync/backup runs against an *.rds.amazonaws.com host it queries the retention setting and WARNs only when it is NULL or under 24 hours — a correctly configured source stays silent. If you see the WARN, the stream is running on borrowed time (~5–11 minutes of it); run the mysql.rds_set_configuration call above and the next run is quiet.

Version + parameter-group gotchas #

The FTWRL platform block (why serial cold copy is expected) #

RDS blocks FLUSH TABLES WITH READ LOCK at the platform level even though the master user holds RELOAD — the statement returns 1045 Access denied regardless of grants. Two sluice behaviours follow, both by design and both WARNed:

No grant fixes this — it's the platform, not your permissions (sluice's WARN text names the RDS reality on RDS hosts). If exactness of the handoff position matters, quiesce writers during the snapshot; on an idle or low-write source, accept the WARN.

TLS: the public regional bundle #

RDS defaults allow plaintext (require_secure_transport=OFF), and a bare ?tls=true fails — the RDS CA is not in system roots. The working recipe is --source-tls-ca with the public regional bundle (one well-known URL per region, no API call — contrast DO's authenticated CA endpoint):

curl -sO https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem

sluice sync start \
    --source-driver mysql --source 'admin:pass@tcp(mydb.abc123.us-east-1.rds.amazonaws.com:3306)/app' \
    --source-tls-ca us-east-1-bundle.pem \
    --target-driver postgres --target 'postgres://user:pass@target-host:5432/app?sslmode=require' \
    --stream-id rds-app

The master user has the replication grants CDC needs out of the box (REPLICATION SLAVE, REPLICATION CLIENT) — nothing to GRANT on defaults.

What sluice checks for you #

Next steps #