CPU Utilization Spike Due to I/O Wait During MySQL Backup

Mydbops
Jul 29, 2026
10
Mins to Read
All
CPU Utilization Spike Due to I/O Wait During MySQL Backup
CPU Utilization Spike Due to I/O Wait During MySQL Backup

CPU Utilization Spike Due to I/O Wait During MySQL Backup

The Deceptive Alert of CPU Saturation

For Database Administrators (DBAs) and Site Reliability Engineers (SREs), a high CPU utilization alert is one of the most common production pages. The immediate instinct when seeing a CPU graph pegged at near-maximum capacity is to investigate application queries, look for missing indexes, scale up compute resources, or check for transaction lock waits.

However, high CPU utilization metrics can be highly deceptive. An engine that appears to be consuming 100% of its compute resources might not actually be performing active calculations. Instead, the processor might spend the majority of its cycles completely idle, blocked while waiting for storage subsystems to retrieve data.

In database environments, this phenomenon is particularly common during heavy administrative tasks, such as scheduled daily physical backups. When application queries compete with the massive physical disk read operations generated by backup tools, storage bottlenecks can easily masquerade as compute bottlenecks.

This case study reviews a real-world incident where a MySQL replica server generated a critical CPU utilization alert, spiking to 95% during its scheduled backup window. We will walk through the underlying metrics, system performance baselines, and step-by-step diagnostic workflows that revealed the true root cause: extreme storage contention and high CPU I/O wait rather than actual CPU saturation.

Incident Overview: Environment & Timeline

To understand the context of the incident, we must first examine the operational environment and the exact sequence of events.

System Environment

  • Database Engine: MySQL 8.0
  • Server Role: Replica
  • Storage Medium: Solid State Drive (SSD)
  • Backup Utility: Percona XtraBackup
  • Backup Method: Full Physical Backup
  • Backup Schedule: 02:00 AM Daily

Incident Timeline

The following sequence of events occurred during the early morning backup window:

Incident Timeline Explorer

Interact with the incident timeline below to examine system diagnostic outputs and performance baselines at each stage of the physical backup.

01:58 Replica healthy
02:00 Backup started
02:03 Disk Reads increased rapidly
02:05 I/O Wait crossed 60%
02:06 CPU utilization reached 95%
02:08 Active Threads increased
02:12 Slow Queries reported
02:20 Backup completed
02:23 CPU returned to normal
Sys-Diagnostics Analyzer
HEALTHY
TIMESTAMP: 01:58 AM
Replica database engine is operating at baseline efficiency. Replication sync with the primary source is optimal. No query delays detected.
Metric Summary:
• Disk Latency: 4ms (Normal)
• Threads Running: 15
• CPU utilization: 20%

Initial Symptoms

CPU Utilization

95%
Status: High Threshold: 80%

CPU Utilization Over Time

CPU Utilization (%)
Threshold (80%)
100 80 60 40 20 Backup Window 05:00 - 08:00 Threshold: 80% 03:00 04:00 05:00 06:00 07:00 08:00 09:00

CPU Breakdown

100%
CPU Time
CPU State Percentage Telemetry Definition
User CPU 14% Time spent running user-space processes (MySQL operations)
System CPU 8% Time spent running kernel processes
IO Wait 73% Time spent waiting for storage I/O operations to complete
Idle 5% Time the CPU is idle and not performing any task
i

Core Insight: A high I/O Wait (73%) indicates that the database compute nodes are mostly sitting idle, waiting for the underlying storage subsystem to fulfill pending physical disk reads generated by the parallelized backup process.

At first this looked like CPU saturation.

After investigation:

CPU wasn't busy.

CPU was waiting.

3. The Core Metric: What is CPU I/O Wait?

I/O Wait (%wa) is the percentage of time that the CPU remains idle while there are outstanding disk or storage read and write operations. It is a subset of overall idle time, indicating that the processor has tasks ready to execute but is blocked because the required data has not yet been fetched from the storage device into memory.

What is I/O Wait?

The CPU performs work only when data is available. If MySQL requests a page from storage disk, the execution sequence behaves as follows:

CPU
The CPU intends to execute an operations thread or client query.
Needs Data
MySQL needs a specific tablespace page that is missing from active Buffer Pool memory. A read request is issued to the disk controller.
! Storage Busy
The storage controller queue is busy fulfilling consecutive administrative read processes (such as massive parallel physical backups).
CPU Waits
The execution threads are suspended and blocked. The CPU cannot complete calculations because raw data blocks are pending transfer into memory.
i

This waiting period is recorded in the operating system metrics as I/O Wait (%wa). While overall metrics might suggest extreme database CPU utilization, the processor is actually fully idle, sitting in wait cycles for the storage device to retrieve tablespace structures.

