MOO malgré la mémoire disponible (cache)

12

Nous avons rencontré le tueur OOM malgré presque la moitié de notre mémoire utilisée pour le cache FS. Nous avons enregistré les statistiques de la mémoire une fois par minute (comme indiqué par le haut), mais il semble y avoir beaucoup de disponibilité.

...

Mem:  15339640k total, 15268304k used,    71336k free,     3152k buffers
Swap:        0k total,        0k used,        0k free,  6608384k cached

Mem:  15339640k total, 14855280k used,   484360k free,    13748k buffers
Swap:        0k total,        0k used,        0k free,  6481852k cached

[OOM killer: postgres killed]

Mem:  15339640k total,  8212200k used,  7127440k free,    32776k buffers
Swap:        0k total,        0k used,        0k free,  2394444k cached

...

Détails du MOO de syslog:

...
Jun 10 05:45:25 db kernel: [11209156.840462] wal-e invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Jun 10 05:45:25 db kernel: [11209156.840469] wal-e cpuset=/ mems_allowed=0
Jun 10 05:45:25 db kernel: [11209156.840474] Pid: 7963, comm: wal-e Not tainted 3.2.0-43-virtual #68-Ubuntu
Jun 10 05:45:25 db kernel: [11209156.840477] Call Trace:
Jun 10 05:45:25 db kernel: [11209156.840498]  [<ffffffff81119711>] dump_header+0x91/0xe0
Jun 10 05:45:25 db kernel: [11209156.840502]  [<ffffffff81119a95>] oom_kill_process+0x85/0xb0
Jun 10 05:45:25 db kernel: [11209156.840506]  [<ffffffff81119e3a>] out_of_memory+0xfa/0x220
Jun 10 05:45:25 db kernel: [11209156.840511]  [<ffffffff8111f823>] __alloc_pages_nodemask+0x8c3/0x8e0
Jun 10 05:45:25 db kernel: [11209156.840520]  [<ffffffff81216e00>] ? noalloc_get_block_write+0x30/0x30
Jun 10 05:45:25 db kernel: [11209156.840528]  [<ffffffff811566c6>] alloc_pages_current+0xb6/0x120
Jun 10 05:45:25 db kernel: [11209156.840534]  [<ffffffff81116637>] __page_cache_alloc+0xb7/0xd0
Jun 10 05:45:25 db kernel: [11209156.840539]  [<ffffffff81118602>] filemap_fault+0x212/0x3c0
Jun 10 05:45:25 db kernel: [11209156.840553]  [<ffffffff81138c32>] __do_fault+0x72/0x550
Jun 10 05:45:25 db kernel: [11209156.840557]  [<ffffffff8113c2ea>] handle_pte_fault+0xfa/0x200
Jun 10 05:45:25 db kernel: [11209156.840562]  [<ffffffff8100638e>] ? xen_pmd_val+0xe/0x10
Jun 10 05:45:25 db kernel: [11209156.840567]  [<ffffffff81005309>] ? __raw_callee_save_xen_pmd_val+0x11/0x1e
Jun 10 05:45:25 db kernel: [11209156.840571]  [<ffffffff8113d559>] handle_mm_fault+0x269/0x370
Jun 10 05:45:25 db kernel: [11209156.840576]  [<ffffffff8100a56d>] ? xen_force_evtchn_callback+0xd/0x10
Jun 10 05:45:25 db kernel: [11209156.840581]  [<ffffffff8100ad42>] ? check_events+0x12/0x20
Jun 10 05:45:25 db kernel: [11209156.840589]  [<ffffffff8165b3cb>] do_page_fault+0x14b/0x520
Jun 10 05:45:25 db kernel: [11209156.840594]  [<ffffffff81160d64>] ? kmem_cache_free+0x104/0x110
Jun 10 05:45:25 db kernel: [11209156.840600]  [<ffffffff811ba2c8>] ? ep_remove+0xa8/0xc0
Jun 10 05:45:25 db kernel: [11209156.840604]  [<ffffffff811bb133>] ? sys_epoll_ctl+0xb3/0x3d0
Jun 10 05:45:25 db kernel: [11209156.840614]  [<ffffffff81658035>] page_fault+0x25/0x30
Jun 10 05:45:25 db kernel: [11209156.840617] Mem-Info:
Jun 10 05:45:25 db kernel: [11209156.840618] Node 0 DMA per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840622] CPU    0: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840624] CPU    1: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840627] CPU    2: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840629] CPU    3: hi:    0, btch:   1 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840631] Node 0 DMA32 per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840634] CPU    0: hi:  186, btch:  31 usd:  30
Jun 10 05:45:25 db kernel: [11209156.840637] CPU    1: hi:  186, btch:  31 usd:  47
Jun 10 05:45:25 db kernel: [11209156.840639] CPU    2: hi:  186, btch:  31 usd:  15
Jun 10 05:45:25 db kernel: [11209156.840641] CPU    3: hi:  186, btch:  31 usd:   2
Jun 10 05:45:25 db kernel: [11209156.840643] Node 0 Normal per-cpu:
Jun 10 05:45:25 db kernel: [11209156.840646] CPU    0: hi:  186, btch:  31 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840648] CPU    1: hi:  186, btch:  31 usd:  14
Jun 10 05:45:25 db kernel: [11209156.840650] CPU    2: hi:  186, btch:  31 usd:   0
Jun 10 05:45:25 db kernel: [11209156.840653] CPU    3: hi:  186, btch:  31 usd:   1
Jun 10 05:45:25 db kernel: [11209156.840658] active_anon:3616567 inactive_anon:4798 isolated_anon:0
Jun 10 05:45:25 db kernel: [11209156.840660]  active_file:98 inactive_file:168 isolated_file:20
Jun 10 05:45:25 db kernel: [11209156.840661]  unevictable:1597 dirty:73 writeback:0 unstable:0
Jun 10 05:45:25 db kernel: [11209156.840662]  free:16921 slab_reclaimable:17631 slab_unreclaimable:7534
Jun 10 05:45:25 db kernel: [11209156.840663]  mapped:1614529 shmem:1613928 pagetables:124012 bounce:0
Jun 10 05:45:25 db kernel: [11209156.840666] Node 0 DMA free:7888kB min:4kB low:4kB high:4kB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB isolated(anon):0kB isolated(file):0kB present:7632kB mlocked:0kB dirty:0kB writeback:0kB mapped:0kB shmem:0kB slab_reclaimable:0kB slab_unreclaimable:0kB kernel_stack:0kB pagetables:0kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:0 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840681] lowmem_reserve[]: 0 4016 15112 15112
Jun 10 05:45:25 db kernel: [11209156.840686] Node 0 DMA32 free:48368kB min:4176kB low:5220kB high:6264kB active_anon:3776804kB inactive_anon:28kB active_file:0kB inactive_file:20kB unevictable:932kB isolated(anon):0kB isolated(file):0kB present:4112640kB mlocked:932kB dirty:0kB writeback:0kB mapped:1458536kB shmem:1458632kB slab_reclaimable:17604kB slab_unreclaimable:8088kB kernel_stack:1872kB pagetables:190616kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:437 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840698] lowmem_reserve[]: 0 0 11095 11095
Jun 10 05:45:25 db kernel: [11209156.840703] Node 0 Normal free:11428kB min:11548kB low:14432kB high:17320kB active_anon:10689464kB inactive_anon:19164kB active_file:528kB inactive_file:652kB unevictable:5456kB isolated(anon):0kB isolated(file):80kB present:11362176kB mlocked:5456kB dirty:292kB writeback:0kB mapped:4999580kB shmem:4997080kB slab_reclaimable:52920kB slab_unreclaimable:22048kB kernel_stack:2584kB pagetables:305432kB unstable:0kB bounce:0kB writeback_tmp:0kB pages_scanned:1974 all_unreclaimable? yes
Jun 10 05:45:25 db kernel: [11209156.840715] lowmem_reserve[]: 0 0 0 0
Jun 10 05:45:25 db kernel: [11209156.840720] Node 0 DMA: 2*4kB 3*8kB 1*16kB 3*32kB 3*64kB 3*128kB 2*256kB 1*512kB 2*1024kB 2*2048kB 0*4096kB = 7888kB
Jun 10 05:45:25 db kernel: [11209156.840752] Node 0 DMA32: 5813*4kB 2636*8kB 114*16kB 15*32kB 5*64kB 1*128kB 1*256kB 0*512kB 1*1024kB 0*2048kB 0*4096kB = 48372kB
Jun 10 05:45:25 db kernel: [11209156.840776] Node 0 Normal: 1888*4kB 10*8kB 46*16kB 4*32kB 3*64kB 2*128kB 1*256kB 1*512kB 0*1024kB 1*2048kB 0*4096kB = 11760kB
Jun 10 05:45:25 db kernel: [11209156.840788] 1615243 total pagecache pages
Jun 10 05:45:25 db kernel: [11209156.840790] 0 pages in swap cache
Jun 10 05:45:25 db kernel: [11209156.840801] Swap cache stats: add 0, delete 0, find 0/0
Jun 10 05:45:25 db kernel: [11209156.840803] Free swap  = 0kB
Jun 10 05:45:25 db kernel: [11209156.840805] Total swap = 0kB
Jun 10 05:45:25 db kernel: [11209156.909794] 3934192 pages RAM
Jun 10 05:45:25 db kernel: [11209156.909804] 99282 pages reserved
Jun 10 05:45:25 db kernel: [11209156.909809] 18899146 pages shared
Jun 10 05:45:25 db kernel: [11209156.909811] 2198511 pages non-shared
Jun 10 05:45:25 db kernel: [11209156.909817] [ pid ]   uid  tgid total_vm      rss cpu oom_adj oom_score_adj name
Jun 10 05:45:25 db kernel: [11209156.909835] [  332]     0   332     4308      109   1       0             0 upstart-udev-br
Jun 10 05:45:25 db kernel: [11209156.909845] [  346]     0   346     5384      271   2     -17         -1000 udevd
Jun 10 05:45:25 db kernel: [11209156.909851] [  408]     0   408     5364      174   2     -17         -1000 udevd
...
Jun 10 05:45:25 db kernel: [11209156.910703] [ 7963]   111  7963    17456     2966   0       0             0 wal-e
Jun 10 05:45:25 db kernel: [11209156.910707] [ 7968]   111  7968  1639372     2351   3       0             0 postgres
Jun 10 05:45:25 db kernel: [11209156.910711] [ 7969]   111  7969  1639371     1934   2       0             0 postgres
Jun 10 05:45:25 db kernel: [11209156.910716] Out of memory: Kill process 12443 (postgres) score 418 or sacrifice child
Jun 10 05:45:25 db kernel: [11209156.910733] Killed process 12443 (postgres) total-vm:6555152kB, anon-rss:4600kB, file-rss:6396572kB
Jun 10 05:45:30 db kernel: [11209159.293083] postgres invoked oom-killer: gfp_mask=0x201da, order=0, oom_adj=0, oom_score_adj=0
Jun 10 05:45:31 db kernel: [11209159.293091] postgres cpuset=/ mems_allowed=0
Jun 10 05:45:31 db kernel: [11209159.293095] Pid: 6508, comm: postgres Not tainted 3.2.0-43-virtual #68-Ubuntu
Jun 10 05:45:31 db kernel: [11209159.293098] Call Trace:
Jun 10 05:45:31 db kernel: [11209159.293111]  [<ffffffff81119711>] dump_header+0x91/0xe0
Jun 10 05:45:31 db kernel: [11209159.293115]  [<ffffffff81119a95>] oom_kill_process+0x85/0xb0
Jun 10 05:45:31 db kernel: [11209159.293119]  [<ffffffff81119e3a>] out_of_memory+0xfa/0x220
...

