Tueur OOM tuant des choses avec beaucoup (?) De RAM gratuite

11

Le tueur OOM semble tuer des choses malgré qu'il y ait plus qu'assez de RAM libre sur mon système:

Graphique d'utilisation de la mémoire (Pleine résolution)

Graphique d'utilisation des E / S (Pleine résolution)

27 minutes et 408 processus plus tard, le système a recommencé à répondre. Je l'ai redémarré environ une heure après, et peu après, l'utilisation de la mémoire est revenue à la normale (pour cette machine).

Après inspection, j'ai quelques processus intéressants en cours d'exécution sur ma boîte:

USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
[...snip...]
root      1399 60702042  0.2 482288 1868 ?     Sl   Feb21 21114574:24 /sbin/rsyslogd -i /var/run/syslogd.pid -c 4
[...snip...]
mysql     2022 60730428  5.1 1606028 38760 ?   Sl   Feb21 21096396:49 /usr/libexec/mysqld --basedir=/usr --datadir=/var/lib/mysql --user=mysql --log-error=/var/log/mysqld.log --pid-file=/var/run/mysqld/mysqld.pid --socket=/var/lib/mysql/mysql.sock
[...snip...]

Ce serveur spécifique fonctionne depuis env. 8 heures, et ce sont les deux seuls processus qui ont des valeurs aussi ... étranges. Je soupçonne qu'il se passe "quelque chose d'autre", potentiellement pertinent pour ces valeurs non sensorielles. Plus précisément, je pense que le système pense qu'il est hors de mémoire, alors qu'en réalité ce n'est pas le cas. Après tout, il pense que rsyslogd utilise un processeur 55383984% de manière cohérente, alors que le maximum théorique est de 400% sur ce système de toute façon.

Il s'agit d'une installation CentOS 6 entièrement mise à jour (6.2) avec 768 Mo de RAM. Toute suggestion sur la façon de comprendre pourquoi cela se produit serait appréciée!

modifier: attacher le vm. sysctl tunables .. J'ai joué avec swappiness (rendu évident par le fait qu'il soit 100), et je lance également un script absolument terrible qui vide mes tampons et cache (rendu évident par vm.drop_caches étant 3) + synchronise le disque chaque 15 minutes. C'est pourquoi après le redémarrage, les données mises en cache ont atteint une taille quelque peu normale, mais ont ensuite rapidement chuté à nouveau. Je reconnais qu'avoir du cache est une très bonne chose, mais jusqu'à ce que je comprenne cela ...

Il est également intéressant de noter que bien que mon fichier d'échange ait augmenté pendant l'événement, il n'a atteint que 20% de l'utilisation totale possible, ce qui n'est pas caractéristique des événements OOM réels. À l'autre extrémité du spectre, le disque est devenu complètement fou pendant la même période, ce qui est caractéristique d'un événement MOO lorsque le fichier d'échange est en cours de lecture.

sysctl -a 2>/dev/null | grep '^vm':

vm.overcommit_memory = 1
vm.panic_on_oom = 0
vm.oom_kill_allocating_task = 0
vm.extfrag_threshold = 500
vm.oom_dump_tasks = 0
vm.would_have_oomkilled = 0
vm.overcommit_ratio = 50
vm.page-cluster = 3
vm.dirty_background_ratio = 10
vm.dirty_background_bytes = 0
vm.dirty_ratio = 20
vm.dirty_bytes = 0
vm.dirty_writeback_centisecs = 500
vm.dirty_expire_centisecs = 3000
vm.nr_pdflush_threads = 0
vm.swappiness = 100
vm.nr_hugepages = 0
vm.hugetlb_shm_group = 0
vm.hugepages_treat_as_movable = 0
vm.nr_overcommit_hugepages = 0
vm.lowmem_reserve_ratio = 256   256     32
vm.drop_caches = 3
vm.min_free_kbytes = 3518
vm.percpu_pagelist_fraction = 0
vm.max_map_count = 65530
vm.laptop_mode = 0
vm.block_dump = 0
vm.vfs_cache_pressure = 100
vm.legacy_va_layout = 0
vm.zone_reclaim_mode = 0
vm.min_unmapped_ratio = 1
vm.min_slab_ratio = 5
vm.stat_interval = 1
vm.mmap_min_addr = 4096
vm.numa_zonelist_order = default
vm.scan_unevictable_pages = 0
vm.memory_failure_early_kill = 0
vm.memory_failure_recovery = 1