A high CPU utilization percentage driven primarily by I/O Wait is a classic signature of a storage bottleneck, not compute saturation. If application queries require data that resides on disk, and the disk is fully occupied with other tasks (such as a massive backup job), those queries wait, and the CPU spends its cycles in an idle waiting state.

Under the Hood: How Physical Backups Cause Storage Contention

Physical backup tools like Percona XtraBackup create database copies by reading raw data files directly from disk. To achieve a consistent snapshot, the tool sequentially scans all allocated tablespace files (such as ibdata1, individual .ibd tablespace files like orders.ibd or users.ibd, and active redo logs).

For larger datasets—for instance, an 800 GB database—the backup utility reads nearly the entire volume of data from the underlying storage. This process generates a massive, sustained sequence of read requests. Because the backup is highly parallelized (configured with --parallel=8 in this incident), it consumes the majority of the available Input/Output Operations Per Second (IOPS) and disk read bandwidth.

Disk I/O Telemetry Panel

System performance metrics mapped during the scheduled physical database backup window.

Backup Process Engine

ACTIVE
replica-db:~$ xtrabackup --backup --parallel=8 --target-dir=/backup/mysql/
ibdata1
COMPLETED
orders.ibd
SCANNING (450 GB)
users.ibd
QUEUED
redo logs
STREAMING ACTIVE
Active Thread Pool Allocations Workers: 8/8
T1
T2
T3
T4
T5
T6
T7
T8

Storage Subsystem Status

SATURATED
100% UTIL
  • Disk Read rate: 620 MB/s
  • Disk Latency: 55 ms
  • Average Wait (await): 48 ms
  • Queue Depth (aqu-sz): 27

ALERT: IO_WAIT_SATURATED
System execution threads are stalled. The storage array is fully saturated by background physical reads, increasing disk queue length.

At the same time, the replica server continues to process application read queries. If a query requests a data page that is not currently cached in the MySQL InnoDB Buffer Pool, MySQL must issue a read request to the same physical disk. Because the storage queue is already saturated with backup reads, the query wait times increase dramatically.

When the backup process shares the same storage as the database, it generates heavy disk reads that compete with application queries for I/O resources. As a result, database requests spend more time waiting for disk access, increasing I/O Wait (%wa). Although overall CPU utilization may appear high (90–95%), the CPU is primarily idle while waiting for storage operations to complete rather than actively processing queries. This storage contention leads to higher disk latency, larger I/O queues, increased active threads, slower query response times, and reduced overall database performance.

MySQL Issues a Disk I/O Request

Application Query : 

SELECT * FROM orders WHERE customer_id=100;

Required page : 

orders.ibd

But storage is already busy serving backup reads. So MySQL waits.

MySQL Disk I/O Processing Loop

When active queries request index or tablespace blocks absent from database cache memory, execution blocks until concurrent storage reading processes clear.

1. Application Query
SELECT * FROM orders
WHERE customer_id = 100;

The client application issues an incoming SQL read request for specific records.

2. Cache Miss
orders.ibd

The requested data tablespace page is not found cached in the InnoDB Buffer Pool.

3. I/O Dispatch

MySQL engine issues a physical read operation to fetch required datablocks from disk.

4. Storage Saturation

The disk pipeline is fully occupied handling high parallel raw backup scans.

5. MySQL Blocked

SQL query execution is suspended, waiting for disk reads to complete.

Impact:
High I/O Wait

CPU sits in idle loops

Latency Spikes

Query response times rise

Threads Stacking

Active thread counts rise

Observed System Metrics

CPU Utilization

Value: 95%

Description: Overall CPU usage reached 95%, but most of it was due to I/O Wait, indicating the CPU was waiting for disk operations rather than actively processing MySQL workloads.

CPU Utilization Overview

Last 6 Hours

CPU Utilization

95%
Current Load Alert

Metric Context

Overall CPU usage reached a peak of 95%, but detailed state metrics show the compute layers remained idle. High CPU readings were driven by pending storage reads rather than active MySQL workload execution.

CPU Utilization Over Time

100 80 60 40 20 03:00 04:00 05:00 06:00 08:00 09:00

CPU Breakdown (By State)

User CPU 14%
System CPU 8%
I/O Wait 73%
Idle 5%

Key Insight

Around 73% of CPU cycle blocks were dedicated strictly to waiting on storage controllers to return tablespace data blocks.

This queue stress restricted active query resolution pipelines, triggering temporary cascades in slow execution reports and thread accumulation.

I/O Wait

Value: 73%

Description: Around 73% of CPU time was spent waiting for storage I/O to complete, confirming that the storage subsystem had become the primary bottleneck during the backup.

I/O Wait Overview

Last 6 Hours

I/O Wait

73%
Value: 73%

Description

