Database storage on block volumes is an architecture that places database files on attached disk-like storage separate from a VM’s system disk. It gives PostgreSQL, MySQL, and similar engines a clear storage boundary, but the team still owns filesystem health, capacity, I/O performance, backups, and recovery.
That ownership matters because database storage failures rarely begin with a single obvious error. A volume can have free space while latency rises, I/O queues grow, checkpoints slow down, temporary files expand, or transaction logs consume the remaining headroom. Raff has supported more than 15,000 VM deployments, and the recurring operational lesson is that database storage should be monitored as both a Linux device and a database subsystem.
This guide explains how to structure database data on block volumes, which storage signals matter, how PostgreSQL and MySQL expose I/O pressure, and how layout choices affect recovery. It does not cover initial formatting and mounting; use Block Storage Volume Setup for Linux VMs. It does not replace a full backup policy; use Database Backup Strategy for SaaS Apps for RPO, RTO, retention, and restore planning.
Database storage needs a defined boundary
A production database writes more than table rows. Its storage path can include data files, indexes, transaction logs, temporary files, metadata, and engine-specific control files. These files have different write patterns, but together they form one recovery system.
A simple self-hosted architecture is:
Raff VM system disk ↓ Linux, packages, database service, configuration Raff Volume ↓ Database data directory, indexes, WAL or redo files Database-aware backups ↓ Independent recovery history
The separate volume gives the database a clear capacity and recovery boundary. It also prevents database growth from filling the operating-system filesystem, where a disk-full event could affect logging, package management, SSH access, and other services at the same time.
PostgreSQL normally keeps cluster data under PGDATA; its physical layout includes database files, control data, and the pg_wal directory. MySQL stores server-managed files in its data directory, including InnoDB tablespaces and log files. Moving either engine to a separate volume should preserve the database’s expected directory structure, ownership, permissions, and startup order.
The volume is only the active storage layer. It does not replace database consistency, replication, backups, or restore testing.
The layout decision should follow workload evidence
Most small teams should begin with one dedicated database volume rather than splitting every file type across multiple devices. A simpler layout is easier to document, monitor, back up, and recover.
| Layout | Better fit | Main advantage | Main trade-off |
|---|---|---|---|
| Database on VM system disk | Development or low-risk workloads | Fewest components | Database growth competes with the OS |
| One dedicated database volume | Most self-hosted production databases | Clear capacity and recovery boundary | One volume carries mixed database I/O |
| Separate data and transaction-log volumes | High-write workloads with measured contention | Independent capacity and I/O observation | More mounts, recovery ordering, and configuration |
| Separate temporary-work volume | Workloads with large sorts, imports, or rebuilds | Temporary activity cannot consume data capacity | Extra monitoring and cleanup ownership |
| Managed database | Teams that do not want to own host-level database storage | Reduced storage and recovery operations | Less host-level control and a different cost model |
Choose one dedicated volume when:
- the database needs storage separate from the OS;
- data growth is predictable enough for one capacity pool;
- the team wants the simplest recoverable self-hosted layout;
- observed I/O pressure does not justify splitting file classes;
- backups and restore procedures assume one database storage boundary.
Consider separate data and log volumes when:
- measurements show transaction-log activity competing with data-file I/O;
- the log and data areas have materially different growth rates;
- recovery documentation covers every mount and their required ordering;
- monitoring can distinguish the devices;
- the engine configuration and backup plan explicitly support the split.
Choose a managed database when:
- nobody owns filesystem, patching, backup, and restore operations;
- disk alerts are regularly ignored;
- the team cannot test database recovery;
- database availability matters more than host-level control;
- operational time is more constrained than infrastructure flexibility.
Splitting storage before evidence exists can make recovery harder without improving performance. The strongest default is a single dedicated volume, enough headroom, and measurements that reveal whether a second boundary is justified.
Capacity planning should use time-to-full, not only percentage used
A database volume can move from healthy to critical quickly during an import, index rebuild, schema migration, replication problem, or transaction-log surge. Percentage-used alerts are necessary, but they are incomplete without growth rate.
A practical capacity model tracks:
- current allocated capacity;
- database data size;
- index size;
- transaction-log or WAL generation rate;
- temporary-file growth;
- backup or export staging space;
- maintenance-operation headroom;
- daily and weekly growth rate;
- estimated time to full;
- available expansion and recovery window.
For example, a volume at 70% utilization may be safe if growth is stable at 1% per month. The same utilization can be urgent if a migration is adding 5% per hour. Time-to-full makes the difference visible.
| Capacity signal | What it reveals | Operational response |
|---|---|---|
| Filesystem utilization | Remaining usable space | Investigate before emergency thresholds |
| Inode utilization | Ability to create more files | Check engines or workloads that create many small files |
| Data and index growth | Long-term database expansion | Forecast capacity and archiving needs |
| WAL, redo, or binary-log growth | Write activity and retention pressure | Check replication, archiving, and checkpoint behavior |
| Temporary-file growth | Sorts, imports, queries, or maintenance pressure | Correlate with query and job activity |
| Time to full | How long the team has to act | Resize, clean up, archive, or change the workload |
A volume resize is a capacity action, not a root-cause fix. If retention, failed archiving, runaway queries, or abandoned temporary files caused the pressure, increasing capacity only postpones the incident. Use Linux Volume Expansion: Filesystem Growth and Verification when additional capacity has been approved.
Storage monitoring needs five infrastructure signals
Database storage should be observed through at least five infrastructure dimensions: capacity, latency, IOPS, throughput, and queueing.
| Signal | Meaning | Why it matters to databases |
|---|---|---|
| Capacity | Used and available filesystem space | Full storage can stop writes, checkpoints, or service startup |
| Latency | Time required to complete reads and writes | Commit and query response times can rise before capacity is exhausted |
| IOPS | Number of I/O operations completed per second | Small random reads and writes can saturate operation capacity |
| Throughput | Bytes transferred per second | Scans, backups, imports, and maintenance can be bandwidth-heavy |
| Queueing | Work waiting for the storage device | Sustained queues indicate demand is arriving faster than it is completed |
These signals should be correlated rather than read separately. High IOPS with low latency may be healthy. Moderate IOPS with rising latency and queue depth may indicate saturation. High throughput during a scheduled backup may be expected; the same pattern during peak traffic may explain application slowdown.
Linux tools such as iostat, filesystem metrics, and system telemetry reveal the device view. Database statistics reveal which engine activity is producing that pressure. PostgreSQL’s monitoring system includes pg_stat_io, pg_stat_wal, checkpointer statistics, database statistics, and relation I/O views. MySQL’s Performance Schema includes file I/O summary tables, while InnoDB monitoring exposes pending I/O, redo-log progress, checkpoints, buffer-pool activity, and write statistics.
The useful question is not simply “is the disk busy?” It is:
Which database activity is producing storage pressure, and is the device completing that work within the workload’s latency budget?
PostgreSQL storage signals should be read together
PostgreSQL stores the database cluster under PGDATA and keeps write-ahead log files under pg_wal by default. Data-file and WAL behavior should be monitored together because both participate in durability and recovery.
Useful PostgreSQL evidence includes:
pg_stat_iofor reads, writes, writebacks, extensions, operation timing, and I/O context;pg_stat_walfor WAL records, bytes, writes, syncs, and related timing;pg_stat_checkpointerfor checkpoint activity and write/sync behavior;- database and relation statistics for temporary files, table reads, and index activity;
- archiver and replication status when WAL retention depends on downstream consumers;
- filesystem capacity for
PGDATA,pg_wal, tablespaces, and temporary paths.
A rise in storage latency combined with checkpoint pressure can produce broader query and commit delays. Rapid pg_wal growth may reflect heavy writes, delayed archiving, replication-slot retention, or a maintenance operation. Large temporary-file growth can point to memory pressure or expensive sorts and joins, but the storage effect still has to be managed.
PostgreSQL tablespaces can place selected database objects on different storage locations, but that should be an evidence-based decision. Each additional path becomes part of backup, monitoring, permissions, and recovery documentation. A separate WAL path or tablespace is not automatically faster; it is useful only when the workload, storage characteristics, and operating model support it.
MySQL and InnoDB need engine and filesystem telemetry
MySQL’s data directory can contain InnoDB tablespaces, redo files, temporary data, binary logs, and other server-managed files. InnoDB performs background I/O and checkpoints to preserve durability while controlling how dirty pages reach storage.
Useful MySQL evidence includes:
- Performance Schema file I/O summary tables;
- file instruments for InnoDB data, log, temporary, and related files;
- InnoDB Standard Monitor output for pending reads and writes, log progress, checkpoints, and buffer-pool activity;
- redo-log capacity and checkpoint movement;
- binary-log growth and retention;
- temporary-file and tablespace growth;
- filesystem capacity, latency, throughput, and queueing.
The InnoDB documentation emphasizes managing both I/O saturation and disk space. That is an important pairing: a volume may have ample capacity but still be too slow for the workload, or it may deliver acceptable latency while uncontrolled logs consume all remaining space.
Do not tune InnoDB I/O settings only because the volume reports high utilization. First identify whether the pressure comes from foreground queries, flushing, checkpoints, backup activity, DDL, imports, or insufficient memory. Storage tuning without workload context can move the bottleneck rather than remove it.
Recovery design should match the failure mode
A database volume creates a useful recovery boundary, but different failures require different recovery sources.
| Failure | Better recovery source | Why |
|---|---|---|
| VM operating-system failure | Rebuild or replace the VM, then attach or restore database storage | The database data boundary is separate from the OS |
| Accidental row or table deletion | Database backup, point-in-time recovery, or replica strategy | The active volume already contains the deletion |
| Filesystem or database corruption | Verified database backup or known-good recovery point | A current snapshot may contain the corruption |
| Bad schema migration | Database-aware rollback or pre-change recovery point | Logical and physical state must match the migration plan |
| Full volume | Restore write capacity, then address growth cause | Capacity must be recovered without hiding retention failures |
| Lost or unavailable volume | Restore to replacement storage | The workload needs a documented replacement path |
| Wrong permissions or mount path | Correct the storage boundary and verify ownership | The data may be intact but inaccessible to the engine |
| Complete VM and volume loss | Independent backup and tested rebuild runbook | Active infrastructure cannot be the only copy |
A block-level snapshot can be valuable before upgrades, migrations, imports, and other risky changes. It should not be assumed to be database-consistent without an engine-aware procedure. Database-aware backups, WAL or log retention, replica strategy, and restore testing remain necessary according to the recovery objective.
The backup page owns RPO, RTO, retention, and backup-method selection. This guide’s narrower rule is that every storage layout must have a recovery map: which files live on which volume, which recovery source covers each failure, and in what order the database is brought back.
Operational controls prevent most storage surprises
The storage design should be recorded before the database becomes difficult to move or recover.
A useful database-volume record contains:
Workload: production PostgreSQL Volume purpose: primary database data Mount path: /srv/postgres-data Database path: documented PGDATA location Filesystem: documented type and UUID Owner: platform team Capacity owner: named engineer or team Monitoring: capacity, latency, IOPS, throughput, queueing Recovery: database backup plus pre-change snapshots Growth review: monthly or after major releases
The following controls reduce operational ambiguity:
- one clear owner for the volume and database service;
- stable UUID-based mounts and documented startup dependencies;
- narrow filesystem permissions for the database service account;
- separate alerts for filesystem usage and storage performance;
- time-to-full forecasting;
- database-level WAL, redo, temporary-file, and checkpoint monitoring;
- backups stored independently from the active volume;
- restore tests that include the mount path and database startup;
- pre-change recovery points for high-risk maintenance;
- post-change validation of writes, reads, replication, and backups;
- a deletion process that proves the volume is no longer authoritative.
Across Raff infrastructure reviews, the most useful evidence is a single dashboard or incident view that aligns Linux device metrics with database events. It prevents teams from treating a slow query, a checkpoint spike, a backup job, and a saturated volume as four unrelated problems.
Raff supports two database operating models
Raff Volumes fit teams that want to self-host a database on a Raff VM while keeping database storage separate from the system disk. At the current canonical rate of $0.10 per GB-month, capacity can scale independently from the VM’s CPU and RAM plan. The team retains control over the engine, filesystem, mount path, tuning, backups, and recovery.
A practical self-hosted model is:
Raff VM ↓ Database service and configuration Raff Volume ↓ Database data boundary Raff Data Protection and database-aware backups ↓ Recovery points and independent history
This model is appropriate when the team needs engine-level control and has an owner for Linux and database operations. Use Block Storage Volumes for Databases, Containers, and App Data for the broader storage decision and Block Storage Volume Setup for Linux VMs for initial preparation.
Raff Managed Databases fit teams that want to reduce host-level database operations. The managed path can be the better decision when the team cannot consistently maintain storage telemetry, backups, patching, and recovery exercises. The choice is not between “simple” and “advanced.” It is between two responsibility models.
Self-host on a volume when control is worth the operating burden. Choose a managed database when reducing that burden creates more value than host-level flexibility.
Database volume readiness checklist
Before placing a production database on a block volume, confirm:
- The database volume has one documented purpose and owner.
- The system disk and database data are separated intentionally.
- The mount path, filesystem, UUID, ownership, and startup dependency are recorded.
- The engine’s data, WAL or redo, binary-log, temporary, and tablespace paths are known.
- The current data and index size are measured.
- Daily and monthly growth rates are tracked.
- Time-to-full is monitored.
- Capacity, latency, IOPS, throughput, and queueing are visible.
- PostgreSQL or MySQL engine telemetry is correlated with device metrics.
- Maintenance operations have enough temporary headroom.
- Volume expansion has an approved operating procedure.
- Backups are independent from the active volume.
- Snapshot consistency assumptions are documented.
- Restore testing includes the filesystem mount and database startup.
- Recovery sources are mapped to deletion, corruption, migration, and infrastructure failure.
- The team has decided whether managed databases would reduce unacceptable operational risk.
Conclusion
Database storage on block volumes works best when the volume is treated as an operating boundary, not merely extra disk space.
Start with one dedicated database volume unless measurements justify a more complex split. Monitor capacity, latency, IOPS, throughput, queueing, and the engine signals that explain them. Preserve enough headroom for maintenance and log growth, map each failure to a recovery source, and test recovery independently from the active volume.
For the broader storage decision, continue with Block Storage Volumes for Databases, Containers, and App Data. For backup policy, use Database Backup Strategy for SaaS Apps.