edit: et en joignant le premier message OOM ... en y regardant de plus près, cela signifie que quelque chose s'est clairement mis en travers pour manger l'intégralité de mon espace de swap également.

Feb 21 17:12:49 host kernel: mysqld invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0
Feb 21 17:12:51 host kernel: mysqld cpuset=/ mems_allowed=0
Feb 21 17:12:51 host kernel: Pid: 2777, comm: mysqld Not tainted 2.6.32-71.29.1.el6.x86_64 #1
Feb 21 17:12:51 host kernel: Call Trace:
Feb 21 17:12:51 host kernel: [<ffffffff810c2e01>] ? cpuset_print_task_mems_allowed+0x91/0xb0
Feb 21 17:12:51 host kernel: [<ffffffff8110f1bb>] oom_kill_process+0xcb/0x2e0
Feb 21 17:12:51 host kernel: [<ffffffff8110f780>] ? select_bad_process+0xd0/0x110
Feb 21 17:12:51 host kernel: [<ffffffff8110f818>] __out_of_memory+0x58/0xc0
Feb 21 17:12:51 host kernel: [<ffffffff8110fa19>] out_of_memory+0x199/0x210
Feb 21 17:12:51 host kernel: [<ffffffff8111ebe2>] __alloc_pages_nodemask+0x832/0x850
Feb 21 17:12:51 host kernel: [<ffffffff81150cba>] alloc_pages_current+0x9a/0x100
Feb 21 17:12:51 host kernel: [<ffffffff8110c617>] __page_cache_alloc+0x87/0x90
Feb 21 17:12:51 host kernel: [<ffffffff8112136b>] __do_page_cache_readahead+0xdb/0x210
Feb 21 17:12:51 host kernel: [<ffffffff811214c1>] ra_submit+0x21/0x30
Feb 21 17:12:51 host kernel: [<ffffffff8110e1c1>] filemap_fault+0x4b1/0x510
Feb 21 17:12:51 host kernel: [<ffffffff81135604>] __do_fault+0x54/0x500
Feb 21 17:12:51 host kernel: [<ffffffff81135ba7>] handle_pte_fault+0xf7/0xad0
Feb 21 17:12:51 host kernel: [<ffffffff8103cd18>] ? pvclock_clocksource_read+0x58/0xd0
Feb 21 17:12:51 host kernel: [<ffffffff8100f951>] ? xen_clocksource_read+0x21/0x30
Feb 21 17:12:51 host kernel: [<ffffffff8100fa39>] ? xen_clocksource_get_cycles+0x9/0x10
Feb 21 17:12:51 host kernel: [<ffffffff8100c949>] ? __raw_callee_save_xen_pmd_val+0x11/0x1e
Feb 21 17:12:51 host kernel: [<ffffffff8113676d>] handle_mm_fault+0x1ed/0x2b0
Feb 21 17:12:51 host kernel: [<ffffffff814ce503>] do_page_fault+0x123/0x3a0
Feb 21 17:12:51 host kernel: [<ffffffff814cbf75>] page_fault+0x25/0x30
Feb 21 17:12:51 host kernel: Mem-Info:
Feb 21 17:12:51 host kernel: Node 0 DMA per-cpu:
Feb 21 17:12:51 host kernel: CPU    0: hi:    0, btch:   1 usd:   0
Feb 21 17:12:51 host kernel: CPU    1: hi:    0, btch:   1 usd:   0
Feb 21 17:12:51 host kernel: CPU    2: hi:    0, btch:   1 usd:   0
Feb 21 17:12:51 host kernel: CPU    3: hi:    0, btch:   1 usd:   0
Feb 21 17:12:51 host kernel: Node 0 DMA32 per-cpu:
Feb 21 17:12:51 host kernel: CPU    0: hi:  186, btch:  31 usd:  47
Feb 21 17:12:51 host kernel: CPU    1: hi:  186, btch:  31 usd:   0
Feb 21 17:12:51 host kernel: CPU    2: hi:  186, btch:  31 usd:   0
Feb 21 17:12:51 host kernel: CPU    3: hi:  186, btch:  31 usd: 174
Feb 21 17:12:51 host kernel: active_anon:74201 inactive_anon:74249 isolated_anon:0
Feb 21 17:12:51 host kernel: active_file:120 inactive_file:276 isolated_file:0
Feb 21 17:12:51 host kernel: unevictable:0 dirty:0 writeback:2 unstable:0
Feb 21 17:12:51 host kernel: free:1600 slab_reclaimable:2713 slab_unreclaimable:19139
Feb 21 17:12:51 host kernel: mapped:177 shmem:84 pagetables:12939 bounce:0
Feb 21 17:12:51 host kernel: Node 0 DMA free:3024kB min:64kB low:80kB high:96kB active_anon:5384kB inactive_anon:5460kB active_file:36kB inactive_file:12kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:14368kB mlocked:0kB dirty:0kB writeback:0kB mapped:16kB shmem:0kB slab_reclaimable:16kB slab_unreclaimable:116kB kernel_stack:32kB pagetables:140kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:8 all_unreclaimable? no
Feb 21 17:12:51 host kernel: lowmem_reserve[]: 0 741 741 741
Feb 21 17:12:51 host kernel: Node 0 DMA32 free:3376kB min:3448kB low:4308kB high:5172kB active_anon:291420kB inactive_anon:291536kB active_file:444kB inactive_file:1092kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:759520kB mlocked:0kB dirty:0kB writeback:8kB mapped:692kB shmem:336kB slab_reclaimable:10836kB slab_unreclaimable:76440kB kernel_stack:2520kB pagetables:51616kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:2560 all_unreclaimable? yes
Feb 21 17:12:51 host kernel: lowmem_reserve[]: 0 0 0 0
Feb 21 17:12:51 host kernel: Node 0 DMA: 5*4kB 4*8kB 2*16kB 0*32kB 0*64kB 1*128kB 1*256kB 1*512kB 0*1024kB 1*2048kB 0*4096kB = 3028kB
Feb 21 17:12:51 host kernel: Node 0 DMA32: 191*4kB 63*8kB 9*16kB 2*32kB 0*64kB 1*128kB 1*256kB 1*512kB 1*1024kB 0*2048kB 0*4096kB = 3396kB
Feb 21 17:12:51 host kernel: 4685 total pagecache pages
Feb 21 17:12:51 host kernel: 4131 pages in swap cache
Feb 21 17:12:51 host kernel: Swap cache stats: add 166650, delete 162519, find 1524867/1527901
Feb 21 17:12:51 host kernel: Free swap  = 0kB
Feb 21 17:12:51 host kernel: Total swap = 523256kB
Feb 21 17:12:51 host kernel: 196607 pages RAM
Feb 21 17:12:51 host kernel: 6737 pages reserved
Feb 21 17:12:51 host kernel: 33612 pages shared
Feb 21 17:12:51 host kernel: 180803 pages non-shared
Feb 21 17:12:51 host kernel: Out of memory: kill process 2053 (mysqld_safe) score 891049 or a child
Feb 21 17:12:51 host kernel: Killed process 2266 (mysqld) vsz:1540232kB, anon-rss:4692kB, file-rss:128kB
Kyle Brantley
la source
Pouvez-vous fournir la sortie de sysctl -a 2>/dev/null | grep '^vm'?
Patrick
Ajoutée. J'espère que vous (ou quelqu'un) pouvez trouver quelque chose que j'ai manqué.
Kyle Brantley
La seule chose qui me saute aux yeux est le overcommit_memorydécor. Le mettre à 1 ne devrait pas provoquer ce problème, mais je n'ai jamais eu besoin de le régler sur «toujours sur-engagé» auparavant, donc pas beaucoup d'expérience là-bas. En regardant les autres notes que vous avez ajoutées, vous avez dit que le swap n'était utilisé qu'à 20%. Toutefois , selon la sauvegarde du journal de OOM, Free swap = 0kB. Il pensait certainement que le swap était utilisé à 100%.
Patrick