Around 73% of CPU execution blocks were spent waiting for storage system reads to resolve, confirming that physical storage device queuing was the primary performance bottleneck during the backup task.

I/O Wait Over Time

100 80 60 40 20 73% 03:00 04:00 05:00 06:00 08:00 09:00

CPU Breakdown (By State)

User CPU 14%
System CPU 8%
I/O Wait 73%
Idle 5%

Key Insight

High I/O Wait (73%) confirms that the storage subsystem was the primary bottleneck during the backup window.

Higher Query Response Time
Increased Active Threads

Disk Read Throughput

Normal: 80 MB/s
During Backup:
620 MB/s

Description: Disk read throughput increased nearly as the backup tool continuously scanned MySQL data files, consuming a significant portion of the available storage bandwidth.

Disk Read Throughput Console

Disk read throughput increases significantly during physical table space copy streams.

Normal (Before Backup)
80 MB/s
Average Baseline Read rate
During Backup
620 MB/s
Peak Saturated Read Rate
Disk Read Surge
Increase
Surge Ratio versus Baseline
MAX
Disk Read Throughput Over Time
700 500 300 100 0 Normal baseline: 80 MB/s Backup Average: 620 MB/s Backup Window 03:00 04:00 05:00 06:00 08:00 09:00
Description

Disk read throughput increased nearly as the backup tool continuously scanned database tablespace files. This extreme read rate heavily consumed the storage subsystem's available channel bandwidth.

Performance Impact
  • Extreme disk read activity significantly reduced available database I/O bandwidth.
  • MySQL read I/O operations experienced immediate latency inflation.
  • Directly caused high I/O Wait states and extended transaction execution latency.

Disk Latency

Before Backup: 4 ms
During Backup:
55 ms

Description: Disk latency increased from 4 ms to 55 ms, meaning each I/O request took significantly longer to complete, resulting in slower query execution and higher I/O Wait.

Disk Latency Telemetry Console

Disk block I/O processing times degrade significantly during high sequential read loads.

Latency is the time taken to complete a disk I/O request.
Before Backup
4 ms
Average Disk Block Latency
During Backup
55 ms
Average Disk Block Latency
Disk Latency Surge
13.8× Increase
Surge Ratio versus Baseline
MAX
Disk Latency Over Time
70 50 30 10 0 Before Backup: 4 ms During Backup: 55 ms Backup Window 03:00 04:00 05:00 06:00 08:00 09:00
Description

Disk read latency inflated from 4 ms to a peak of 55 ms. Each discrete read operation took substantially longer to complete, leading to immediate thread wait accumulation.

4ms
55ms
Performance Impact
  • Each disk I/O request takes significantly longer to resolve.
  • Active MySQL read queries experience highly inflated response times.
  • Database processes accrue prolonged execution stalls waiting on storage blocks.
  • Overall transactional query capacity degrades.

Overall Observation

The combined metrics clearly indicate that the backup process saturated the storage subsystem, leading to increased disk latency, higher I/O queues, and elevated CPU utilization driven primarily by I/O Wait, rather than actual CPU processing.

Overall Observation Console

The combined metrics indicate that the backup process saturated the storage subsystem, leading to increased disk latency, higher I/O queues, and elevated CPU utilization driven primarily by I/O Wait rather than active compute processing.

CPU Utilization

Compute Layer Load Status

95 %
User 14%
System 8%
IO Wait 73%

I/O Wait

CPU Stalled Waiting on Disk

73 %

Disk Throughput

Read Vol vs Baseline (80MB/s)

620 MB/s

Disk Latency

Block Wait vs Baseline (4ms)

55 ms
Chronological Chain of Events
1. Backup Executed
2. Storage Saturated
3. Latency Surge
4. High I/O Wait
5. Delayed Queries
Performance Metrics Breakdown
  • The massive 73% I/O Wait was the dominant component driving high CPU utilization alerts (95%).
  • Storage subsystem bottleneck increased average disk block response latency from 4 ms to 55 ms.
  • Queued disk operations caused outstanding storage queue depth to spike.
  • Delayed read operations triggered query execution stalls and increased the number of concurrent active threads.
  • Database replica transaction capacity degraded while replication streams remained intact.
i

Key Takeaway: The storage subsystem was the primary bottleneck during the backup window. The CPU spent most of its clock cycles idle waiting for disk block operations to resolve, confirmable by correlating I/O wait and queue depth metrics rather than raw compute utilization.

MySQL Metrics

Threads Running

Normal: 15
Peak:
76

Description: The number of active MySQL threads increased from 15 to 76, as queries waited longer for disk I/O to complete during the backup.

Threads Running Diagnostic Dashboard

Number of active database threads currently executing or waiting for storage resources.

