RonDB training · module 17 of 25 · 18 min
Backup and restore
A transaction-consistent copy of the whole cluster, taken online, and the four steps that bring it back.
Backup · not the same as a checkpoint
Backups vs checkpoints: backups survive disasters and move data
Local checkpoint
- Continuous, partial, per node.
- Only that node can use it, with its REDO log.
- Kept by RonDB, replaced as it goes.
Backup
- On demand: the whole cluster, consistent at one global checkpoint.
- Restorable into any cluster: new hardware, other sizes, other versions.
- Kept by you: archives, upgrades, seeding replication.
Both share one disk write budget, MinDiskWriteSpeed and MaxDiskWriteSpeed; BackupDiskWriteSpeedPct (50) reserves part of it for backups.
docs: rondb_backup.md · code: ConfigInfo.cpp (BackupDiskWriteSpeedPct 50: "Percentage of MaxDiskWriteSpeed to reserve for Backup")
Taking a backup · from the management client
START BACKUP: one command backs up the whole cluster, online
- Each backup gets an id: here 1.
- The backup is consistent at a global checkpoint: here StopGCP 3845.
- Records came from the scan; log records are changes made while it ran.
docs: rondb_backup.md · rondb_global_prepare_primary.md (the output) · code: mgmclient/CommandInterpreter.cpp (START BACKUP)
START BACKUP · the full syntax
START BACKUP options: the id, encryption, the snapshot point and waiting
START BACKUP [<backup id>] [ENCRYPT [PASSWORD='<password>']] [SNAPSHOTSTART | SNAPSHOTEND] [NOWAIT | WAIT STARTED | WAIT COMPLETED]
| Option | Means |
|---|---|
| <backup id> | Your own id instead of the next number |
| ENCRYPT PASSWORD | Encrypted backup files; RequireEncryptedBackup can make it mandatory |
| SNAPSHOTEND · default | Consistent at the end of the backup |
| SNAPSHOTSTART | Consistent at the start |
| WAIT COMPLETED · default | The client waits for the report; NOWAIT and WAIT STARTED return sooner |
code: mgmclient/CommandInterpreter.cpp (helpTextStartBackup) · ConfigInfo.cpp (RequireEncryptedBackup) · docs: rondb_backup.md (The START BACKUP command)
The algorithm · a scan plus a log
The backup algorithm: scan every fragment while a log records the changes
The backup starts at a global checkpoint, StartGCP: from then on triggers send every change to the backup log.
Table definitions go to the control file first.
Each fragment is scanned into the data file. The scan is not consistent by itself: rows change while it runs. The log has every change.
After the scan, the log stops at a later global checkpoint, StopGCP. Data plus log replayed give exactly the state at StopGCP.
docs: rondb_backup.md (Backup algorithm) · code: backup/Backup.cpp
SNAPSHOTEND or SNAPSHOTSTART · REDO or UNDO
SNAPSHOTEND or SNAPSHOTSTART: the backup shows its end or its start
SNAPSHOTEND · default
- The log records how to redo each change.
- Restore applies it forwards after the data.
- Consistent at StopGCP.
SNAPSHOTSTART
- The log records how to undo each change.
- Restore applies it backwards; the log is never compressed, so it can be read from the end.
- Consistent at StartGCP: the moment you asked for.
docs: rondb_backup.md (Backup algorithm, The START BACKUP command) · code: backup/Backup.cpp (log left uncompressed for SNAPSHOTSTART)
On disk · one set of files per ldm thread
Backup files: every ldm thread writes its own part of the backup
# under BackupDataDir, on data node 1 BACKUP/ BACKUP-10/ BACKUP-10-PART-1-OF-4/ BACKUP-10-0.1.Data # rows BACKUP-10.1.ctl # definitions BACKUP-10.1.log # changes BACKUP-10-PART-2-OF-4/ … BACKUP-10-PART-4-OF-4/
- Each data node writes only its own fragments: a full backup is the files of all data nodes.
- One PART directory per ldm thread, written in parallel.
code: src/kernel/blocks/ndbfs/Filename.cpp (BACKUP-%u-PART-%u-OF-%u, BACKUP-%u-%u.%u) · backup/Backup.cpp · docs: rondb_backup.md (Backup file placement) · ids are an illustration
Configuration · and file management
Put backups on their own device: a full disk can stop the cluster
| config.ini | Default | Why |
|---|---|---|
| BackupDataDir | DataDir | A separate device: filling it must not take space from checkpoints |
| BackupLogBufferSize | 16M per ldm thread | Changes during the backup; if it fills, the backup aborts |
| CompressedBackup | false | Smaller files, more CPU in io threads |
| BackupDiskWriteSpeedPct | 50 | Share of the write budget kept for backups |
Old backups are yours to delete. ABORT BACKUP <id> stops a running backup and deletes its files.
docs: rondb_backup.md (Backup configuration, Backup file management, Aborting a backup) · code: ConfigInfo.cpp (BackupLogBufferSize 16M, CompressedBackup false, BackupDiskWriteSpeedPct 50)
Metadata · what the backup does not cover
Back up MySQL objects with mysqldump
mysqldump \
--no-data \
--databases db1 db2 \
> backup_metadata.sql
# restore it through a MySQL server
mysql < backup_metadata.sql
- Tables and databases, and also views, stored procedures and triggers, which live in MySQL servers (module 03).
- Recommended over the backup's own metadata: it goes through MySQL, so all servers and global replication see it.
- Keep RonDB tables in their own databases to dump only them.
docs: rondb_backup.md (Backing up metadata in RonDB) · rondb_restore.md (Using MySQL dump)
PART 1
Restore
ndb_restore, in four steps.
ndb_restore · into a freshly started cluster
ndb_restore: metadata once, indexes off, data in parallel, indexes back on
Restore into an empty cluster, after an initial start. The target may have a different number of data nodes: rows are hashed to its partitions.
docs: rondb_restore.md (Commands to run) · code: tools/restore/restore_main.cpp
Commands · backup 10 of a two-node cluster
ndb_restore commands: each names the server, node id, backup id and path
R="ndb_restore --connectstring=mgm_host --backupid=10 --backup-path=/backup/path/dir" $R --nodeid=1 --restore_meta --no-restore-disk-objects # 1 once $R --nodeid=1 --disable-indexes # 2 once $R --nodeid=1 --restore-data & # 3 per node, $R --nodeid=2 --restore-data & # in parallel wait $R --nodeid=1 --rebuild-indexes # 4 once
--nodeidnames the node that took the backup, whose files are read.- Each call finds the PART directories itself and restores them with a thread each;
--parallelismdefaults to 128 transactions. - After step 1, run SHOW TABLES on the MySQL servers so they see the new tables.
docs: rondb_restore.md (Commands to run, Restoring metadata) · code: restore_main.cpp (parallelism default 128; PART-x-OF-y detection) · the shell wrapper is an illustration
Indexes · off during the data step
Why indexes are off: restored data is inconsistent until the last log record
The scan
Rows were scanned at different moments: two rows may briefly hold the same unique value.
So
With unique indexes enabled, inserts could fail mid-restore. Disabling indexes is a must when unique indexes exist.
Meanwhile
Only primary key lookups and full table scans give correct results. Keep applications away until step 4 is done.
docs: rondb_restore.md (Disabling indexes, Commands to run)
ndb_restore options · pick and transform
ndb_restore options: restore part of a backup, under other names, or with changes
| Option | Does |
|---|---|
| --include-databases · --exclude-tables … | Restore only some databases or tables |
| --rewrite-database=old,new | Restore into another database name |
| --remap-column · --allow-pk-changes | Transform column values; allow primary key changes |
| --num-slices · --slice-id | Split one node's data over several ndb_restore processes |
| --decrypt --backup-password | Read an encrypted backup |
| --include-stored-grants · --restore-privilege-tables | Users stored in RonDB |
code: storage/ndb/tools/restore/restore_main.cpp (option table) · docs: rondb_restore.md (Partial restore)
Global replication · start a replica from a backup
Seeding a replica: a restore tells it where in the binary log to start
- Back up the primary cluster; the backup ends at a known epoch (from StopGCP).
- Restore all four steps on the replica with
--no-binlog: the restore itself must not be replicated. - Add
--restore-epochto the last step: it writes the epoch intondb_apply_statuswith server_id 0. - Start replication from that epoch: nothing lost, nothing applied twice (module 24).
docs: rondb_restore.md (restore with --no-binlog and --restore-epoch) · rondb_global_prepare_primary.md
Recap · module 17
What to take away
START BACKUP: online, consistent at a global checkpoint.- A scan plus a log: SNAPSHOTEND rolls forward, SNAPSHOTSTART rolls back.
- One PART directory per ldm thread, on every data node; use a separate device.
- Restore: metadata, indexes off, data per node in parallel, indexes on.
--no-binlogand--restore-epochseed global replication.
RonDB training · 25 modules · you are at 17