Under heavy transactional workloads—such as high-traffic WooCommerce checkout sprees, inventory bulk updates, or ERP journal entries in Pakistan—MariaDB databases frequently experience periodic throughput crashes. Every few minutes, database performance drops from 4,000 queries per second down to zero. Transactions freeze for 3 to 8 seconds before suddenly recovering, while application error logs report Lock wait timeout exceeded or MySQL server has gone away.
This erratic behavior is caused by Furious Flushing (or checkpoint stalls).
When InnoDB modified pages (“dirty pages”) in the buffer pool are not flushed to disk at a smooth, continuous rate matching the rate of new inbound writes, the circular InnoDB redo logs fill up. When the redo log reaches its synchronization capacity ceiling, MariaDB halts all active client transactions, forcing foreground threads to synchronously flush thousands of pages to disk before any new transaction can commit.
Hosting core databases on bare-metal Dedicated Servers provides massive NVMe storage bandwidth, but banishing checkpoint stalls permanently requires properly tuning InnoDB Adaptive Flushing and configuring sufficient redo log headroom.
Understanding the Redo Log Checkpoint Boundary
InnoDB’s Redo Log (ib_logfile0, ib_logfile1 or dynamic redo log files in modern MariaDB) records modifications sequentially to guarantee ACID durability in the event of a crash. Because the redo log is a circular ring buffer of fixed total size:
- LSN (Log Sequence Number): Tracks the total bytes written to the redo log since database inception.
- Checkpoint Age: The difference between the latest write LSN and the flushed checkpoint LSN: $$\text{Checkpoint Age} = \text{Log Sequence Number} - \text{Last Checkpoint at LSN}$$
- The Synchronization Ceiling (Furious Flushing):
- When Checkpoint Age is below 70% of total redo log capacity, flushing is asynchronous.
- When Checkpoint Age crosses 75% to 80%, the redo log is about to overwrite unflushed dirty pages. MariaDB triggers Synchronous Panic Flushing, halting all client transactions until the checkpoint moves forward!
Inbound Write Burst (4,000 TPS)
│
▼
[Redo Log Fills Rapidly]
│
┌───────────┴───────────────────────────┐
▼ ▼
Checkpoint Age < 70% Checkpoint Age > 75%
(Adaptive Flushing Active) (SYNCHRONOUS PANIC FLUSH!)
Background Page Cleaners Flush Smoothly All Client Transactions HALTED!
Throughput remains flat & stable. Latency jumps from 2ms to 6,000ms!
The Power of Adaptive Flushing: innodb_adaptive_flushing
Prior to adaptive flushing, InnoDB merely flushed pages based on a static dirty page percentage threshold (innodb_max_dirty_pages_pct). If a massive burst arrived, the dirty page percentage climbed too slowly to warn the flusher before the redo log ran out of space.
Adaptive Flushing (innodb_adaptive_flushing = ON):
- Dynamically monitors the speed at which the Redo Log is filling.
- Calculates the rate of LSN generation and page cleaner flush rates.
- Automatically scales up dirty page flushing to persistent NVMe storage long before the redo log approaches dangerous thresholds.
Step 1: Redo Log Sizing for High-Throughput Production
A common error on Pakistani database servers is leaving the redo log size at legacy defaults (e.g. two 48MB files = 96MB total). Under 50MB/s write activity, a 96MB redo log wraps around in less than 2 seconds, triggering continuous checkpoint stalls.
Calculate required redo log size:
$$\text{Target Redo Log Size} = \text{Peak Write Volume per Minute} \times 60 \text{ minutes}$$
On dedicated nodes processing high-volume ecommerce, configure at least 4GB to 8GB of total redo log space.
Edit /etc/my.cnf.d/server.cnf (under [mariadb] or [mysqld]):
# /etc/my.cnf.d/server.cnf - Adaptive Flushing & Redo Log Tuning
[mariadb]
# Expand redo log capacity (2 files x 4GB = 8GB total redo log headroom)
# In MariaDB 10.5+, this is set via innodb_log_file_size
innodb_log_file_size = 4G
innodb_log_files_in_group = 2
# Enable Adaptive Flushing
innodb_adaptive_flushing = ON
# Low Watermark (LWM): Trigger adaptive flushing early when redo log reaches 10% capacity
innodb_adaptive_flushing_lwm = 10.0
# Target dirty page percentage in buffer pool
innodb_max_dirty_pages_pct = 70.0
innodb_max_dirty_pages_pct_lwm = 0.0
# Scale background I/O capacity to match NVMe flash drives
innodb_io_capacity = 10000
innodb_io_capacity_max = 20000
# Flush neighbor pages disabled for flash SSDs
innodb_flush_neighbors = 0
# Page cleaners match buffer pool instances
innodb_buffer_pool_instances = 8
innodb_page_cleaners = 8
# Redo log buffer sizing (prevents log buffer flush locks)
innodb_log_buffer_size = 64M
Step 2: Applying Dynamic Settings Without Service Interruption
While altering innodb_log_file_size requires a controlled service restart, all adaptive flushing thresholds can be adjusted dynamically on a live running MariaDB server:
-- Apply live adaptive flushing optimizations immediately
SET GLOBAL innodb_adaptive_flushing = ON;
SET GLOBAL innodb_adaptive_flushing_lwm = 10.0;
SET GLOBAL innodb_max_dirty_pages_pct = 70.0;
SET GLOBAL innodb_max_dirty_pages_pct_lwm = 0.0;
SET GLOBAL innodb_io_capacity = 10000;
SET GLOBAL innodb_io_capacity_max = 20000;
SET GLOBAL innodb_flush_neighbors = 0;
Step 3: Monitoring Redo Log Checkpoint Age & Flushing Rates
Inspect MariaDB’s internal InnoDB engine status to ensure checkpoint age remains well below panic thresholds:
SHOW ENGINE INNODB STATUS\G
Under the LOG section, evaluate:
Log sequence number: Current LSN.Last checkpoint at: Checkpoint LSN.Checkpoint age: $\text{Log sequence number} - \text{Last checkpoint at}$.Max checkpoint age: The maximum capacity of the redo log before synchronous stalls occur.
---
LOG
---
Log sequence number 184920412850
Log flushed up to 184920412850
Pages flushed up to 184920391200
Last checkpoint at 184920210000
0 pending log flushes, 0 pending chkp writes
1841029 log i/o's done, 120.40 log i/o's/second
With innodb_adaptive_flushing = ON and lwm = 10.0, the difference between Log sequence number and Last checkpoint at will remain stable and smooth, eliminating checkpoint stalls entirely.
Hosting critical database instances on enterprise Dedicated Servers in Pakistan provides the high-IOPS NVMe flash storage, dedicated CPU processing cores, and low latency necessary to sustain massive transactional throughput with zero freeze spikes.
Eliminate Database Stalls with NextGen Dedicated Servers
Run demanding MariaDB, MySQL, and PostgreSQL transactional databases on bare-metal servers equipped with enterprise NVMe storage, adaptive flushing tuning, and 10Gbps connectivity in Pakistan.
Explore Pakistan Dedicated Servers