Before Backup
15
Peak threads
76
Increase
5.1×
Threads Running Over Time
100 80 60 40 20 Normal Baseline: ~15 Threads Peak: 76 Threads (02:08 AM) 02:00 AM (Started) 02:20 AM (Completed) 01:45 01:55 02:00 02:10 02:15 02:20 02:30 02:35

Comparison

15 Normal 76 Peak 5.1×

Dial Gauge

76
Active Threads

Threads Summary

Baseline Avg 15
Backup Peak 76
Min Observed 12
Max Observed 81
Increase 5.1x
Impact High

Impact

  • Active threads stacked because reads waited longer for storage blocks.
  • Prolonged I/O waiting times resulted in high thread concurrency.
  • Confirms disk contention is the bottleneck, not compute or MySQL parser limits.
i

Key Takeaway: Active database threads increased sharply from 15 to 76 inside the backup window (5.1x increase). This confirms that user sessions stacked up waiting for storage reads to resolve, resulting in elevated concurrent connection states.

Slow Queries

Normal: 0
Peak:
145

Description: Slow queries increased from 0 to 145 because disk read latency increased, causing many queries to exceed the configured long_query_time.

Slow Queries Diagnostic Dashboard

Number of queries that exceeded the configured database long_query_time limit.

Before Backup
0
Peak slow queries
145
Increase
145×
Slow Queries Over Time
200 160 120 80 40 Normal Baseline: ~0 Slow Queries Peak: 145 Slow Queries (02:09 AM) 02:00 AM (Started) 02:20 AM (Completed) 01:45 01:55 02:00 02:10 02:15 02:20 02:30 02:35

Comparison

0 Normal 145 Peak 145×

Dial Gauge

145
Slow Queries

Slow Queries Summary

Baseline Avg 0
Backup Peak 145
Min Observed 0
Max Observed 162
Increase 145x
Impact High

Impact

  • Disk read latency increased, forcing execution times to exceed long_query_time.
  • Concurrent queries stacked, increasing thread concurrency and latency log entries.
  • Slower block operations drove up execution wait times on storage layers.
  • Degraded transactional throughput limits overall application capacity.
i

Key Takeaway: Slow queries increased sharply from 0 to 145 inside the backup window (145x increase). This confirms that user sessions stacked up waiting for storage reads to resolve, resulting in elevated concurrent connection states.

Buffer Pool Hit Ratio

Value: 99%

Description: The Buffer Pool Hit Ratio remained at 99%, indicating that most data requests were served from memory and the issue was not caused by poor cache efficiency, but by storage contention for pages that required disk access.

Buffer Pool Hit Ratio Console

Percentage of database read requests successfully served directly from memory cache.

Before Backup
99%
During Backup
99%
Change
~0%
Buffer Pool Hit Ratio Over Time
100% 99% 98% 97% 96% 02:00 AM (Started) 02:20 AM (Completed) Stable ~99% Hit Ratio No Cache Inefficiencies 01:45 01:55 02:00 02:10 02:15 02:20 02:30 02:35

Metric Details

Baseline Avg 99%
Backup Avg 99%
Min Observed 98.6%
Max Observed 99.5%
Change ~0%
Impact Optimal

Dial Gauge

99%
Cache Hit Ratio

What This Means

  • High hit ratio confirms most database reads are served directly from RAM.
  • Rules out Buffer Pool size or page replacement issues as a cause.
  • The remaining 1% of uncached disk reads stalled due to heavy parallel backup load.

Why This Matters

RAM
DISK

Memory cache hit rate is highly efficient. Stalls are driven solely by un-cached block reads waiting on disk channels.

i

Key Takeaway: Buffer Pool Hit Ratio stayed at 99% before, during, and after the backup. This confirms the operational workload remained fully resident in memory, and the latency spike was caused solely by physical storage contention, not memory-to-disk paging stalls.

Lock Waits

Value: None Observed

Description: No lock waits were detected, confirming that query delays were not caused by row-level or table-level locking.

Replication Status

Value: Healthy

Description: Replication remained healthy throughout the backup, with no significant replication lag or SQL thread delays observed.

Replication Status Console

Operational health and lag metrics of the replica database node during copy tasks.

Status
Healthy
Avg Lag
0 sec
Peak Lag
1 sec
Replication Lag Over Time
10s 8s 6s 4s 2s 0s 02:00 AM (Started) 02:20 AM (Completed) Replication remained healthy No delays observed 01:45 01:55 02:00 02:10 02:15 02:20 02:30 02:35

Summary Metrics

Status Healthy
IO Thread Running
SQL Thread Running
Peak Lag 1 sec
Avg Lag 0 sec
Relay Log Space Low

Status Gauge

0 10+
Healthy
No Replication Lag
(Seconds Behind Master ≤ 1)

Replication Details

  • IO Thread: Running
  • SQL Thread: Running
  • Avg Lag: 0 seconds

