MySQL - oom killer

kortex
2015-06-17T11:29:59+02:00
Linux.général, mysqldump, mysql

Bonjour à tous,

Je vous sollicite à nouveau pour un problème relativement complexe.

Samedi matin j'ai eu un "too many connection" bloquant mon applicatif sur MySQL (version = 5.5.40).
Mon max_connections est à 350 et rien n'explique encore une telle anomalie hormis un 'optimize' qui tournait et qui a peut être bloqué plusieurs bots.

J'ai donc killé tous les bots + toutes les sessions MySQL et nous étions repartis.

Mardi matin (hier donc), j'ai eu la désagréable surprise de constater que MySQL s'est fait killer par oom killer : out of memory. Est-ce la suite du samedi ? Bizarre mais pourquoi pas.
La machine physique est dédiée à MySQL et dispose de 256 Go de mémoire.

Voici un bout de la configuration (la partie intéressante pour la mémoire / les performances) :
key_buffer_size = 16M
max_allowed_packet = 100M
table_open_cache = 1000
table_definition_cache = 1000
sort_buffer_size = 20M
net_buffer_length = 8K
read_buffer_size = 256K
read_rnd_buffer_size = 512K
myisam_sort_buffer_size = 8M
max_heap_table_size = 2G
tmp_table_size = 2G
max_connections = 350
query_cache_limit = 128M
query_cache_size = 2G
query_cache_type = 1
thread_cache_size = 2000
innodb_buffer_pool_size = 128G
innodb_additional_mem_pool_size = 4G
innodb_data_file_path = ibdata1:50M:autoextend:max:100G
innodb_log_file_size = 500M
innodb_log_buffer_size = 8M
innodb_log_files_in_group = 2
innodb_flush_log_at_trx_commit = 1
innodb_io_capacity = 200
innodb_file_per_table

D'après ce site http://www.omh.cc/mycnf/ j'ai besoin de 176 Go.
D'après ce site http://www.mysqlcalculator.com/ j'ai besoin de 151 Go.
J'avais également trouvé une règle de calcul mais je n'arrive pas à remettre la main dessus et j'étais plutôt à l'aise.

Le dmesg me dit que le kill a eu lieu à 23H50.
Si je regarde mes traitements, je constate plus un kill vers 00H31.
Les deux serveurs sont à l'heure (ntp toutes les heures).

Les deux seuls paramètres qui peuvent expliquer un pic de consommation sont tmp_table_size et max_heap_table_size puisqu'ils sont liés à une requête.
Par contre, s'il n'y a pas assez de mémoire pour assurer la mise en ram, j'ose espérer que MySQL flush sur disque. De plus, à l'heure du kill, je n'avais pas beaucoup de traitement (en tout cas rien qui explique que ce soit X tables temporaires ou X requêtes à jointures qui soient la cause du soucis).

Quand le service est tombé, j'étais en pleine sauvegarde : j'utilise déjà '--opt' (donc '--quick') vu que mes bases sont volumineuses. Ce qui signifie que normalement les lignes ne sont pas en ram mais directement flushées dans le dump.
J'ai redémarré le service hier matin et je suis resté à une consommation de 20% de la mémoire physique sur toute la journée. Quand le dump s'est déclenché hier soir, je suis monté à 65%. Depuis je ne descends plus.

Du coup, j'ai plusieurs questions :
- est-ce que MySQL pourrait ne pas avoir rendu la mémoire suite au kill des connexions ?
- qu'est-ce qui aurait pu causer cette consommation de mémoire alors que mes calculs tendent quand même à dire que j'ai une belle marge de sécurité ?
- qu'est-ce qui explique un décalage 23H50 (heure du kill dans dmesg) et 00H31 (heure réelle ou MySQL n'est plus) ?

Si quelqu'un a des idées / pistes à suivre je suis preneur.

Je vous remercie d'avance.