Quick Start
Write a configuration file, preview the job, and run your first archive.
This page takes a common case β orders older than two years, together with the rows that belong to them β and archives it end to end.
1. Describe the job
Create archiver.yaml:
source:
host: source-db.internal
port: 3306
user: archiver
password: change_me
database: production
destination:
host: archive-db.internal
port: 3306
user: archiver
password: change_me
database: archive
jobs:
archive_old_orders:
root_table: orders
primary_key: id
where: "created_at < DATE_SUB(NOW(), INTERVAL 2 YEAR)"
relations:
- table: order_items
primary_key: id
foreign_key: order_id
dependency_type: "1-N"
- table: order_payments
primary_key: id
foreign_key: order_id
dependency_type: "1-N"
processing:
batch_size: 1000
batch_delete_size: 500
sleep_seconds: 1
verification:
method: sha256
The job says: start from orders, select the rows matching where, and treat
order_items and order_payments as belonging to them.
2. See the shape of the job
goarchive plan -c archiver.yaml --job archive_old_orders
plan draws the relationship tree, the order tables will be written in, and the
order they will be removed in. It reads nothing but the configuration and the
table structure.
3. Check the environment
goarchive validate -c archiver.yaml
validate confirms the tables exist on both servers, the structures are
compatible, the account holds the privileges the run needs, and the
relationships you declared match the database. It reports everything it finds so
you can fix issues before moving data.
4. Preview the work
goarchive dry-run -c archiver.yaml --job archive_old_orders
dry-run shows the filter being applied and how many rows each table would
contribute, following the actual relationships rather than counting whole
tables. It changes nothing.
5. Run it
goarchive archive -c archiver.yaml --job archive_old_orders
GoArchive processes the job in batches. For each batch it discovers the rows that belong together, writes them to the destination parents-first, verifies the result, and removes them from the source children-first. Progress is recorded as it goes.
6. Confirm
SELECT COUNT(*) FROM archive.orders;
SELECT COUNT(*) FROM production.orders
WHERE created_at < DATE_SUB(NOW(), INTERVAL 2 YEAR);
The first count reflects what was archived. The second should be zero.
What to read next
- Concepts β what happens inside a batch
- Configuration β every available setting
- Guides β the copy-only and purge workflows