What This Means

  • The replica nodes are healthy and structurally stable.
  • No replication lag accumulated during high storage read stress.
  • SQL thread processing executed transactions without errors or delays.
  • Confirms physical backup load did not compromise replication durability.
i

Key Takeaway: Replication remained healthy throughout the backup, with no significant replication lag or SQL thread delays observed. Database durability was maintained while copy processes ran in parallel.

Deadlocks

Value: None Observed

Description: No deadlocks occurred during the incident, indicating that transaction conflicts were not a contributing factor.

Overall Observation

The MySQL metrics indicate that the database engine itself was functioning normally. The increase in Threads Running and Slow Queries was a direct consequence of storage I/O delays, while the absence of lock waits, deadlocks, and replication issues confirms that the root cause was disk contention introduced by the backup activity, rather than an internal MySQL locking or replication problem.

Sample Linux Evidence

CPU Utilization (top)

Description: The top output shows that only 14% of CPU time was spent executing user processes and 8% on system tasks, while 73% was consumed by I/O Wait, confirming that the CPU was primarily waiting for storage operations rather than processing MySQL workloads.

I/O Statistics (iostat -x 1)

Linux Diagnostic Telemetry (top)

Observing physical execution blockages directly via kernel CPU state dumps.

root@mysql-server:~ (top)
[root@mysql-server ~]# top - 14:32:01 up 5:42, 2 users, load average: 2.35, 2.41, 2.28 Tasks: 235 total, 2 running, 233 sleeping, 0 stopped, 0 zombie %Cpu(s): 14.0 us, 8.0 sy, 0.0 ni, 5.0 id, , 0.2 hi, 0.1 si, 0.0 st KiB Mem : 3282368 total, 19251236 used, 4687236 free, 8949396 buff/cache KiB Swap: 4194300 total, 0 used, 4194300 free. 12008052 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 12345 mysql 20 0 12.6g 2.1g 8560 S 4.1 6.6 32:15.42 mysqld 12346 mysql 20 0 12.6g 2.1g 8560 S 3.8 6.6 28:11.07 mysqld 12347 mysql 20 0 12.6g 2.1g 8560 S 3.5 6.6 25:47.11 mysqld 12348 mysql 20 0 12.6g 2.1g 8560 S 2.9 6.6 21:33.19 mysqld 12349 mysql 20 0 12.6g 2.1g 8560 S 2.6 6.6 19:15.58 mysqld 12350 mysql 20 0 12.6g 2.1g 8560 S 2.3 6.6 17:23.66 mysqld _|

14% User (us)

CPU time spent executing user-space database processes (such as MySQL query execution threads).

8% System (sy)

CPU time spent handling kernel-level tasks (such as socket connection management, interrupts, and I/O polling).

73% I/O Wait (wa)

Dominant Component. CPU time spent idle waiting for requested storage block reads/writes to complete.

5% Idle (id)

CPU time completely free, idle, and waiting for new threads to be scheduled in the execution queue.

Read Requests per Second (r/s)

Value: 950

Description: The storage device processed approximately 950 read requests per second, indicating an intensive read workload generated by the backup process.

Read Requests per Second (r/s)

Real-time disk reading speed measurements mapped during the parallel backup stream.

950
Requests / Second
root@db-server:~ (iostat)
[root@db-server ~]# iostat -x 1 Linux 4.18.0-425.el8.x86_64 (db-server) 05/20/2025 _x86_64_ (2 CPU) Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s r_await w_await aqu-sz rareq-sz wareq-sz sda 120.45 620102.45 15360.22 0.00 2.11 47.89 55.21 23.45 652.70 127.49 sdb 0.00 0.10 0.00 1.20 0.00 0.00 0.00 0.00 0.00 2.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device wsvctm asvctm %util sda 3.12 3.04 100.00 sdb 8.00 8.00 0.10 dm-0 0.00 0.00 0.00 _|
Metric r/s
Device sda
Read Requests / Sec 950
Workload Type Read Intensive
Sample Interval 1 second

Read Throughput (rkB/s)

Value: 620,000 kB/s (~620 MB/s)

Description: Disk read throughput reached approximately 620 MB/s, showing that the backup continuously scanned MySQL data files and heavily utilized the available storage bandwidth.

Read Throughput (rkB/s)

Direct storage read performance volume parsed during parallel full physical backup scanning.

620,000 kB/s
(~620 MB/s)
root@db-server:~ (iostat)
[root@db-server ~]# iostat -x 1 Linux 4.18.0-425.el8.x86_64 (db-server) 05/20/2025 _x86_64_ (2 CPU) Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s r_await w_await aqu-sz rareq-sz wareq-sz sda 950.29 120.45 15360.22 0.00 2.11 47.89 55.21 23.45 652.70 127.49 sdb 0.00 0.10 0.00 1.20 0.00 0.00 0.00 0.00 0.00 2.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device wsvctm asvctm %util sda 3.12 3.04 100.00 sdb 8.00 8.00 0.10 dm-0 0.00 0.00 0.00 _|
Metric rkB/s
Device sda
Throughput Volume 620,000kB/s
Approximate Speed ~620 MB/s
Sample Interval 1 second