Nous pouvons essayer d'augmenter la résolution de ces derniers à environ une fois par seconde, mais y aurait-il une raison pour un MOO ici? (Nous avons vu http://bl0rg.krunch.be/oom-frag.html mais nous travaillons avec des quantités absolues de mémoire beaucoup plus importantes, dont la plupart sont prises par le cache FS du noyau.)

Incluant également des parties pertinentes de notre postgresql.confci-dessous:

shared_buffers = 6GB
effective_cache_size = 8GB
Yang
la source
Euh ... 3.2.0-43? Temps de mise à jour. Le tueur OOM a subi de nombreux (trop) changements au fil du temps. Certaines versions étaient vraiment insensées quant à la prise en compte de l'utilisation de la mémoire partagée ... comme PostgreSQL 9.2 et les versions antérieures shared_buffers.
Craig Ringer
@CraigRinger Malheureusement, il y a d'autres considérations, y compris le maintien du noyau dans la distribution Ubuntu 12.04 pour LTS, la compatibilité, les mises à jour de sécurité, etc. pas intéressé à changer le statu quo / à faire disparaître le problème. BTW shared_buffersest toujours en PG9.3.
Yang
Oui shared_buffersest toujours en 9.3, mais ce n'est plus de la mémoire partagée POSIX en 9.3. Il a été remplacé par une mmap()edrégion anonyme . Cela permet de contourner certains problèmes de configuration du noyau et des problèmes d'épinglage, bien que je doute que cela rende le tueur OOM moins confus.
Craig Ringer
1
Peut-être un doublon de serverfault.com/questions/288319/… , qui a une réponse potentielle.
richvdh

