replication-manager reads the binary logs of the servers it monitors in four ways: it watches their rotation, scans the primary's new events for the security plugins, copies the closed binlogs into the backup directory, and purges binlogs on the servers. This page shows each path, what it reads, where the result goes, and the settings that drive it.
┌─────────────────────────────────────────── primary ────────────────────────────────────────────┐
│ mysql-bin.000041 mysql-bin.000042 mysql-bin.000043 (current) │
└───────────────┬───────────────────────────────┬────────────────────────────────┬───────────────┘
│ │ │
│ every tick: │ replica stream │ on rotation
│ file + position │ (active only) │ (backup-binlogs)
▼ ▼ ▼
┌──────────────────────────────┐ ┌──────────────────────────────┐ ┌──────────────────────────────┐
│ 1. Rotation watch │ │ 2. Event scanner │ │ 3. Binlog copy │
│ binlog list, oldest time, │ │ new QUERY events into an │ │ mysqlbinlog | ssh | script │
│ binary-logs.meta.json │ │ in-memory ring buffer │ │ the closed binlog, then │
│ (server's repman folder) │ │ (200 events per server) │ │ the missing ones (keep) │
└──────────────────────────────┘ └──────────────────────────────┘ └──────────────────────────────┘
│ │ │
▼ ▼ ▼
┌──────────────────────────────┐ ┌──────────────────────────────┐ ┌──────────────────────────────┐
│ 4. Purge on servers │ │ Security plugins │ │ Backup directory │
│ PURGE BINARY LOGS on the │ │ cleartext password, │ │ <backups>/<cluster>/<server>/│
│ primary and the replicas │ │ credit card leak ... │ │ binary-logs.meta.json, │
│ (force-binlog-purge*) │ │ (binlog_events input) │ │ in the next backup snapshot, │
└──────────────────────────────┘ └──────────────────────────────┘ │ copies beyond keep purged │
└──────────────────────────────┘
Every path that streams a binlog presents a replica server id leased from a pool of 11 ids
starting at check-binlog-server-id (10000 to 10010 by default), so two consumers of one
replication-manager never kill each other's stream on the primary.
At every monitoring tick replication-manager reads the current binlog file and position of each
server (SHOW MASTER STATUS). When the file changes, the binlog rotated:
binlog-parse-mode, and written to binary-logs.meta.json in replication-manager's folder of
the server, <working-dir>/<cluster>/<host>_<port>/;binlog-rotation-script runs on the primary, when set;backup-binlogs is on and no failover runs.binlog-parse-mode| Item | Value |
|---|---|
| Description | How binlogs are read for their event times: gomysql (in process) or mysqlbinlog |
| Type | string |
| Default Value | "gomysql" |
binlog-rotation-script| Item | Value |
|---|---|
| Description | Script run on the primary at each binlog rotation |
| Type | string |
| Default Value | "" |
With monitoring-binlog-events on, replication-manager keeps a replica stream open on the
primary only, and only on the active replication-manager (a standby never consumes the
primary's binlog). The stream starts at the primary's current position: only new events are read.
At each tick it reads what arrived, within 50 ms per event, so the monitoring tick never waits,
and keeps the QUERY events (statement text, default schema, server id, time; BEGIN,
COMMIT and ROLLBACK skipped) in a ring buffer in memory, per server, newest first, of
monitoring-binlog-event-log-length events. Nothing is written to disk. With the scanner off,
the buffer takes no memory.
The security plugins (plugin-binlog-cleartext-password, plugin-binlog-creditcard-leak ...) run
at each tick right after the scan and receive a copy of the buffer in their input
(binlog_events). Row events are not decoded: what the plugins see is SQL text, such as
statements in statement-based logging and DDL like CREATE USER or ALTER USER, which are
always logged as statements.
When the stream is reset again and again (another binlog consumer presenting the same replica
server id: a replica, another replication-manager, a mysqlbinlog fetch), the scanner pauses:
30 s after the third reset within 10 minutes, doubling up to 30 minutes, with a state saying why.
monitoring-binlog-events| Item | Value |
|---|---|
| Description | Scan the primary's new binlog QUERY events for the binlog security plugins |
| Type | boolean |
| Default Value | false |
monitoring-binlog-event-log-length| Item | Value |
|---|---|
| Description | Number of binlog QUERY events kept in memory per server for the security plugins |
| Type | integer |
| Default Value | 200 |
check-binlog-server-id| Item | Value |
|---|---|
| Description | First replica server id of the pool the binlog consumers lease from (the pool is 11 ids) |
| Type | integer |
| Default Value | 10000 |
With backup-binlogs on, the primary's binlogs are copied into its backup directory,
<backups>/<cluster>/<server>/:
backup-binlogs-keep binlogs.backup-binlogs-keep that is missing
from the backup directory is copied, as long as the server still has it.How a binlog is copied is binlog-copy-mode:
| Mode | How |
|---|---|
mysqlbinlog (default; client is the same) |
mysqlbinlog --read-from-remote-server --raw from the replication-manager host |
ssh (default of the on-premise builds) |
the file copied over SSH from the server's binlog directory |
script |
binlog-copy-script <cluster> <host> <port> <ssh port> <binlog dir> <copy dir> <binlog> |
gomysql is accepted by the setting but does not copy binlogs: use one of the three above.
How it ends up in the backup directory:
.binlog.partial/ of the backup directory,
and only moved into the backup directory once complete: the directory, and so its snapshots,
only ever holds complete binlogs. A failed copy is removed from the staging folder.<binlog>.enc with its integrity sidecar, and
the plain copy is removed.binary-logs.meta.json of the backup directory.With an archive attached, a binlog copy that leaves the keep window and that no snapshot holds
yet is kept while a binlog-only snapshot of the backup directory, tagged trigger:binlogs,
is taken; once it succeeds the copies beyond the window are deleted. With no backup in between,
a snapshot is so taken every backup-binlogs-keep binlogs at most, and every binlog copied is in
a snapshot of the archive. Each of these snapshots also holds the last backup of the directory:
it restores on its own. After a restart, the snapshots holding the copies are not known: the
first deletion takes a snapshot first. While copies wait for it, WARN0258 says how many, the
oldest and since when.
Better lose binlogs than backups. The binlog copy never stops, and the purge policy always applies. The binlog-only snapshot is not taken when:
backup-archive-remove-original is on: it would hold binlogs without their backup;backup-disk-treshold-warn;The copies beyond the window are then deleted anyway, and the binlog continuity of the server
in the archive is lost: WARN0259 gives the server, the binlogs in no snapshot, why and since when.
A point-in-time restore from a backup taken before them stops there. Binlogs dropped from the
copy queue (more than backup-binlogs-keep waiting) are tracked the same way. The state is kept
across restarts and ends with the next backup of the server in the archive: the chain is whole
from that backup on.
The binlog-only snapshots are purged by their own tagged policy, trigger:binlogs in
backup-keep-tag-policies (default keep-within=1d), counted apart from the backups: they never
push a backup out of backup-keep-last. Those taken since the last backup are always kept; the
policy sets how long the older ones stay, the point-in-time restore window before the last
backup. See Archiving, tagged purge policies.
Without an archive, the copies beyond the window are deleted at once.
backup-binlogs (2.1)| Item | Value |
|---|---|
| Description | Copy the primary's binlogs into its backup directory |
| Type | boolean |
| Default Value | false |
backup-binlogs-keep (2.1)| Item | Value |
|---|---|
| Description | Number of the primary's last binlogs kept in the backup directory (and caught up when missing) |
| Type | integer |
| Default Value | 10 |
binlog-copy-mode| Item | Value |
|---|---|
| Description | How binlogs are copied: mysqlbinlog, ssh or script |
| Type | string |
| Default Value | "mysqlbinlog" ("ssh" for the on-premise builds) |
binlog-copy-script| Item | Value |
|---|---|
| Description | Script copying a binlog, for binlog-copy-mode script (arguments above) |
| Type | string |
| Default Value | "" |
backup-mysqlbinlog-path (2.1)| Item | Value |
|---|---|
| Description | Path to the mysqlbinlog binary |
| Type | string |
| Default Value | "" |
When empty, the binary provided in the share directory is used. It can be old: installing the client package of your database version is advised.
replication-manager can purge binlogs on the servers themselves (PURGE BINARY LOGS):
force-binlog-purge-min-replica replicas are connected (otherwise a warning says why it
waits);The binlog budget is force-binlog-purge-total-size when set (GB). At 0, the default, it
follows the disk, from the first of these that is known:
| Known | Budget |
|---|---|
the plan's disk (prov-db-disk-size, a provisioned cluster) and the database size (the schema monitor) |
(plan disk - data) / 2 |
the data disk's free space: reported by the jobs script (on premise, while SSH is available), else information_schema.DISKS |
binlogs now + half the free space |
| nothing | 30 GB |
Half, so that the other half stays for the data, temporary files and a restore. The budget is
recomputed as the data grows and after a disk resize, and it never goes below two binlog files
(2 x max_binlog_size): WARN0264 says when the data leaves no more room. On MariaDB 11.4 and up
it is set as max_binlog_total_size. Under the dynamic configuration the plan sets that variable
instead: prov-db-binlog-total-size-pct of the plan's disk, set live on every MariaDB 11.4+ server
whether force-binlog-purge is on or not.
Replicas and the purge, by version
| Database | Who purges by size | A connected replica (IO thread running), even lagging | A disconnected replica (stopped, down, IO error) |
|---|---|---|---|
| MariaDB 11.4 and up | the server itself (max_binlog_total_size, set from the budget, or by the plan under the dynamic configuration) |
safe: the server never purges a binlog a replica's dump thread is reading | at risk: the server purges past the budget whatever it still needs; WARN0265 names it, and it needs a reseed unless it reconnects first |
| MariaDB before 11.4, MySQL, Percona | replication-manager (PURGE BINARY LOGS) |
safe | safe: the purge stops at the oldest binlog any replica still reads (WARN0107), the primary keeps more than the budget |
On MariaDB 11.4 and up the server also purges by size only while slave_connections_needed_for_purge
replicas (1 by default) are connected: with every replica disconnected, nothing is purged by size.
Only the server's own expiry by time (binlog_expire_logs_seconds, expire_logs_days), not
replication-manager's, can remove a binlog a replica still needs on any version.
So an active replica is never broken by the purge, on any version. On MariaDB 11.4 and up, the one to watch is a replica left disconnected longer than the budget's worth of binlogs: bring it back, or let replication-manager reseed it.
A binlog still queued for copy (path 3) is never purged by replication-manager: the purge stops
just before it. Since 3.1.45 the size limit it sets on MariaDB 11.4 and up (max_binlog_total_size)
never drops under the binlogs still queued for copy either: the server purges by size by itself,
and would otherwise remove a binlog before its copy reached the archive. The server's own expiry (binlog_expire_logs_seconds, expire_logs_days) is not
replication-manager's: a binlog it removes before it was copied can no longer be caught up;
WARN0257 says when the oldest binlog to copy is the server's oldest.
force-binlog-purge| Item | Value |
|---|---|
| Description | Purge the primary's binlogs beyond force-binlog-purge-total-size |
| Type | boolean |
| Default Value | false |
force-binlog-purge-total-size| Item | Value |
|---|---|
| Description | The binlog budget in GB: the primary's binlogs beyond it are purged; 0 follows the disk (see above) |
| Type | integer |
| Default Value | 0 (30 before 3.1.45) |
force-binlog-purge-min-replica| Item | Value |
|---|---|
| Description | Replicas connected needed to purge the primary's binlogs |
| Type | integer |
| Default Value | 1 |
force-binlog-purge-replicas| Item | Value |
|---|---|
| Description | Purge the replicas' binlogs down to the oldest binlog time on the primary |
| Type | boolean |
| Default Value | false |
force-binlog-purge-on-restore| Item | Value |
|---|---|
| Description | Purge binlogs on restore |
| Type | boolean |
| Default Value | false |