Average Wait Time (await)

Value: 48 ms

Description: Each I/O request waited an average of 48 ms before completion, indicating increased storage latency due to heavy disk activity.

Average Wait Time (await)

Operational statistics showing average queue times before storage operations resolve.

48 ms
Diagnostic Reading
root@db-server:~ (iostat)
[root@db-server ~]# iostat -x 1 Linux 4.18.0-425.el8.x86_64 (db-server) 05/20/2025 _x86_64_ (2 CPU) Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s r_await w_await aqu-sz rareq-sz wareq-sz sda 950.29 120.45 620102.45 15360.22 0.00 2.11 55.21 23.45 652.70 127.49 sdb 0.00 0.10 0.00 1.20 0.00 0.00 0.00 0.00 0.00 2.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device wsvctm asvctm %util sda 3.12 3.04 100.00 sdb 8.00 8.00 0.10 dm-0 0.00 0.00 0.00 _|
Metric await
Definition Average Wait
Value 48 ms
Device sda
Type Read I/O
Interval 1 second

Service Time (svctm)

Value: 3 ms

Description: The storage device serviced each individual I/O request in approximately 3 ms, suggesting that the increased response time was mainly caused by queued requests rather than slow hardware.

Service Time (svctm)

Direct storage request processing benchmarks exclusive of queue wait delays.

3 ms
Metric Value
root@db-server:~ (iostat)
[root@db-server ~]# iostat -x 1 Linux 4.18.0-425.el8.x86_64 (db-server) 05/20/2025 _x86_64_ (2 CPU) Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s r_await w_await aqu-sz rareq-sz wareq-sz sda 950.29 120.45 620102.45 15360.22 0.00 2.11 47.89 55.21 23.45 652.70 127.49 sdb 0.00 0.10 0.00 1.20 0.00 0.00 0.00 0.00 0.00 2.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device asvctm %util sda 3.04 100.00 sdb 8.00 0.10 dm-0 0.00 0.00 _|
Metric svctm
Definition Service Time
Value 3 ms
Device sda
Type Read I/O
Interval 1 second

Disk Utilization (%util)

Value: 100%

Description: The storage device reached 100% utilization, confirming that it was fully occupied processing backup and database read requests with no spare I/O capacity available.

Disk Utilization (%util)

Operational workload percentage representing the total portion of time the storage unit remained busy.

100%
Utilization Level
root@db-server:~ (iostat)
[root@db-server ~]# iostat -x 1 Linux 4.18.0-425.el8.x86_64 (db-server) 05/20/2025 _x86_64_ (2 CPU) Device r/s w/s rkB/s wkB/s rrqm/s wrqm/s r_await w_await aqu-sz rareq-sz wareq-sz sda 950.29 120.45 620102.45 15360.22 0.00 2.11 47.89 55.21 23.45 652.70 127.49 sdb 0.00 0.10 0.00 1.20 0.00 0.00 0.00 0.00 0.00 2.00 0.00 dm-0 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Device wsvctm asvctm %util sda 3.12 3.04 100.00 sdb 8.00 8.00 0.10 dm-0 0.00 0.00 0.00 _|
Metric %util
Device sda
Utilization Level 100%
Type Utilization
Interval 1 second

Backup Process

ps -ef | grep xtrabackup
xtrabackup
--backup
--parallel=8

Backup Process Diagnostics (ps)

Inspecting parallel process thread spawning and execution parameters inside the Linux kernel table.

8 Workers
Active Parallel Workers
root@db-server:~ (ps)
[root@db-server ~]# ps -ef | grep xtrabackup UID PID PPID C STIME TTY TIME CMD root 31245 1 2 10:15 ? 00:00:05 xtrabackup --backup --parallel=8 \--target-dir=/backup/mysql/full \--datadir=/var/lib/mysql \--user=root \--password=****** \--compress \--compress-threads=8 \--log=/backup/mysql/full/xtrabackup.log root 31252 31245 98 10:15 ? 00:01:12 xtrabackup: Parallel worker 1 root 31253 31245 98 10:15 ? 00:01:11 xtrabackup: Parallel worker 2 root 31254 31245 98 10:15 ? 00:01:10 xtrabackup: Parallel worker 3 ... root 31259 31245 98 10:15 ? 00:01:09 xtrabackup: Parallel worker 8 root 31270 25789 0 10:15 pts/0 00:00:00 grep --color=auto xtrabackup _|
Utility xtrabackup
Parent PID 31245
Parallel Threads 8 Workers
Target Path /backup/mysql