Réponses:

13

Je viens de regarder le vidage du journal oom, et je doute de l'exactitude de ce graphique. Remarquez la première ligne «Node 0 DMA32». Il dit free:3376kB, min:3448kBet low:4308kB. Chaque fois que la valeur libre tombe en dessous de la valeur basse, kswapd est censé commencer à échanger des choses jusqu'à ce que cette valeur remonte au-dessus de la valeur haute. Chaque fois que free tombe en dessous de min, le système se fige essentiellement jusqu'à ce que le noyau le récupère au-dessus de la valeur min. Ce message indique également que l'échange a été complètement utilisé là où il est indiqué Free swap = 0kB.
Donc, fondamentalement, kswapd s'est déclenché, mais le swap était complet, donc il ne pouvait rien faire, et la valeur pages_free était toujours inférieure à la valeur pages_min, donc la seule option était de commencer à tuer des choses jusqu'à ce qu'il puisse récupérer pages_free.
Vous avez définitivement manqué de mémoire.

http://web.archive.org/web/20080419012851/http://people.redhat.com/dduval/kernel/min_free_kbytes.html a une très bonne explication de la façon dont cela fonctionne. Voir la section «Implémentation» en bas.

Patrick
la source
1
Alors l'OP a vraiment besoin de plus de RAM ...
ewwhite
plus de bélier, ou découvrez ce que vous en mangez.
Patrick
J'ai mis les lignes sur ce graphique très précisément. Il a arrêté d'enregistrer les données ~ 1 à 2 m avant la fin du premier processus et a repris les données d'enregistrement ~ 4 à 5 m après la fin du dernier. À ce stade, je parie qu'un processus s'est complètement détraqué et a commencé à détruire mon fichier d'échange - une fois qu'il a finalement tout obtenu, il a également tué les processus qui fonctionnaient à court du fichier d'échange, c'est pourquoi lorsque les données sont retournées, le fichier d'échange était élevé mais pas plein. Des suggestions sur la façon de déterminer ce que cela fait seraient les bienvenues!
Kyle Brantley
@KyleBrantley Quelles valeurs tirez-vous pour générer le graphique? L'un des inconvénients du système de mémoire virtuelle Linux est qu'il n'y a pas de définition concrète de «libre». Il existe une douzaine de façons de définir la «mémoire libre». Celui qui compte en ce qui concerne kswapd est la valeur pages_free. En ce qui concerne l'échange gratuit, je ne sais pas quelle valeur vous pourriez lire, ce qui serait si loin. La seule façon de vraiment voir ce qui mange la mémoire est d'enregistrer des instantanés continus de tous les processus sur la boîte et de voir ce qui utilise toute la mémoire lorsque le tueur oom commence à devenir fou.
Patrick
2
Ouais, j'ai manqué de mémoire. J'ai fini par parcourir les journaux pour découvrir que mes processus enfants apache étaient tués à plusieurs reprises, ce qui m'a amené à comprendre que j'avais des processus enfants fonctionnellement infinis qu'il pouvait démarrer. Tout ce qu'il a fallu, c'est que les robots de blogs automatisés lancent beaucoup de requêtes / seconde à l'hôte pour qu'il tombe. Ajuster Apache a tout résolu.
Kyle Brantley
3

