Under write-intensive transactional workloads—such as high-traffic WooCommerce, Magento, or custom ERP systems during promotional flash sales in Pakistan—MariaDB databases often suffer sudden, temporary lockups lasting between 1 and 5 seconds. Application logs report SQLSTATE[HY000] [2006] MySQL server has gone away or connection pool timeouts, while the MariaDB error log contains the dreaded message:
[Note] InnoDB: page_cleaner: 1000ms intended loop took 4120ms. The settings might not be optimal. (flushed=1840 and evicted=0, during the time.)
This stall indicates that InnoDB’s asynchronous page cleaner threads failed to flush dirty pages from the buffer pool to persistent storage at a pace matching inbound write velocity. When foreground user threads are forced to perform synchronous page flushing, client queries block completely. Hosting critical database workloads on NVMe-accelerated Dedicated Servers provides the raw IOPS needed, but software-level synchronization parameters must be tuned to eliminate page cleaner lag.
Understanding the InnoDB Flushing Architecture
InnoDB maintains data pages in memory within the innodb_buffer_pool. Modifications create “dirty pages” that reside in memory until flushed asynchronously to disk:
- Flush List Flushing: Writes dirty pages to the doublewrite buffer and tablespaces in checkpoint order so redo logs can be recycled.
- LRU (Least Recently Used) Flushing: Frees clean or flushed pages at the end of the buffer pool LRU list so incoming read queries can immediately allocate empty memory blocks.
If innodb_page_cleaners is under-allocated or innodb_lru_scan_depth is set too high, the page cleaner thread spends excessive time scanning thousands of pages across multiple buffer pool instances, missing its 1000ms scheduling deadline.
Diagnosing Page Cleaner Lag & Flushed Pages
Inspect MariaDB’s internal InnoDB engine status to assess flush contention and dirty page ratios:
SHOW ENGINE INNODB STATUS\G
Under the BUFFER POOL AND MEMORY section, monitor:
Buffer pool size: Total allocated pool pages.Free buffers: Available clean pages for immediate assignment.Modified db pages: Current count of dirty pages pending disk write.Pages flushed up to: LSN checkpoint advancement rate.
Query dirty page percentage directly via SQL:
SELECT
VARIABLE_VALUE AS Buffer_Pool_Pages_Total,
(SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty') AS Buffer_Pool_Pages_Dirty,
ROUND(((SELECT VARIABLE_VALUE FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_dirty') / VARIABLE_VALUE) * 100, 2) AS Dirty_Page_Percent
FROM information_schema.GLOBAL_STATUS
WHERE VARIABLE_NAME = 'Innodb_buffer_pool_pages_total';
If Dirty_Page_Percent consistently exceeds 25% or fluctuates violently, the page cleaner subsystem requires immediate re-synchronization.
Optimal InnoDB Page Cleaner Tuning Configuration
In modern MariaDB (versions 10.6, 10.11 LTS, and 11.4), configure innodb_page_cleaners to match the number of buffer pool instances (innodb_buffer_pool_instances), ensuring each memory pool has a dedicated cleaner thread.
Add to /etc/my.cnf.d/server.cnf (under [mariadb] or [mysqld]):
# /etc/my.cnf.d/server.cnf - High-Concurrency InnoDB Tuning for NextGen Nodes
# Buffer pool allocation (e.g., 64GB node dedicating 48GB to DB)
innodb_buffer_pool_size = 48G
innodb_buffer_pool_instances = 8
# Match page cleaners 1:1 with buffer pool instances
innodb_page_cleaners = 8
# Reduce LRU scan depth to prevent loop overruns on large pools
# Default is 1024 or 2048; set to 256 or 512 for fast scanning
innodb_lru_scan_depth = 512
# IO capacity tuned for enterprise NVMe arrays (adjust to match your drive capabilities)
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
# Adaptive flushing parameters
innodb_adaptive_flushing = ON
innodb_adaptive_flushing_lwm = 10.0
innodb_max_dirty_pages_pct = 70.0
innodb_max_dirty_pages_pct_lwm = 0.0
# Flush neighbor pages setting (0 for modern NVMe SSDs to prevent write amplification)
innodb_flush_neighbors = 0
# Purge thread parallelism
innodb_purge_threads = 4
Dynamic Runtime Application Without Downtime
Most of these parameters can be applied dynamically to a running MariaDB instance without restarting the service:
SET GLOBAL innodb_io_capacity = 4000;
SET GLOBAL innodb_io_capacity_max = 8000;
SET GLOBAL innodb_lru_scan_depth = 512;
SET GLOBAL innodb_flush_neighbors = 0;
SET GLOBAL innodb_adaptive_flushing = ON;
SET GLOBAL innodb_max_dirty_pages_pct = 70.0;
(Note: innodb_page_cleaners and innodb_buffer_pool_instances require a service restart if altered).
Verifying Resolution of Page Cleaner Warnings
After applying the configuration, monitor /var/log/mariadb/mariadb.log for 30 minutes under peak traffic:
tail -f /var/log/mariadb/mariadb.log | grep -i "page_cleaner"
The periodic 1000ms intended loop took XXXXms warnings will disappear.
For mission-critical ecommerce applications in Pakistan demanding sub-10ms query response times under high concurrency, deploying MariaDB on bare-metal Dedicated Servers in Pakistan provides the dedicated I/O queues and NVMe throughput necessary to sustain continuous, uninterrupted transaction flushing.
Scale Your Database Infrastructure with NextGen Dedicated Servers
Eliminate database lockups, page cleaner lag, and I/O bottlenecks. Deploy scalable MariaDB, MySQL, and PostgreSQL database clusters with high-IOPS NVMe storage.
Explore Pakistan Dedicated Servers