Description: The process list confirmed that Percona XtraBackup was running with 8 parallel threads, generating sustained disk read operations that saturated the storage subsystem during the backup window.

Overall Observation

The Linux system metrics clearly indicate that the server was not CPU-bound. Instead, the backup process generated a high volume of disk reads, driving storage utilization to 100%, increasing I/O wait and disk latency, and ultimately causing the observed CPU spike due to storage contention.

MySQL Processlist

The SHOW FULL PROCESSLIST command was used during the incident to identify the state of active MySQL sessions while the backup was running.

SHOW FULL PROCESSLIST;
Id   Command   Time   State

235  Query     38     Sending data
241  Query     42     Sending data
248  Query     30     Waiting for disk

Active Sessions (Processlist)

Verifying connection pipeline waits and query status states inside the MySQL process table.

3 Stalled
Blocked Database Queries
mysql> (processlist)
mysql> SHOW FULL PROCESSLIST; +-----+-----------------+-----------+-------+---------+---------+---------------------------------+-----------------------+ | Id | User | Host | db | Command | Time | State | Info | +-----+-----------------+-----------+-------+---------+---------+---------------------------------+-----------------------+ | 1 | system user | | NULL | Connect | 1028642 | Waiting for thread to be killed | NULL | | 2 | event_scheduler | localhost | NULL | Daemon | 1028642 | Waiting on empty queue | NULL | | 3 | root | localhost | NULL | Query | 0 | starting | SHOW FULL PROCESSLIST |
| 235 | backup | 10.0.0.15 | NULL | Query | 38 | Sending data | NULL | | 241 | backup | 10.0.0.15 | NULL | Query | 42 | Sending data | NULL | | 248 | backup | 10.0.0.15 | NULL | Query | 30 | Waiting for disk | NULL |
| 259 | root | localhost | mysql | Query | 0 | init | SHOW STATUS | | 260 | root | localhost | mysql | Sleep | 12 | | NULL | | 261 | root | localhost | mysql | Sleep | 5 | | NULL | | 262 | root | localhost | mysql | Sleep | 7 | | NULL | | 263 | root | localhost | mysql | Sleep | 9 | | NULL | | 264 | root | localhost | mysql | Sleep | 3 | | NULL | +-----+-----------------+-----------+-------+---------+---------+---------------------------------+-----------------------+ 11 rows in set (0.00 sec) mysql>_|
State Sending data
State Waiting for disk
Execution Delay 30-42 sec
Impacted Sessions 3 Sessions

Query State

State: Sending data

Description: Multiple sessions were in the Sending data state, indicating that MySQL was actively retrieving rows for client queries. Although the name suggests data was being sent to clients, these queries were also waiting for data pages to be read from disk before they could continue processing.

Query Execution Time

Observed: 30–42 seconds

Description: Several queries had been running for 30–42 seconds, significantly longer than their normal execution time, indicating delays caused by slow disk I/O rather than CPU or lock contention.

Waiting for Disk

State: Waiting for disk

Description: One or more sessions entered the Waiting for disk state because the required data pages were not immediately available in memory and the storage subsystem was already busy servicing backup read requests.

Processlist Observation

Description: The process list showed an increasing number of active sessions waiting for data pages to be fetched from disk. Since the backup process was generating continuous sequential reads, application queries experienced longer wait times before their I/O requests could be serviced.

Why "Sending data" Doesn't Always Mean Network Activity

Description: Despite its name, the Sending data state does not necessarily mean MySQL is transmitting results to the client. It often indicates that MySQL is scanning tables, reading index pages, fetching rows from storage, or processing result sets. During the backup window, many queries remained in this state because they were waiting for disk reads to complete.

Overall Observation

The process list confirmed that MySQL itself was healthy and actively processing client requests. However, many sessions remained in Sending data or Waiting for disk for an extended period because the backup process had saturated the storage subsystem. This resulted in delayed query execution, increased Active Threads, and higher CPU I/O Wait, even though there were no lock waits, deadlocks, or replication issues.

Root Cause

  • The backup process generated sustained sequential disk reads.
  • Storage bandwidth became saturated.
  • Application queries had to wait for disk access.
  • CPU accumulated I/O Wait time.
  • Monitoring therefore reported high CPU utilization, although the processor itself was not executing significant work.

Investigation Using PMM (Percona Monitoring and Management)

The following steps were performed in PMM to identify the root cause of the CPU utilization spike during the backup window.

Step 1: Verify CPU Utilization

PMM Dashboard:

Home
   └── Nodes Overview
          └── CPU Usage

Observe the following metrics:

  • CPU Utilization (%)
  • User CPU
  • System CPU
  • I/O Wait

