Un serveur de réplication esclave crée deux autres petits fichiers dans le dossier de données. Ces fichiers sont appelés master.info et relay-log.info par défaut :

  • Le fichier master.info est modifié par le thread d'I/O.
  • Le fichier relay-log.info est modifié par le thread SQL.

Un log de relais est automatiquement effacé par le thread SQL aussitôt qu'il n'en a plus besoin : c'est à dire aussitôt qu'il en a exécuté les commandes. Il n'y a pas de commande pour effacer les logs de relais, car le thread SQL se charge de le faire.

Problème rencontré : RELAY_LOG_PURGE "OFF", saturation du disque à cause des fichiers relay-bin non supprimés

Par exemple, suite à disque plein, on peut lire dans le fichier d'erreur : myhostname.err

120909  4:49:07 [ERROR] /usr/sbin/mysqld: Disk is full writing './m_database/my_table.TMD' (Errcode: 28). Waiting for someone to free space... (Expect up to 60 secs delay for server to continue after freeing disk space)
120909  4:49:07 [ERROR] /usr/sbin/mysqld: Retry in 60 secs. Message reprinted in 600 secs
120909  4:49:09 [ERROR] /usr/sbin/mysqld: Disk is full writing './myhostname-relay-bin.000984' (Errcode: 28). Waiting for someone to free space... (Expect up to 60 secs delay for server to continue after freeing disk space)
120909  4:49:09 [ERROR] /usr/sbin/mysqld: Retry in 60 secs. Message reprinted in 600 secs
120909  4:51:09 [ERROR] /usr/sbin/mysqld: Disk is full writing './myhostname-relay-bin.000984' (Errcode: 28). Waiting for someone to free space... (Expect up to 60 secs delay for server to continue after freeing disk space)
# ls -al
-rw-rw 1 mysql root      73728 10 sept. 10:51 myhostname.err
-rw-rw 1 mysql mysql         6  9 mars   2012 myhostname.pid
-rw-rw 1 mysql mysql     38780 31 juil. 06:25 myhostname-relay-bin.000783
-rw-rw 1 mysql mysql 276234419 31 juil. 14:44 myhostname-relay-bin.000784
...
-rw-rw 1 mysql mysql     77564  8 sept. 06:25 myhostname-relay-bin.000981
-rw-rw 1 mysql mysql 480966971  9 sept. 04:47 myhostname-relay-bin.000982
-rw-rw 1 mysql mysql       199  9 sept. 04:49 myhostname-relay-bin.000983
-rw-rw 1 mysql mysql    786432 10 sept. 10:57 myhostname-relay-bin.000984
-rw-rw 1 mysql mysql      5252  9 sept. 04:49 myhostname-relay-bin.index
-rw-rw 1 mysql mysql  56180736 10 sept. 10:57 myhostname-slow.log

# cat myhostname-relay-bin.index
./myhostname-relay-bin.000783
./myhostname-relay-bin.000784
..
./myhostname-relay-bin.000983
./myhostname-relay-bin.000984
# cat relay-log.info
./myhostname-relay-bin.000982
480412405
mysql-bin.000404
480489566
1

Visiblement, les fichiers antérieurs à 000982 ne sont plus utiles.

Mais alors pourquoi les autres sont toujours présents sur le disque ? puisqu'il est dit : Un log de relais est automatiquement effacé par le thread SQL aussitôt qu'il n'en a plus besoin : c'est à dire aussitôt qu'il en a exécuté les commandes. Il n'y a pas de commande pour effacer les logs de relais, car le thread SQL se charge de le faire.

C'est à cause de RELAY_LOG_PURGE défini à 0 (OFF)

SHOW VARIABLES LIKE 'RELAY_LOG_PURGE';
-- +-----------------+-------+
-- | Variable_name   | Value |
-- +-----------------+-------+
-- | relay_log_purge | OFF   |
-- +-----------------+-------+

Voir l'option relay-log-purge dans les Options de démarrage de la réplication

--relay-log-purge={0|1}

