πŸ“ͺServer Runbook: MariaDB + PHP-FPM Performance Tuningtled

This document summarizes what we diagnosed, what we changed, why it helped, and how to check the same things again later.


1) Initial symptoms

From htop and later checks, the main issue was:

  • Disk IO saturation

  • High disk reads

  • Low CPU usage

  • Plenty of free RAM

That usually means the system is waiting on storage, not CPU or RAM.

What we saw

  • CPU load was low

  • RAM was mostly free

  • Disk usage was the main bottleneck

  • php-fpm workers were present, but not obviously too large

  • mariadbd memory usage looked too small for a busy database server on a 64 GB machine


2) Root cause

The main bottleneck was MariaDB, not PHP-FPM itself.

Why

MariaDB was configured with a very small InnoDB buffer pool:

It returned:

That is only 128 MB.

On a server with about 64 GB RAM, that is far too small for a production workload if the database is serving real traffic.

Effect of small InnoDB buffer pool

A small buffer pool means:

  • Hot table/index pages do not stay in memory

  • MariaDB must read from disk much more often

  • Disk becomes saturated

  • PHP requests wait on DB

  • Site feels slow even though CPU and RAM look fine


3) Process priority after diagnosis

First priority

  • mariadbd

Second priority

  • php-fpm: pool example.de

Why PHP-FPM was not the first fix

php-fpm workers were around 120 MB to 180 MB RSS each, which was acceptable on this machine.

The real issue was that PHP requests were driving expensive DB access while MariaDB had too little cache.


4) PHP-FPM facts we checked

Command

Result pattern

Workers were around:

  • 119 MB

  • 136 MB

  • 148 MB

  • 164 MB

  • 168 MB

  • 174 MB

  • 182 MB

This was not the primary issue.

PHP-FPM pool config we found

Relevant values:

Important note

When pm = ondemand, these settings are ignored:

  • pm.start_servers

  • pm.min_spare_servers

  • pm.max_spare_servers


5) MariaDB facts we checked

Check DB process memory

We saw MariaDB around:

  • RSS β‰ˆ 1.65 GB before tuning

That was suspiciously low for this server.

Check InnoDB buffer pool size

Before change:

After change:

That means:

  • Before: 128 MB

  • After: 8 GB


6) Buffer pool efficiency checks

Command

Before change

Approximate physical-read ratio:

That is high for a warm production InnoDB workload.

After change

Approximate physical-read ratio:

That is a major improvement.


7) Slow query we caught in processlist

We found an expensive MariaDB query through:

The query had several bad scaling patterns:

  • many LEFT JOIN

  • many OR clauses

  • many LIKE '%term%'

  • GROUP BY

  • HAVING

  • ORDER BY

  • ranking/scoring calculation in SQL

Why that is expensive

Queries using:

usually cannot use normal indexes efficiently because of the leading wildcard.

That forces scans and increases disk reads.


8) MariaDB change we made

We created a dedicated MariaDB tuning file.

File

Content


9) Command used to create/update the tuning file


10) Restart MariaDB

Verify service health

Expected good signs:

  • active (running)

  • ready for connections

  • no restart loop


11) Verify new buffer pool size

Expected:


12) Check server RAM before/after

Useful for confirming there is enough headroom.

In our case, the machine had plenty of free/available memory, so increasing MariaDB cache was appropriate.


13) Check MariaDB runtime memory usage

Important note

Even after setting innodb_buffer_pool_size = 8G, MariaDB RSS may not instantly show the full amount immediately after restart.

That is normal. It often grows as the workload warms the cache.


14) Disk IO check command

What to watch

  • %util

  • await

  • r/s

  • rkB/s

  • w/s

  • wkB/s

  • overall %iowait

Before tuning

Symptoms looked like:

  • very high disk read pressure

  • disk near saturation

  • htop showed disk 100%

After tuning

We saw:

  • much lower iowait

  • much lower %util

  • much lower read pressure

That confirmed the MariaDB cache increase helped.


15) Enable and verify slow query log

Check if slow query logging is enabled

Expected values:

  • slow_query_log = ON

  • long_query_time = 1

  • slow_query_log_file = /var/log/mysql/mariadb-slow.log


16) Fix slow log path if the file does not exist

Create directory and file

Restart MariaDB after that

Verify


17) Test slow query log manually

A safe test query:

Because long_query_time = 1, this should appear in the slow query log.

Read the last entries

Live watch


18) Useful slow-query workflow

Open one terminal and run:

Then reproduce slow actions in the application, for example:

  • customer search

  • order search

  • slow admin pages

  • imports

  • scheduled tasks

Then copy the resulting query block for analysis.

What to look for in slow queries

  • high Query_time

  • high Rows_examined

  • many LEFT JOIN

  • many LIKE '%...%'

  • many OR

  • GROUP BY

  • HAVING

  • ORDER BY


19) Command to inspect active running queries

This helps when the system is slow right now and you want to catch the live query.


20) Optional: lower slow-query threshold temporarily

If the app still feels slow but nothing interesting appears in the slow log, lower the threshold briefly:

Check it:

Set it back later:

Note: SET GLOBAL applies until restart unless persisted in config.


21) Commands used to inspect PHP-FPM settings

Show PHP-FPM worker sizes

Show pool config values

Validate PHP-FPM config after changes

Reload PHP-FPM

Check PHP-FPM service


We did not apply this yet, but this was the recommended next-step tuning once MariaDB was stabilized.

Suggested PHP-FPM pool config

Why

  • keeps a few workers warm

  • avoids excessive process churn from ondemand

  • limits concurrency a bit more conservatively than 20 workers

  • helps avoid overloading MariaDB with too many simultaneous requests


23) Suggested PHP-FPM change procedure for later

Backup config

Edit config

Test config

Reload service


24) Revert MariaDB tuning if needed

If you need to revert:

Option A: remove custom tuning file

Option B: edit and reduce the values


25) Revert PHP-FPM tuning if needed later


26) Health-check command set for future troubleshooting

Use this group together when the server feels slow:

General memory

Disk IO

MariaDB memory + CPU

PHP-FPM memory

InnoDB buffer pool size

InnoDB read efficiency

Slow query log status

Live slow queries

Active DB queries

MariaDB service status

PHP-FPM service status


27) Summary of what was actually done

We identified

  • Disk IO was the main bottleneck

  • MariaDB had an extremely undersized InnoDB buffer pool (128M)

  • A heavy search query pattern was contributing to DB load

  • PHP-FPM was not the first root cause

We changed

  • innodb_buffer_pool_size from 128M to 8G

  • enabled slow query logging

  • created/fixed the slow query log path

Result

  • disk pressure dropped significantly

  • iowait improved

  • InnoDB physical-read ratio improved

  • MariaDB became much less likely to force disk reads for hot data


  1. Keep slow query log running during real traffic

  2. Capture the real expensive queries from the app

  3. Review customer/admin search behavior

  4. Tune PHP-FPM pool only after DB behavior is confirmed stable

  5. If needed later, consider raising innodb_buffer_pool_size further to 12G if DB workload remains heavy and RAM stays comfortable


29) One-line conclusion

The biggest fix was increasing MariaDB's InnoDB buffer pool from 128 MB to 8 GB, because the server was disk-bound due to under-cached database reads, not CPU or raw PHP memory pressure.

Last updated