Finding:

CPU Utilization : 95%
I/O Wait        : 73%

Observation:

Although CPU utilization was high, most of the CPU time was spent in I/O Wait, indicating that the processor was waiting for storage operations rather than executing MySQL queries.

Step 2: Check Disk Performance

PMM Dashboard:

Node Summary
Disk Performance

Observe the following metrics:

  • Disk Read Throughput
  • Disk Write Throughput
  • Disk Utilization
  • Disk Latency

Finding:

Disk Reads : 620 MB/s
Disk Utilization : 100%
Latency : 55 ms

Observation:

Disk read throughput increased significantly after the backup started, saturating the storage subsystem.

Step 3: Analyze Disk Queue

PMM Dashboard

Node Summary
  Disk I/O

Observe the following metrics:

  • Queue Depth
  • Read IOPS
  • Read Requests

Finding

Queue Depth

Normal : 1
Peak : 27

Observation

The storage device accumulated pending I/O requests because it could not process incoming read operations quickly enough.

Step 4: Verify MySQL Activity

PMM Dashboard

MySQL Overview
MySQL Activity

Observe the following metrics:

  • Threads Running
  • Questions
  • Queries
  • Connections

Finding

Threads Running

Normal : 15
Peak : 76

Observation

The increase in running threads indicated that application queries were waiting longer for storage I/O.

Step 5: Review Slow Queries

PMM Dashboard

MySQL
Query Analytics (QAN)

Observe the following metrics:

  • Slow Queries
  • Query Response Time
  • Top Queries

Finding

Slow Queries

Peak : 145

Observation

The increase in slow queries coincided with the backup window, confirming that higher disk latency affected query execution.

Step 6: Verify InnoDB Metrics

PMM Dashboard

MySQL InnoDB Details

Observe the following metrics:

  • Buffer Pool Hit Ratio
  • Buffer Pool Reads
  • Buffer Pool Size

Finding

Buffer Pool Hit Ratio

99%

Observation

The Buffer Pool remained highly efficient, indicating that the issue was not caused by poor cache performance but by the small percentage of requests that required disk access.

Step 7: Correlate with Backup Window

PMM Dashboard

Annotations / Timeline / compare the graphs around the backup schedule.

Observation

At approximately 02:00 AM, the backup process started. Immediately after:

  • Disk Reads increased
  • Disk Utilization reached 100%
  • Disk Latency increased
  • I/O Wait increased
  • Threads Running increased
  • Slow Queries increased

All metrics returned to normal shortly after the backup completed.

Root Cause Identification Workflow

Root Cause Identification Workflow

Diagnostic path executed sequentially to verify and isolate memory-resident I/O latency bottlenecks.

1. CPU Alert Triggered
2. Check CPU Breakdown
3. High I/O Wait Found
4. Check Disk Performance
High Read Throughput
High Disk Utilization
High Disk Latency
6. Check MySQL Metrics
7. Threads Running ↑    Slow Queries ↑
8. Correlate with Backup
9. Root Cause Identified

Storage Contention Due to Physical Backup

Resolution

  • Backup completed successfully.
  • Disk utilization returned to normal.
  • I/O Wait decreased.
  • Active Threads reduced.
  • Query response times normalized.

No MySQL restart was required.

Recommendations

Short Term

  • Schedule backups during periods of lower application traffic.
  • Reduce backup parallelism if storage becomes saturated.
  • Continuously monitor iostat, disk latency, and CPU I/O Wait.

Long Term

  • Use faster storage (NVMe/Provisioned IOPS) for backup-intensive workloads.
  • Offload backups to a dedicated replica to isolate production traffic.
  • Consider incremental backups where appropriate to reduce read volume.
  • Review backup scheduling to avoid overlap with maintenance or reporting jobs.

Final Observations

  • The incident was a classic example of storage contention during backup activity, not CPU saturation.
  • High CPU utilization alone is insufficient to determine the root cause of a performance issue.
  • Correlating CPU metrics with storage metrics such as I/O Wait, disk latency, queue depth, and disk utilization provides a more accurate diagnosis.
  • Regular monitoring of system and MySQL performance metrics enables faster root cause identification and reduces troubleshooting time.
  • Proper backup scheduling and storage capacity planning are essential to minimize performance impact in production environments.

Are you struggling with performance slowdowns, high I/O wait, or replica lag during your backup windows? Our MySQL database engineering specialists are here to assist. At Mydbops, we provide proactive MySQL Managed Services and performance tuning to analyze your query workloads, optimize your backup parameters, and ensure your system maintains reliable recovery paths without impacting production traffic.

No items found.

About the Author

Subscribe Now!

Subscribe here to get exclusive updates on upcoming webinars, meetups, and to receive instant updates on new database technologies.

Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.