Skip to content

Commit ac00fd0

Browse files
committed
fix(mysql-innodb-log-waits): stop alerting on write log efficiency
Per the MariaDB InnoDB source, only Innodb_log_waits (log_sys.waits, incremented on the WRITE_BACKOFF path; srv0mon.cc labels it "Number of log waits due to small log buffer") signals a too-small log buffer. The write log efficiency ratio Innodb_log_writes / Innodb_log_write_requests reflects group commit / innodb_flush_log_at_trx_commit batching, not buffer capacity, so raising innodb_log_buffer_size cannot improve it. MySQLTuner alerts and recommends a bigger buffer when that ratio drops below 90%; this plugin now deviates deliberately and treats write log efficiency as informational only, alerting solely on log waits. The deviation is documented in the source, DESCRIPTION and README. The Director basket is regenerated via build-basket --auto.
1 parent a5d8a4a commit ac00fd0

4 files changed

Lines changed: 84 additions & 57 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Monitoring Plugins:
3535
* disk-io: per-disk performance data now reports read/write throughput per second and disk busy percentage as ready-to-graph values instead of raw cumulative counters; re-import the disk-io Grafana dashboard after updating ([#320](https://github.com/Linuxfabrik/monitoring-plugins/issues/320))
3636
* disk-usage: mountpoints are now filtered with `--match` and `--ignore`, consistent with the other plugins; the previous `--include-pattern`/`--include-regex`/`--exclude-pattern`/`--exclude-regex` options keep working unchanged
3737
* docker-stats, podman-stats: containers can now be selected or excluded by name with `--match` / `--ignore`, consistent with the docker-container/podman-container checks, and `--no-match-severity` sets the state when nothing matches
38+
* mysql-innodb-log-waits: no longer warns on a low InnoDB write log efficiency, which does not actually indicate an undersized log buffer and cannot be improved by raising `innodb_log_buffer_size`; the check now alerts only on real InnoDB log waits, so the buffer-size recommendation appears only when it will help
3839
* mysql-logfile: documents that `--ignore-pattern`/`--ignore-regex` match against the lowercased log line, and shows how to silence the harmless idle-connection-timeout warning (server closing an idle connection after `wait_timeout`) without hiding real connection errors
3940
* podman-info, podman-stats: gained `--user` to report on a specific rootless user's Podman. Running these checks as root only sees root's own containers, so use `--user` for rootless setups (running via sudo does not cover other users)
4041
* snmp: `--device` now also accepts an absolute path, so the OID definition CSV can be stored outside the plugin directory ([#1308](https://github.com/Linuxfabrik/monitoring-plugins/issues/1308))

check-plugins/mysql-innodb-log-waits/README.md

Lines changed: 36 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,23 +3,27 @@
33

44
## Overview
55

6-
Checks two related InnoDB log buffer health metrics in MySQL/MariaDB:
6+
Checks InnoDB redo log buffer health in MySQL/MariaDB:
77

8-
1. **Log waits** (`Innodb_log_waits` / `Innodb_log_writes`) - how often InnoDB had to wait for log writes to be flushed because the log buffer was full. Anything above 0% indicates that `innodb_log_buffer_size` is too small for the write workload.
9-
2. **Write log efficiency** (`(Innodb_log_write_requests - Innodb_log_writes) / Innodb_log_write_requests * 100`) - how many log write requests were absorbed by the buffer without needing a physical disk write. Below 90% indicates `innodb_log_buffer_size` is too small for the write workload.
8+
1. **Log waits** (`Innodb_log_waits` / `Innodb_log_writes`) - how often InnoDB had to wait because the in-memory log buffer was full before its contents could be flushed to disk. Per the MariaDB InnoDB source this counter is the authoritative signal for an undersized log buffer ("Number of log waits due to small log buffer"). Anything above 0 means `innodb_log_buffer_size` was too small for the write workload at some point. This is the only metric the plugin alerts on.
9+
2. **Write log efficiency** (`(Innodb_log_write_requests - Innodb_log_writes) / Innodb_log_write_requests * 100`) - the share of in-memory log appends that were batched into a shared physical write. This ratio is governed by group commit and `innodb_flush_log_at_trx_commit`, not by buffer size, so the plugin reports it for trending only. It never alerts and never recommends resizing the buffer.
10+
11+
**Deliberate deviation from MySQLTuner:**
12+
13+
The check logic is derived from MySQLTuner, which alerts and recommends increasing `innodb_log_buffer_size` whenever write log efficiency drops below 90%. The MariaDB InnoDB source does not support that link: only `Innodb_log_waits` reflects a too-small buffer, while the write efficiency ratio reflects commit/flush batching. This plugin therefore treats write log efficiency as informational only and alerts solely on log waits.
1014

1115
**Important Notes:**
1216

1317
* See [additional notes for all mysql monitoring plugins](https://linuxfabrik.github.io/monitoring-plugins/plugins-mysql/)
1418
* If the InnoDB engine is not available or is disabled, the plugin reports OK with an info message instead of UNKNOWN
15-
* The Write Log efficiency check is silently skipped on MySQL versions that do not expose `Innodb_log_write_requests` (very old MySQL pre-5.0)
16-
* When `Innodb_log_writes > Innodb_log_write_requests` (a physically impossible state that can briefly appear during counter resets), the plugin emits an info note instead of alerting
19+
* The Write Log efficiency line is silently skipped on MySQL versions that do not expose `Innodb_log_write_requests` (very old MySQL pre-5.0)
20+
* When `Innodb_log_writes > Innodb_log_write_requests` (a physically impossible state that can briefly appear during counter resets), the plugin emits an info note instead of a value
1721

1822
**Data Collection:**
1923

2024
* Queries `SHOW GLOBAL VARIABLES` for `innodb_log_buffer_size`
2125
* Queries `SHOW GLOBAL STATUS` for `Innodb_log_waits`, `Innodb_log_writes` and `Innodb_log_write_requests`
22-
* Logic is taken from [MySQLTuner](https://github.com/major/MySQLTuner-perl):mysql_innodb() (sections "InnoDB Log Waits" and "InnoDB Write Log efficiency") and has been verified in sync with MySQLTuner
26+
* Logic is derived from [MySQLTuner](https://github.com/major/MySQLTuner-perl):mysql_innodb() (sections "InnoDB Log Waits" and "InnoDB Write Log efficiency"), with the deliberate deviation on write log efficiency described above
2327

2428

2529
## Fact Sheet
@@ -43,15 +47,24 @@ usage: mysql-innodb-log-waits [-h] [-V] [--always-ok]
4347
[--defaults-group DEFAULTS_GROUP]
4448
[--timeout TIMEOUT]
4549
46-
Checks two related InnoDB log buffer metrics in MySQL/MariaDB: 1. **Log
47-
waits** (`Innodb_log_waits` / `Innodb_log_writes`) - how often InnoDB had to
48-
wait for log writes to be flushed because the log buffer was full. Anything
49-
above 0% indicates that `innodb_log_buffer_size` is too small for the write
50-
workload. 2. **Write log efficiency** ((`Innodb_log_write_requests` -
51-
`Innodb_log_writes`) / `Innodb_log_write_requests` * 100) - how many log write
52-
requests were absorbed by the buffer without needing a physical disk write.
53-
Below 90% indicates `innodb_log_buffer_size` is too small for the write
54-
workload. Alerts on either condition.
50+
Checks InnoDB redo log buffer health in MySQL/MariaDB. Primary check - **Log
51+
waits** (`Innodb_log_waits` / `Innodb_log_writes`): how often InnoDB had to
52+
wait because the in-memory log buffer was full before its contents could be
53+
flushed to disk. Per the MariaDB InnoDB source this counter is the
54+
authoritative signal for an undersized log buffer ("Number of log waits due to
55+
small log buffer"). Any value above 0 means `innodb_log_buffer_size` was too
56+
small for the write workload at some point, so the plugin alerts and
57+
recommends a larger buffer. Secondary informational metric - **Write log
58+
efficiency** ((`Innodb_log_write_requests` - `Innodb_log_writes`) /
59+
`Innodb_log_write_requests` * 100): the share of in-memory log appends that
60+
were batched into a shared physical write. This ratio is governed by group
61+
commit and `innodb_flush_log_at_trx_commit`, not by buffer size, so the plugin
62+
reports it for trending but never alerts on it and never recommends resizing
63+
the buffer based on it. Deliberate deviation from MySQLTuner: MySQLTuner
64+
alerts and recommends increasing `innodb_log_buffer_size` whenever write log
65+
efficiency drops below 90%. The MariaDB InnoDB source does not support that
66+
link, so this plugin treats write log efficiency as informational only and
67+
alerts solely on log waits.
5568
5669
options:
5770
-h, --help show this help message and exit
@@ -80,23 +93,26 @@ Output:
8093
```text
8194
InnoDB log waits: 0.0% (0.0 waits / 867.6K writes).
8295
83-
InnoDB Write Log efficiency: 95.6% (12.5M log buffer hits / 13.1M total).
96+
InnoDB Write Log efficiency: 95.6% (12.5M batched / 13.1M log write requests).
8497
```
8598

86-
When the buffer is undersized:
99+
When the buffer is undersized (only log waits trigger a WARNING; write log efficiency stays informational):
87100

88101
```text
89-
InnoDB log waits: 0.05% (450.0 waits / 867.6K writes) [WARNING]. Set `innodb_log_buffer_size` > 16.0MiB.
102+
InnoDB log waits: 0.05% (450.0 waits / 867.6K writes) [WARNING].
103+
104+
InnoDB Write Log efficiency: 82.3% (5.2M batched / 6.3M log write requests).
90105
91-
InnoDB Write Log efficiency: 82.3% (5.2M log buffer hits / 6.3M total) [WARNING]. Set `innodb_log_buffer_size` > 16.0MiB.
106+
Recommendations:
107+
* Set `innodb_log_buffer_size` > 16.0MiB
92108
```
93109

94110

95111
## States
96112

97113
* WARN if `Innodb_log_waits > 0` (any wait at all means the buffer was too small at some point).
98-
* WARN if InnoDB Write Log efficiency is below 90%.
99114
* OK if the InnoDB engine is not available or is disabled.
115+
* Write Log efficiency is informational only and never changes the state.
100116
* `--always-ok` suppresses all alerts and always returns OK.
101117

102118

check-plugins/mysql-innodb-log-waits/icingaweb2-module-director/mysql-innodb-log-waits.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@
8080
"tpl-service-generic"
8181
],
8282
"max_check_attempts": 5,
83-
"notes": "Checks two related InnoDB log buffer metrics in MySQL/MariaDB: 1. **Log waits** (`Innodb_log_waits` / `Innodb_log_writes`) - how often InnoDB had to wait for log writes to be flushed because the log buffer was full. Anything above 0% indicates that `innodb_log_buffer_size` is too small for the write workload. 2. **Write log efficiency** ((`Innodb_log_write_requests` - `Innodb_log_writes`) / `Innodb_log_write_requests` * 100) - how many log write requests were absorbed by the buffer without needing a physical disk write. Below 90% indicates `innodb_log_buffer_size` is too small for the write workload. Alerts on either condition.",
83+
"notes": "Checks InnoDB redo log buffer health in MySQL/MariaDB. Primary check - **Log waits** (`Innodb_log_waits` / `Innodb_log_writes`): how often InnoDB had to wait because the in-memory log buffer was full before its contents could be flushed to disk. Per the MariaDB InnoDB source this counter is the authoritative signal for an undersized log buffer (\"Number of log waits due to small log buffer\"). Any value above 0 means `innodb_log_buffer_size` was too small for the write workload at some point, so the plugin alerts and recommends a larger buffer. Secondary informational metric - **Write log efficiency** ((`Innodb_log_write_requests` - `Innodb_log_writes`) / `Innodb_log_write_requests` * 100): the share of in-memory log appends that were batched into a shared physical write. This ratio is governed by group commit and `innodb_flush_log_at_trx_commit`, not by buffer size, so the plugin reports it for trending but never alerts on it and never recommends resizing the buffer based on it. Deliberate deviation from MySQLTuner: MySQLTuner alerts and recommends increasing `innodb_log_buffer_size` whenever write log efficiency drops below 90%. The MariaDB InnoDB source does not support that link, so this plugin treats write log efficiency as informational only and alerts solely on log waits.",
8484
"notes_url": "https://linuxfabrik.github.io/monitoring-plugins/check-plugins/mysql-innodb-log-waits/",
8585
"object_name": "tpl-service-mysql-innodb-log-waits",
8686
"object_type": "template",

check-plugins/mysql-innodb-log-waits/mysql-innodb-log-waits

Lines changed: 46 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,27 @@ import lib.human
2121
from lib.globals import STATE_OK, STATE_UNKNOWN, STATE_WARN
2222

2323
__author__ = 'Linuxfabrik GmbH, Zurich/Switzerland'
24-
__version__ = '2026060201'
25-
26-
DESCRIPTION = """Checks two related InnoDB log buffer metrics in MySQL/MariaDB:
27-
1. **Log waits** (`Innodb_log_waits` / `Innodb_log_writes`) - how often InnoDB had to wait for
28-
log writes to be flushed because the log buffer was full. Anything above 0% indicates that
29-
`innodb_log_buffer_size` is too small for the write workload.
30-
2. **Write log efficiency** ((`Innodb_log_write_requests` - `Innodb_log_writes`) /
31-
`Innodb_log_write_requests` * 100) - how many log write requests were absorbed by the buffer
32-
without needing a physical disk write. Below 90% indicates `innodb_log_buffer_size` is too
33-
small for the write workload.
34-
Alerts on either condition."""
24+
__version__ = '2026070101'
25+
26+
DESCRIPTION = """Checks InnoDB redo log buffer health in MySQL/MariaDB.
27+
28+
Primary check - **Log waits** (`Innodb_log_waits` / `Innodb_log_writes`): how often InnoDB had to
29+
wait because the in-memory log buffer was full before its contents could be flushed to disk. Per
30+
the MariaDB InnoDB source this counter is the authoritative signal for an undersized log buffer
31+
("Number of log waits due to small log buffer"). Any value above 0 means `innodb_log_buffer_size`
32+
was too small for the write workload at some point, so the plugin alerts and recommends a larger
33+
buffer.
34+
35+
Secondary informational metric - **Write log efficiency** ((`Innodb_log_write_requests` -
36+
`Innodb_log_writes`) / `Innodb_log_write_requests` * 100): the share of in-memory log appends that
37+
were batched into a shared physical write. This ratio is governed by group commit and
38+
`innodb_flush_log_at_trx_commit`, not by buffer size, so the plugin reports it for trending but
39+
never alerts on it and never recommends resizing the buffer based on it.
40+
41+
Deliberate deviation from MySQLTuner: MySQLTuner alerts and recommends increasing
42+
`innodb_log_buffer_size` whenever write log efficiency drops below 90%. The MariaDB InnoDB source
43+
does not support that link, so this plugin treats write log efficiency as informational only and
44+
alerts solely on log waits."""
3545

3646
DEFAULT_DEFAULTS_FILE = '/var/spool/icinga2/.my.cnf'
3747
DEFAULT_DEFAULTS_GROUP = 'client'
@@ -112,10 +122,20 @@ def get_status(conn):
112122
def main():
113123
"""The main function. This is where the magic happens."""
114124

115-
# logic taken from mysqltuner.pl:mysql_innodb(), sections "InnoDB Write Log
116-
# efficiency" and "InnoDB Log Waits", verified in sync with MySQLTuner
117-
# (the < 90% write-efficiency threshold and the "any waits at all" log-wait
118-
# threshold are unchanged upstream since the original port).
125+
# Logic derived from mysqltuner.pl:mysql_innodb(), sections "InnoDB Write Log
126+
# efficiency" and "InnoDB Log Waits". Deliberate deviation from MySQLTuner:
127+
# only `Innodb_log_waits > 0` alerts and recommends a larger
128+
# `innodb_log_buffer_size`. Per the MariaDB InnoDB source, `Innodb_log_waits`
129+
# (`log_sys.waits`, incremented only on the WRITE_BACKOFF path when an append
130+
# must wait for a full buffer) is the sole counter that signals a too-small
131+
# log buffer - srv0mon.cc labels it "Number of log waits due to small log
132+
# buffer". The Write Log efficiency ratio Innodb_log_writes /
133+
# Innodb_log_write_requests instead measures how many in-memory log appends
134+
# were batched into a shared physical write (group commit /
135+
# `innodb_flush_log_at_trx_commit` behavior), which is unrelated to buffer
136+
# capacity. MySQLTuner alerts and recommends a bigger buffer when that ratio
137+
# drops below 90%; since the source does not support that, we emit it as an
138+
# informational metric only.
119139

120140
# parse the command line
121141
try:
@@ -188,10 +208,13 @@ def main():
188208
else:
189209
sections.append(f'{log_waits_msg}.')
190210

191-
# 2. InnoDB Write Log efficiency: only computable when the server exposes
192-
# `Innodb_log_write_requests` (older MySQL did not). mysqltuner emits a
193-
# "metrics not reliable" infoprint when `writes > write_requests` (which
194-
# cannot happen physically); we mirror that as an info line.
211+
# 2. InnoDB Write Log efficiency: informational only. Unlike MySQLTuner (see
212+
# the note at the top of main()) this never alerts and never recommends a
213+
# larger buffer, because the ratio reflects group commit /
214+
# `innodb_flush_log_at_trx_commit` batching, not buffer capacity. Only
215+
# computable when the server exposes `Innodb_log_write_requests` (older
216+
# MySQL did not). `writes > write_requests` cannot happen physically and
217+
# briefly appears only during counter resets, so it is reported as info.
195218
if log_write_requests is not None:
196219
if log_write_requests == 0:
197220
sections.append(
@@ -207,25 +230,12 @@ def main():
207230
pct_write_eff = round(
208231
(log_write_requests - log_writes) / log_write_requests * 100, 1
209232
)
210-
absorbed = log_write_requests - log_writes
211-
eff_msg = (
233+
batched = log_write_requests - log_writes
234+
sections.append(
212235
f'InnoDB Write Log efficiency: {pct_write_eff}%'
213-
f' ({lib.human.number2human(absorbed)} log buffer hits /'
214-
f' {lib.human.number2human(log_write_requests)} total)'
236+
f' ({lib.human.number2human(batched)} batched /'
237+
f' {lib.human.number2human(log_write_requests)} log write requests).'
215238
)
216-
if pct_write_eff < 90:
217-
state = lib.base.get_worst(state, STATE_WARN)
218-
sections.append(
219-
f'{eff_msg}{lib.base.state2str(STATE_WARN, prefix=" ")}.'
220-
)
221-
rec = (
222-
f'Set `innodb_log_buffer_size` >'
223-
f' {lib.human.bytes2human(log_buffer_size)}'
224-
)
225-
if rec not in recommendations:
226-
recommendations.append(rec)
227-
else:
228-
sections.append(f'{eff_msg}.')
229239

230240
# build the message
231241
if recommendations:

0 commit comments

Comments
 (0)