Réponses:

4

Il semble que vous (et moi dans un cas présentant des symptômes très similaires) ayez vraiment manqué de mémoire et avez été confus par le cachednombre.

Il y a apparemment des cas où Linux ne libère pas de cache de disque volumineux lorsque la demande de mémoire augmente

En particulier (je ne comprends pas vraiment pourquoi), les postgres shared_bufferspeuvent être signalés sous "Cached" (le cache de page). Dans votre cas, le 6481852k cachedin topcorrespond à cette ligne dans le journal du tueur OOM:

Jun 10 05:45:25 db kernel: [11209156.840788] 1615243 total pagecache pages

(1615243 * 4KB ~ = 6481852k) - ce qui signifie que le cache de pages n'a pas été supprimé avant d'invoquer OOM-killer.

Pourtant, il y a peu de pages soutenues par des fichiers (je suppose qu'elles active_file:98 inactive_file:168sont similaires à Active (file) / Inactive (file) de / proc / meminfo ), ce ne sont donc pas les pages jetables que nous connaissons et aimons.

La publication sur https://www.depesz.com/2012/06/09/how-much-ram-is-postgresql-using/ montre un exemple de session où la fermeture de postgres entraîne une réduction de la "mise en cache" de la taille de shared_buffers(faites défiler jusqu'à "Et la plus grande partie est sortie du cache disque - comme prévu, car elle a été utilisée pour shared_buffers." ) - malheureusement, elle n'indique pas la version de postgres ni le noyau qui a été utilisé pour l'expérience.

J'utilise 3.13.0-67 x86_64 avec PG 9.3. En 9.3, ils sont passés de l'utilisation de la mémoire partagée Sys V ( shmget) à anonymemmap(...R+W, MAP_SHARED|MAP_ANONYMOUS|MAP_HASSEMAPHORE...)+fork() (en 9.4, cela est devenu configurable via dynamic_shared_memory_type ). Mais je n'ai trouvé aucune explication sur la raison pour laquelle ces mmap () sont censés apparaître dans "caché" et pourquoi, seulement https://access.redhat.com/solutions/406773 qui dit "En cache: Mémoire dans le pagecache (Diskcache et mémoire partagée) "

Étant donné qu'il existe de nombreux types de mémoire partagée, je suis à la fois éclairé et confus ...

Nickolay
la source
Après plusieurs années, c'est une bien meilleure réponse, merci. Il y a toujours la question de savoir pourquoi cela est considéré comme mis en cache, mais je marque cela comme accepté pour l'instant.
Yang
8
  1. Pour l'amour de tout ce qui est bon dans le monde, configurez l'espace d'échange sur vos serveurs .
    Vous avez vraiment besoin d'espace d'échange . Je ne suis pas le seul à le dire , c'est à peu près une vérité universelle ici . (<- Ce sont trois liens)
    Vous devez bien sûr avoir suffisamment de RAM pour que votre serveur de base de données ne permute pas régulièrement - si vous ne le faites pas, la solution est de l'argent (que vous prenez votre fournisseur et utilisez pour acquérir plus de RAM) .

  2. Puisque vous avez maintenant une RAM adéquate et que vous pouvez l'échanger en cas de problème, vous pouvez désactiver le tueur OOM (en désactivant la surcharge de la mémoire), comme les gens de Postgres vous le disent .
    (Vous pouvez également appliquer leur solution alternative et dire à l'OOM-Killer de ne jamais tuer Postgres - mais vous ne faites que jouer à la roulette russe avec le reste des processus de votre système ...)

  3. (facultatif) Écrivez une réponse sur la défaillance du serveur expliquant pourquoi le comportement par défaut dans la plupart des distributions Linux est mauvais, incorrect et viole la spécification POSIX sur la façon dont malloc () est censé se comporter . Répétez-le jusqu'à ce que tout le monde en ait assez d'en entendre parler.


Notez également que la mémoire mise en cache du noyau est disponible pour les postgres (ou toute autre application) à utiliser - vous devez la prendre en compte comme mémoire libre / disponible dans vos calculs.

Si je devais hasarder ce qui se passe ici, je dirais que vous avez une requête complexe, Postgres demande à la RAM de l'exécuter, et plutôt que de dire "Je n'ai pas cette RAM", Linux dit à Postgres "Bien sûr, vous pouvez l'avoir."
Ensuite, lorsque Postgres essaie réellement d' utiliser la RAM, il a été (prétendument) donné que Linux se rend compte qu'il n'a PAS la RAM qu'il a promis à Postgres (car il est surchargé) - le tueur OOM est invité à libérer de la RAM et tue consciencieusement le programme en utilisant le plus de mémoire - votre serveur de base de données.

Postgres est un programme bien conçu. Si on lui dit qu'il ne peut pas avoir la RAM, il demande qu'il le gère avec élégance (soit en se contentant de moins, soit en abandonnant avec un message à l'utilisateur).

voretaq7
la source
4
Merci pour l'élaboration du swap, mais cela ne répond pas à ma question de savoir pourquoi cela se produit en premier lieu . Oui, je comprends la prémisse de base selon laquelle Linux sur-engage par défaut et que le MOO est lorsque nous sommes à court de RAM - j'aurais pu le dire dans ma question d'origine. Mais la question est de savoir pourquoi est-ce qu'il se déclenche alors que j'ai encore beaucoup de RAM (une grande partie juste dans le cache FS)? Supposons que je ne suis même pas intéressé à changer quoi que ce soit - que le tueur OOM va bien, tant que je comprends pourquoi il est déclenché.
Yang
2
Après avoir examiné les liens, il y a malheureusement un certain nombre d'affirmations sans preuves à l'appui ni explications techniques concrètes. Il existe certainement de nombreux environnements Linux où le swap n'est même pas une option (exemple: ne cherchez pas plus loin qu'un Live CD où il n'y a pas déjà de partition de swap locale existante à réutiliser). De plus, nous ne souhaitons pas permettre la permutabilité sur la base de nos propres expériences et environnement - nous préférerions avoir le MOO. Une réponse à la question d'origine serait appréciée.
Yang
1
@Yang Je suppose que si vous construisez un serveur pour Postgres, vous voudrez suivre les recommandations du projet Postgres. Ma réponse est de faire ce qu'ils vous disent (éteignez le tueur OOM). Si vous souhaitez attendre et voir si quelqu'un vous propose une réponse différente, vous êtes certainement libre de le faire, mais je ne suis pas à l'aise d'offrir une autre solution - À mon avis, le tueur OOM est mauvais, mauvais et viole POSIX. Il peut être acceptable sur un ordinateur de bureau / poste de travail, mais le désactiver sur les serveurs est, OMI, la bonne chose à faire.
voretaq7
2
J'ai rencontré cette situation sur un serveur qui a un swap, et après saturation de la mémoire disponible + swap, le tueur OOM a été utilisé à la place du noyau récupérant la mémoire "en cache", qui était évidemment en quelque sorte verrouillée. Je n'ai jamais résolu le problème, mais la question originale de @ Yang n'est pas répondue ici.
Patrick
2
L'échange n'est pas la réponse, il ne fait apparaître le problème que plus tard. Vous avez besoin de swap lorsque la RAM est pleine et vous avez besoin de OOM Killer lorsque RAM + swap est plein. Si la quantité de swap est nulle, vous avez besoin de OOM Killer plus tôt mais vous ne pouvez pas éviter OOM Killer avec swap.
Mikko Rantalainen