Active ou désactive la vidange automatique des logs de relais, dès qu'ils ne sont plus utiles. C'est une variable globale, qui peut être dynamiquement modifiée avec SET GLOBAL RELAY_LOG_PURGE=0|1. Sa valeur par défaut est 1.

Soit vous faite comme l'indique Is it safe to delete replication relay-bin files? (mais encore faut il avoir de la place pour exécuter cette commande) :

PURGE BINARY LOGS
-- replication will not be affected at any time.

ou alors (bien plus proprement)

-- better answer is relay logs can be 'deleted' but mysql should manage it automatically. One way to do this is to check for the value of relay_log_purge.
-- It should be set to 1 if you want mysql to manage them:
SET GLOBAL relay_log_purge=1;
-- You would probably need to flush the logs:
FLUSH LOGS;
-- This does not affect the binary logs.

Sans place disponible, je vous invite à faire un rm relay-log (de ceux inférieurs à celui cité dans relay-log.info)

Ensuite pour éviter de rencontrer la même erreur de saturation de l'espace disque :

--relay-log-purge=1

et optionnellement

--relay-log-space-limit=#

Limite la taille maximale de tous les fichiers de logs de relais sur l'esclave (une valeur de 0 signifie "sans limite"). C'est utile lorsque vous avez un petit disque sur votre machine esclave. Lorsque la limite est atteinte, le thread d'I/O fait une pause : il ne lit plus rien dans le log binaire du maître, jusqu'à ce que le thread SQL ait avancé, et effacé des fichiers de logs. Notez que cette limite n,est pas absolue : il se peut que le thread SQL requiert plusieurs événements pour être capable d'effacer les fichiers de log de relais. Dans ce cas, le thread d'I/O va dépasser la limite, jusqu'à ce que l'effacement devienne possible. Sans cela, des blocages pourraient survenir. Avec --relay-log-space-limit, il ne faut pas utiliser de valeur inférieure à deux fois la taille de --max-relay-log-size (ou --max-binlog-size si --max-relay-log-size vaut 0) car dans ce cas, il y a des chances que le thread d'I/O attende de l'espace libre par ce que --relay-log-space-limit est dépassée, mais que le thread SQL n'ait pas de logs à effacer, et ne peut donc libérer le thread d'I/O.¸Cela force le thread d'I/O à ignorer temporairement --relay-log-space-limit.

Ressources

When the logs are flushed; for example, with FLUSH LOGS or mysqladmin flush-logs.

When the size of the current relay log file becomes “too large,” determined as follows:

  • If the value of max_relay_log_size is greater than 0, that is the maximum relay log file size.
  • If the value of max_relay_log_size is 0, max_binlog_size determines the maximum relay log file size.

The SQL thread automatically deletes each relay log file as soon as it has executed all events in the file and no longer needs it. There is no explicit mechanism for deleting relay logs because the SQL thread takes care of doing so. However, FLUSH LOGS rotates relay logs, which influences when the SQL thread deletes them.

If a write by a replication slave to its relay log causes the current log file size to exceed the value of this variable, the slave rotates the relay logs (closes the current file and opens the next one). If max_relay_log_size is 0, the server uses max_binlog_size for both the binary log and the relay log. If max_relay_log_size is greater than 0, it constrains the size of the relay log, which enables you to have different sizes for the two logs. You must set max_relay_log_size to between 4096 bytes and 1GB (inclusive), or to 0. The default value is 0.

SELECT @@global.max_relay_log_size, @@global.max_binlog_size, @@global.relay_log_purge;
-- +-----------------------------+--------------------------+--------------------------+
-- | @@global.max_relay_log_size | @@global.max_binlog_size | @@global.relay_log_purge |
-- +-----------------------------+--------------------------+--------------------------+
-- |                           0 |               1073741824 |                        0 |
-- +-----------------------------+--------------------------+--------------------------+

By default, MySQL automatically purges relay logs when it determines they are no longer needed. If you really need to limit the size of your relay logs, you might want to take a look at the "relay-log-space-limit=size" option, which will pause the slave io thread until the sql thread has caught up.