Débarrassez-vous du script drop_caches. En outre, vous devez publier les parties pertinentes de votre sortie dmesget /var/log/messagesafficher les messages MOO.

Pour arrêter ce comportement, je vous recommande d'essayer ce sysctlparamètre. Il s'agit d'un système RHEL / CentOS 6 et fonctionne clairement sur des ressources limitées. Est-ce une machine virtuelle?

Essayez de modifier /proc/sys/vm/nr_hugepageset voyez si les problèmes persistent. Cela pourrait être un problème de fragmentation de la mémoire, mais voyez si ce paramètre fait une différence. Pour rendre le changement permanent, ajoutez- vm.nr_hugepages = valuele /etc/sysctl.confet lancez sysctl -ppour relire le fichier de configuration ...

Voir aussi: Interprétation des messages "échec d'allocation de page" du noyau cryptique

ewwhite
la source
Ajout du premier message oom-killer. Bien que MySQL soit la chose la plus gourmande en RAM que j'utilise, je l'ai réglée pour ne pas submerger la boîte non plus, donc à part les valeurs folles que je vois en haut, je ne le soupçonne pas vraiment (5,1% l'utilisation de la mémoire est très bien, tout bien considéré). Il s'agit d'un VPS, avec 768 Mo de RAM. Je vais lire sur les nr_hugepages et je vais essayer, merci!
Kyle Brantley
@ewwhite attribuant que de nombreuses pages énormes tueraient la boîte. La boîte n'a que 768 Mo de RAM, et avec l'énorme pages par défaut de 2 Mo, cela allouerait 2 Go d'énormes pages. La boîte ne pourrait pas gérer cela et mourrait immédiatement.
Patrick
Actualisé. La valeur doit cependant être augmentée de zéro.
ewwhite
C'est encore plus compliqué que ça. Vous devez définir les autorisations de page énorme, et mysql doit être configuré pour utiliser des pages énormes, sinon vous les allouez simplement sans raison.
Patrick
2

Il n'y a aucune donnée disponible sur le graphique depuis le début du tueur OOM jusqu'à sa fin. Je crois dans l'intervalle de temps où le graphique est interrompu qu'en fait la consommation de mémoire augmente et qu'il n'y a plus de mémoire disponible. Sinon, le tueur OOM ne serait pas utilisé. Si vous regardez le graphique de mémoire libre après l'arrêt du tueur OOM, vous pouvez voir qu'il descend d'une valeur plus élevée qu'auparavant. Au moins, il a fait son travail correctement, libérant de la mémoire.

Notez que votre espace d'échange est presque entièrement utilisé jusqu'au redémarrage. Ce n'est presque jamais une bonne chose et un signe certain qu'il reste peu de mémoire libre.

La raison pour laquelle il n'y a pas de données disponibles pour cette période particulière est que le système est trop occupé par d'autres choses. Les valeurs "drôles" dans votre liste de processus peuvent être simplement un résultat, pas une cause. Ce n'est pas inconnu.

Vérifiez /var/log/kern.log et / var / log / messages, quelles informations pouvez-vous y trouver?

Si la journalisation s'est également arrêtée, essayez d'autres choses, videz la liste des processus dans un fichier toutes les secondes environ, de même avec les informations sur les performances du système. Exécutez-le avec une priorité élevée afin qu'il puisse toujours faire son travail (espérons-le) lorsque la charge augmente. Bien que si vous n'avez pas de noyau préemptif (parfois indiqué comme noyau "serveur"), vous risquez de manquer de chance à cet égard.

Je pense que vous constaterez que le (s) processus qui utilise (nt) le plus de CPU% au moment où vos problèmes commencent sont (sont) la cause. Je n'ai jamais vu rsyslogd ni mysql se comporter de cette façon. Les coupables les plus probables sont les applications java et les applications gui comme un navigateur.

aseq
la source
Il n'y a pas de données dans cet écart parce que la charge sur les pointes de la boîte est si absurdement élevée que tout, y compris l'agent de surveillance, s'arrête complètement. L'agent lui-même n'a jamais été tué au cours de la période de mort imminente, mais il n'a pas non plus pu fournir de données. Mon espace d'échange était en fait bien. Il utilisait ~ 130/512 Mo au total avant le redémarrage. rsyslogd est configuré pour signaler les journaux à un emplacement réseau, où tout ce qui s'est passé a été enregistré - et à part cela tuant 408 processus (dont certains étaient des enfants apache qui ont été redémarrés), rien ne se démarquait.
Kyle Brantley
Je peux finir par vider la liste complète des processus dans un fichier (ou le réseau) toutes les quelques secondes si je ne peux pas vraiment comprendre ce qui se passe ici, alors merci pour la bonne idée.
Kyle Brantley
Oui, vous devriez le faire, assurez-vous d'enregistrer également l'utilisation du processeur de chaque processus, regardez "top -b" (mode batch). Le processus qui pointe peut être le coupable.
aseq