Chapter 18 · Partitioning, Large Tables, Archiving, and Data Lifecycle
Managing Multi-Terabyte Tables: Capacity, Maintenance Windows, and Growth Forecasts
Build a multi-terabyte capacity model from measured table/index growth, binary logs, backups, replicas, temporary DDL space, and maintenance-window constraints without extrapolating tiny lab timings blindly.
Learning outcomes
A table does not become “multi-terabyte” on one dramatic day. It arrives there through ordinary daily inserts, wider payloads, new indexes, longer retention, more replicas, and backup copies. Capacity engineering turns those trends into runway and maintenance decisions before a resize, archive, or DDL operation becomes an emergency.
Measure table, index, partition, binary-log, and row-growth evidence without confusing estimates with exact counts.
Build a capacity model that includes active data, indexes, logs, backups, replicas, temporary/DDL headroom, and free-space safety margin.
Forecast runway from observed growth rates and update the forecast as workload/retention changes.
Identify maintenance operations whose duration/risk grows with table size and define preflight windows/gates.
Reject linear extrapolation from tiny lab timing as a production forecast and design representative scale tests instead.
InnoDB statistics are estimates, compression/page fill vary, secondary indexes include key payload, binary-log volume depends on change patterns, and backup compression/deduplication varies. Preserve assumptions and uncertainty instead of presenting one spreadsheet cell as truth.
Inventory the current physical footprint
USE servicehub_lifecycle_lab;SELECT TABLE_NAME, ENGINE, TABLE_ROWS, DATA_LENGTH, INDEX_LENGTH, DATA_FREE, (DATA_LENGTH+INDEX_LENGTH) AS allocated_bytesFROM information_schema.TABLESWHERE TABLE_SCHEMA='servicehub_lifecycle_lab' AND TABLE_NAME IN ('work_order_events_plain','work_order_events_part','work_order_events_archive');SELECT TABLE_NAME, PARTITION_NAME, TABLE_ROWS, DATA_LENGTH, INDEX_LENGTH, (DATA_LENGTH+INDEX_LENGTH) AS allocated_bytesFROM information_schema.PARTITIONSWHERE TABLE_SCHEMA='servicehub_lifecycle_lab' AND TABLE_NAME='work_order_events_part'ORDER BY PARTITION_ORDINAL_POSITION;SELECT COUNT(*) AS exact_plain_rows FROM work_order_events_plain;SHOW CREATE TABLE work_order_events_plain\GSHOW CREATE TABLE work_order_events_part\GFor InnoDB, TABLE_ROWS is normally estimated. Use exact counts sparingly for business validation and sampled/monitoring growth trends for capacity. DATA_LENGTH and INDEX_LENGTH describe allocated table/index footprint as reported by metadata, not the application payload size alone.
Measure daily growth instead of guessing from table age
SELECT occurred_on, COUNT(*) AS rows_created, SUM(OCTET_LENGTH(payload)) AS payload_bytesFROM work_order_events_plainGROUP BY occurred_onORDER BY occurred_on DESCLIMIT 14;SELECT AVG(rows_created) AS avg_rows_per_day, MAX(rows_created) AS peak_rows_per_dayFROM ( SELECT occurred_on, COUNT(*) AS rows_created FROM work_order_events_plain GROUP BY occurred_on) AS d;The real system should record daily row/byte deltas from monitoring rather than reconstructing them only from retained data. Growth can be seasonal, release-driven, tenant-driven, or retention-driven. Forecast several scenarios such as median, recent peak, and planned business growth instead of one smooth straight line.
Build a storage budget that includes more than the primary table
| Capacity component | Evidence/source | Planning question |
|---|---|---|
| clustered data | DATA_LENGTH + row growth | how quickly does active/retained data grow? |
| secondary indexes | INDEX_LENGTH + planned index changes | how much does every new index multiply write/storage/backup cost? |
| binary logs | SHOW BINARY LOGS / filesystem trend | what retention/PITR/replication window must be preserved? |
| backups | actual dump/snapshot artifacts | how many full/incremental copies and restore staging sets coexist? |
| replicas | same logical dataset plus local logs/temp | how many full copies are required for HA/read scale? |
| DDL/temp headroom | operation-specific preflight | can a rebuild/index sort/copy coexist with current data? |
| filesystem safety margin | OS free space and growth alerts | how much unallocated capacity must remain for bursts/recovery? |
SELECT @@version AS server_version, @@innodb_file_per_table AS file_per_table, @@binlog_expire_logs_seconds AS binlog_retention_seconds, @@log_bin AS binary_logging, @@binlog_format AS binlog_format;SHOW BINARY LOGS;SHOW BINARY LOGS gives current files and sizes when binary logging is enabled; trend their total growth over time. A short lab cannot predict production binlog bytes per row because UPDATE/DELETE patterns, row images, transaction size, schema, and workload all matter.
A transparent runway worksheet
The following arithmetic is intentionally explicit. Replace the sample assumptions with measured numbers from your environment. It does not claim MySQL will consume exactly the modeled bytes.
SET @current_table_bytes = ( SELECT COALESCE(DATA_LENGTH,0)+COALESCE(INDEX_LENGTH,0) FROM information_schema.TABLES WHERE TABLE_SCHEMA='servicehub_lifecycle_lab' AND TABLE_NAME='work_order_events_plain');SET @daily_growth_bytes = 50 * 1024 * 1024; -- replace with measured trendSET @binlog_bytes_per_day = 25 * 1024 * 1024; -- replace with measured trendSET @forecast_days = 365;SET @replica_copies = 2; -- source + replicas modeled separatelySET @backup_full_copies = 2;SET @ddl_headroom_factor = 1.30; -- scenario assumption, not a MySQL defaultSELECT @current_table_bytes AS current_table_bytes, @daily_growth_bytes*@forecast_days AS projected_table_growth, @binlog_bytes_per_day*@forecast_days AS projected_binlog_if_retained, (@current_table_bytes + @daily_growth_bytes*@forecast_days) * (1 + @replica_copies) AS projected_live_copies, (@current_table_bytes + @daily_growth_bytes*@forecast_days) * @backup_full_copies AS projected_full_backup_copies, (@current_table_bytes + @daily_growth_bytes*@forecast_days) * @ddl_headroom_factor AS planning_space_for_one_rebuild_scenario;The factors are planning inputs, not server constants. A COPY rebuild may require substantial additional space; some INPLACE/INSTANT operations need far less. A physical snapshot may be copy-on-write and deduplicated; a logical dump may compress differently. Model each actual tool and operation from measured artifacts.
Forecast runway with scenarios, not false precision
If a filesystem has usable free capacity F and measured net growth is G bytes/day, the naive runway is F/G. That is only a starting point. Reserve mandatory headroom for DDL/recovery, keep enough binary logs for the recovery objective, account for backup overlap, and consider peak growth rather than only average growth.
| Scenario | Growth assumption | Use |
|---|---|---|
| baseline | recent median/normal workload | ordinary capacity trend |
| busy season | recent high percentile or known seasonal peak | stress runway and archive schedule |
| product launch | planned event/tenant growth multiplier | business-driven what-if |
| retention extension | same ingest but more online days | policy-driven footprint increase |
| new index | measured index build and steady-state bytes | schema-change what-if |
Maintenance duration grows with size—but not linearly enough to guess
Operations that scan/rebuild/copy large tables are sensitive to row width, number and type of indexes, buffer-pool residency, device latency/throughput, DDL parallelism, concurrent writes, online-alter-log growth, partition count, filesystem behavior, and replication. A 30,000-row lab completing in one second does not justify multiplying by a row-count ratio to predict a 5 TB table.
“30k rows took 1 second, therefore 3 billion rows will take 100,000 seconds” is not a production forecast. Cache boundaries, sort algorithms, I/O queueing, parallelism, storage limits, concurrency, and metadata-lock phases change as scale changes.
A safer program tests multiple representative scales on production-like storage, captures elapsed and tail application latency, I/O throughput/latency, CPU, temporary-space high-water marks, redo/binlog generation, replica lag, and metadata-lock wait. Use those measurements to select a maintenance window and abort thresholds.
A multi-terabyte operations matrix
| Operation | How size changes risk | Preferred planning response |
|---|---|---|
| add/rebuild secondary index | scan/sort/load and temp space scale with table/index size | preflight exact DDL, measure space/I/O/replica lag; use online method if supported |
| COPY-type schema change | requires reading/writing a replacement representation | avoid surprise fallback; expand/contract or maintenance window |
| mass DELETE | transaction/log/purge/replica cost can become enormous | archive and bounded purge, or partition lifecycle when design aligns |
| backup/restore | artifact size and recovery time grow | parallel/tool-appropriate backups plus scheduled clean restores and RTO measurement |
| partition maintenance | per-partition operations can localize lifecycle work | keep partition boundaries coarse enough to remain operable |
| analytics scan | cache/I/O and replica contention grow | dedicated read path/replica/warehouse as workload requires |
Capacity acceptance checklist
A credible large-table plan records: current rows/data/index bytes; daily and peak growth; retention period; binlog growth/retention; number of live copies; backup artifacts/overlap; free-space floor; DDL temporary/rebuild requirement for known operations; restore RTO/RPO; archive throughput; replica lag tolerance; and the date each capacity threshold is expected to be crossed. Alert on runway and trend changes, not only “disk 90% full.”
SELECT COUNT(*) AS active_plain_rows, MIN(occurred_on) AS first_day, MAX(occurred_on) AS last_dayFROM servicehub_lifecycle_lab.work_order_events_plain;SELECT COUNT(*) AS archived_rows, MIN(occurred_on) AS archive_first_day, MAX(occurred_on) AS archive_last_dayFROM servicehub_lifecycle_lab.work_order_events_archive;SELECT * FROM servicehub_lifecycle_lab.archive_manifest;Optional chapter cleanup
Keep the lifecycle lab if you want to reuse it for Chapter 19 application-integration experiments. If you are finished, remove only the disposable database created by this chapter.
DROP DATABASE IF EXISTS servicehub_lifecycle_lab;Production judgment and bridge to Chapter 19
At multi-terabyte scale, good engineering is mostly advance knowledge: know which partition/lifecycle boundary you will need, which DDL algorithms are acceptable, which archive is recoverable, how much storage/log/backup headroom exists, and which maintenance operation crosses the next capacity threshold. Partitioning is only one tool in that system.
Chapter 19 moves back up the stack to application integration. Once data size and maintenance costs are explicit, connection pools, timeouts, prepared statements, transaction retries, ORM query generation, replicas, migrations, and deployment coordination can be designed against real database constraints rather than idealized SQL calls.
Knowledge check
- Why is INFORMATION_SCHEMA.TABLES.TABLE_ROWS not sufficient for exact capacity or business counts?
- What major storage consumers belong in a large-table capacity model besides table data?
- Why is free-space divided by average daily growth only a starting runway estimate?
- Why should DDL duration be measured at multiple representative scales?
- What should trigger a capacity decision before disk is nearly full?
Reveal answers
- For InnoDB it is generally an estimate; combine metadata trends with exact checks when correctness requires them and with observed filesystem/artifact metrics.
- Secondary indexes, binary logs, backups, replicas, temporary/DDL work space, restore staging, and required free-space safety margin.
- Peak growth, required operational headroom, backup/binlog overlap, retention changes, and future DDL/recovery work also consume capacity.
- Cache, I/O, parallelism, sorting, concurrency, and lock behavior can change with scale, so tiny-lab timing does not extrapolate reliably.
- Forecasted runway crossing a documented headroom/maintenance threshold, rising growth, upcoming retention/index changes, or operations that no longer fit the tested maintenance window.