MariaDB a détruit le concept du buffer pool configurable dynamiquement !
Description du problème
MySQL a introduit le InnoDB buffer pool configurable dynamiquement dans la version 5.7.5 en septembre 2014 (ici et ici) :
The innodb_buffer_pool_size configuration option can be set dynamically using a SET statement, allowing you to resize the buffer pool without restarting the server. For example:
mysql> SET GLOBAL innodb_buffer_pool_size=402653184;
MariaDB 10.2.2 a repris cette fonctionnalité en septembre 2016 (source) :
InnoDB was merged from MySQL-5.7.14 (XtraDB is disabled in MariaDB-10.2.2 pending a similar merge)
Le problème est, d’une part, que cette fonctionnalité ne fonctionne plus comme avant et ne fonctionne plus comme prévu. D’autre part, ils ont modifié le comportement au printemps 2025 dans le cadre d’une série de versions majeures (LTS), ce qui, à mon avis, est absolument inacceptable (source) :
From MariaDB 10.11.12 / 11.4.6 / 11.8.2, there are significant changes to the InnoDB buffer pool behavior.
De plus, la description à ce sujet est assez maigre (source) :
- decreasing innodb_buffer_pool_size at runtime does not release memory (MDEV-32339)
- reorganise innodb buffer pool (and remove buffer pool chunks) (MDEV-29445)
- The Linux memory pressure interface, which could previously not be disabled and could cause performance anomalies, was rewritten and is disabled by default. (MDEV-34863)
- Server crashes when resizing default innodb buffer pool after setting innodb-buffer-pool-chunk-size to 1M (MDEV-34677)
Dans le journal de travail correspondant (MDEV-36197), MarkoM décrit également un autre comportement :
innodb_buffer_pool_size_auto_max (my proposal for this task) would set the maximum for the automation (default: 0 to disable the logic).
ce qui, à mon avis, aurait été beaucoup plus judicieux.
Comment cela fonctionnait-il auparavant ?
Comment cela fonctionnait-il auparavant avec MariaDB et comment cela fonctionne-t-il encore aujourd’hui avec MySQL :
SQL> SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool%size';
+-------------------------------+-----------+
| Variable_name | Value |
+-------------------------------+-----------+
| innodb_buffer_pool_chunk_size | 2097152 |
| innodb_buffer_pool_size | 134217728 |
+-------------------------------+-----------+
SQL> SET GLOBAL innodb_buffer_pool_size = @@innodb_buffer_pool_chunk_size * 128;
SQL> SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool%size';
+-------------------------------+-----------+
| Variable_name | Value |
+-------------------------------+-----------+
| innodb_buffer_pool_chunk_size | 2097152 |
| innodb_buffer_pool_size | 268435456 |
+-------------------------------+-----------+
Tout est donc OK. Cela fonctionne comme prévu et comme d’habitude.
Que fait MariaDB aujourd’hui ?
Que se passe-t-il aujourd’hui avec MariaDB :
SQL> SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool%size%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| innodb_buffer_pool_chunk_size | 0 |
| innodb_buffer_pool_size | 134217728 |
| innodb_buffer_pool_size_auto_min | 134217728 |
| innodb_buffer_pool_size_max | 134217728 |
+----------------------------------+-----------+
SQL> SET GLOBAL innodb_buffer_pool_size = 256*1024*1024;
Query OK, 0 rows affected, 1 warning (0.000 sec)
SQL> show warnings;
+---------+------+----------------------------------------------------------------+
| Level | Code | Message |
+---------+------+----------------------------------------------------------------+
| Warning | 1292 | Truncated incorrect innodb_buffer_pool_size value: '268435456' |
+---------+------+----------------------------------------------------------------+
SQL> SHOW GLOBAL VARIABLES LIKE 'innodb_buffer_pool%size%';
+----------------------------------+-----------+
| Variable_name | Value |
+----------------------------------+-----------+
| innodb_buffer_pool_chunk_size | 0 |
| innodb_buffer_pool_size | 134217728 |
| innodb_buffer_pool_size_auto_min | 134217728 |
| innodb_buffer_pool_size_max | 134217728 |
+----------------------------------+-----------+
Absolument rien ! Pas même une erreur, juste un avertissement. Et si je ne regarde pas attentivement, je ne remarque même pas que quelque chose n’a pas fonctionné.
Le journal d’erreurs MariaDB indique :
[Note] InnoDB: Memory pressure event disregarded; innodb_buffer_pool_size=128m, innodb_buffer_pool_size_auto_min=128m
En cherchant un peu, on découvre que quelque chose a changé ici : Buffer Pool Changes et on essaie intuitivement :
SQL> SET GLOBAL innodb_buffer_pool_size_max = 256*1024*1024;
ERROR 1238 (HY000): Variable 'innodb_buffer_pool_size_max' is a read only variable
Mais cela ne fonctionne pas non plus.
Cela signifie qu’il faut redémarrer la base de données ! Et cela peut arriver précisément au moment où l’on n’a pas besoin de redémarrer et où l’on aurait besoin de cette fonctionnalité…
La documentation indique également (source) :
Default Value: specified by the initial value of innodb_buffer_pool_size, rounded up to the block size of that variable. See the section about buffer pool changes in MariaDB 10.11.12, 11.4.6, and 11.8.2.
et (source):
If innodb_buffer_pool_size_max is 0 or not specified, it defaults to the innodb_buffer_pool_size value.
Cela signifie que je dois à nouveau réfléchir à l’avance à la taille que je dois donner à innodb_buffer_pool_size_max et que je ne peux corriger qu’après coup, si je l’ai oublié ou si je me suis trompé dans mon estimation.
À mon avis, il s’agit d’un véritable recul d’un point de vue opérationnel. Il s’agit probablement d’une nouvelle implémentation pour certaines solutions Cloud-only as a Service (Enterprise ?).
Ma suggestion est la suivante : soit, comme proposé dans MDEV, 0 désactive cette fonctionnalité et le comportement reste inchangé, soit la valeur par défaut est fixée à 75 % de la taille de la RAM, comme le fait innodb_dedicated_server dans MySQL.
J’ai pris la liberté d’ouvrir un bug ici : New InnoDB Buffer Pool autosize feature not so optimal implemented.
FedericoR a gentiment recommandé le lien suivant : Issues with new buffer pool configuration in MariaDB Minors (10.11.12/13/14, 11.4.6/7/8, 11.8.2/3). Je ne semble pas être le seul à avoir été contrarié par ce changement…
Comment PostgreSQL procède-t-il ?
PostgreSQL n’est actuellement pas (encore) en mesure de modifier dynamiquement les shared_buffers. La valeur par défaut est généralement de 128 Mo. Ici, la règle générale, similaire à celle de MyISAM, est de 25 à 40 % de la RAM. Cependant, l’absence de cette fonctionnalité n’est probablement pas si grave dans PostgreSQL, car PostgreSQL s’appuie fortement sur le cache du système de fichiers, tout comme MyISAM.
Source: Resource Consumption
Cette page a été traduite à l’aide de deepl.com.

