kernel


Dimanche 12 février 2012 7 12 /02 /Fév /2012 15:20

 

Après avoir rencontré quelques anomalies dans la gestion de ISM sous Solaris x86 (voir l'analyse du bug), nous allons étudier la manière de le contourner. Pour rappel le bug est le suivant : non partage de la table de pages en ISM. Les workarounds mis en oeuvre ici concernent uniquement les bases de données Oracle. Cependant certains d'entre eux peuvent vous aider à adresser ce type de problème dans contextes différents. Je remercie Alain et Thierry (consultants Oracle) pour l'aide apportée sur la mise en place de ces workarounds (notamment sur la partie Oracle base de données).

 

 

Ce bug a toujours existé dans Solaris 10x86, et pourtant personne ne l'a remarqué. Et pourquoi donc !? Il faut deux éléments pour qu'il devienne visisble sur le système :

  • Une taille de ISM importante (supérieur à 80 Go environ)
  • Une multitude d'attachements / détachements à cette ISM

 

Sans ces deux conditions, le dysfonctionnement n'est pas impactant pour le système (la consommation du serveur n'est pas affectée par des Spin locks provenant du bug). Il y a deux manières de controurner ce problème :

  • La taille de l'ISM
  • Diminuer le nombre d'attachements / détachements

 

Diminuer la taille de l'ISM va un peu à l'encontre de l'histoire !! Possédant des serveurs de plus en plus capacitifs (512 Go de RAM voir plus maintenant), et ne pas en profiter pleinement, c'est un peu ridicule. Une approche plus constructive serait de découper le segment ISM par plusieurs segments de plus petites tailles. Solaris a bien des qualités mais ne posséde malheuresement pas celle de découper un segment ISM (à l'inverse de Linux : voir shmmax et shmall).

 

Reste que le monde informatique est bien fait !! L'architecture des serveurs x86 (je parle des serveurs produits actuellement) fonctionne en utilisant le schéma mémoire NUMA. Pour simplifier, le temps d'accès à la mémoire dépend de sa localisation par rapport aux processeurs. Solaris utilise pleinement ces fonctionnalités à travers les locality groups (lgrp). La mémoire est implicitement découpée par le système Solaris. La base de données Oracle est capable de découper son segment de mémoire partagée sur les différents locality groups disponibles sur le serveurs. Quand je vous disais que le monde informatique était bien fait !! Il s'agit d'activer une option lors du démarrage de la base de données.

 

L'autre approche est de limiter le nombre d'attachements / détachements. Même si diminuer le nombre d'utilisateurs reste une solution, je ne vous la conseille pas !! Par contre utiliser les fonctionnalités d'Oracle base de données nous permet de répondre à ce besoin. Il s'agit d'utiliser soit la fonctionnalité de Shared Server soit la fonctionnalité de Database Resident Connection Pooling. La dernière fonctionnalité étant disponible en version 11g. 

 

Le protocol de tests est assez simple : lancement de 50 connexions simultanées (via sqlplus). Chaque sqlplus provoque une connexion / déconnexion à la base toutes les 2 secondes. L'activité du système est surveillée par la commande vmstat, les locks (et leurs temps) sont tracés avec un petit script Dtrace. Tous les tests ont été réalisés avec une SGA de 200 Go et 25 Go de shared pool.

 

Résultats obtenus :      

 

Cas 1 : Reproduction du problème

 

Paramétrage Aucun
Durée des 50 connexions 2m16s
Charge CPU Saturé en mode Système
Nombre de locks Spin et Block Des milliers de Spin et Block
Temps des locks Spin

Spin de quelques ms à 700ms

Temps des locks Block

Block de quelques ms à plusieurs milliers de ms

 

 

Cas 2 : Utilisation de NUMA

 

Paramétrage Activation de NUMA
Durée des 50 connexions 32s
Charge CPU 60% en mode système - 5% en mode user
Nombre des locks Spin et Block Des milliers de Spin et Block
Temps des locks Spin Spin inférieur à 1ms
Temps des locks Block Block compris entre 10ms et 100ms

 

Remarques :

  • 4 lgrps disponibles sur le serveur
  • 3 segments ISM de 50 Go + 1 segment ISM de 75 Go (50 Go de SGA et 25 Go PGA)
  • 1 segment ISM de quelques Mo pour la gestion des 4 autres segments

 

Cas 3 : Utilisation de Data Resident Connection Pooling dans Oracle

 

Paramétrage Activation du Data Resident Connection Pooling
Durée des 50 connexions 26s
Charge CPU Inférieur à 5% en mode système et user
Nombre des locks Spin et Block Quelques appels lors de la création des processus de pool
Temps des locks Spin Quelques nanosecondes
Temps des locks Block

Aucun

 

Remarques :

  • Lors du test, un hang non expliqué est apparu
  • Les limitations fonctionnelles de connexions au même schéma sont à valider par l'applicatif

 

Cas 4 : Utilisation de Shared Server      

 

Paramétrage Activation des Shared Server
Durée des 50 connexions 24s
Charge CPU Inférieur à 5% en mode système et user
Nombre des locks Spin et Block Quelques appels lors de la création des processus de pool
Temps des locks Spin Quelques nanosecondes
Temps des locks Block Aucun

 

Remarques :

  • Quelques ajustements à faire : nombre de serveurs, large pool, taille de la UGA
  • Fonctionnalités présentes depuis plusieurs versions d'Oracle base de données

 

Les 3 workarounds présentés ici permettent d'augementer la taille de la SGA de votre base Oracle sur Solaris x86 sans saturer votre système. Les fonctionnalités présentes dans Oracle (Data Resident Connection Pooling et Shared Servers) permettent même de masquer complétement le bug ISM : les attachements / détachements sont supprimés. Cependant leur mise en oeuvre nécessite un paramétrage à faire valider par les utilisateurs. L'option NUMA est plus simple à mettre en oeuvre mais dépend surtout de votre architecture matérielle : nombre de lgrps disponibles sur votre système (j'écris en ce moment un petit artcile à ce sujet).

 

 

Ci-joint quelques références sur ce sujet : 

 

Par gloumps - Publié dans : kernel
Ecrire un commentaire - Voir les 0 commentaires

Mardi 31 janvier 2012 2 31 /01 /Jan /2012 23:03

 

Continuons un peu cette formidable aventure dans la gestion de l'ISM sous Solaris x86. Dans l'article précédent, j'évoque un problème d'initialisation de l'ISM provenant des tailles de pages. Dans cet article, j'ai découvert un bug dans la gestion de l'ISM toujours sous Solaris x86.

 

Suite à une migration d'une base de données Oracle d'une architecture Solaris Sparc à une architecture Solaris x86, l'équipe DBA a décidé d'utiliser pleinement la mémoire disponible sur cette nouvelle infrastructure. Disposant d'un serveur avec 512 Go de mémoire, la SGA de la base Oracle a été positionnée à 290 Go (afin de diminuer les lectures physiques et d'éviter les locks R/W). L'augmentation de cette SGA a eu un bénéfice important sur les opérations de lectures (plus d'activité sur les disques SAN concernant les lectures) par contre le système Solaris saturait...

 

# vmstat 3
kthr memory page disk faults cpu
r b w swap free re mf pi po fr de sr s0 s1 s6 s7 in sy cs us sy id
11 2 0 274157192 335523004 1348 8439 1506 2 2 0 1 5 -1 158 105 15844 31218 10183 5 7 88
2 12 0 86340852 144652404 1996 43583 0 25 24 0 0 0 0 0 0 64086 182685 44871 13 34 53
2 0 0 86352032 144645428 4773 45640 0 17 17 0 0 0 0 0 0 179020 200275 59466 16 31 53
0 1 0 86327500 144637200 1680 42171 0 35 33 0 0 0 0 0 0 69311 178558 44632 14 40 46
2 0 0 86357008 144655832 2035 35481 0 13 13 0 0 0 0 0 0 62857 162021 45164 13 25 63
2 0 0 86334148 144631452 1940 44848 0 11 11 0 0 0 0 0 0 64294 188696 43993 13 38 49
1 1 0 86171376 144496048 3014 52949 0 5 5 0 0 0 0 0 0 64821 192942 46708 17 30 52
52 1 0 86025360 144381188 1779 38176 0 16 16 0 0 0 0 0 0 47234 129932 29021 13 64 24
2 0 0 85953152 144301940 1766 50384 0 21 20 0 0 5 0 0 0 68138 181369 40882 18 46 37
0 2 0 86124088 144497016 2889 38238 0 11 11 0 0 0 0 0 0 53142 151981 36137 11 46 43
50 0 0 86065384 144470520 1806 46570 0 27 24 0 0 0 0 0 0 41055 147273 26207 9 71 20
2 0 0 86020672 144434312 1818 30717 8 3 1 0 0 0 0 0 0 59711 155183 37919 11 55 33
20 1 0 86000472 144415592 2892 46429 0 24 23 0 0 0 0 0 0 48937 161600 32703 12 66 23

^C

 

Le système saturait complètement lors de l'utilisation massive de la base de données. Avec un load de plus 200 sur 5 minutes, un pourcentage de 80 pour le SYS et 20 pour le USER, quelques choses ne fonctionnait pas correctement.

 

Passons à l'analyse de ce problème. D'abord, qui utilise le temps système ?

 

# dtrace -n 'profile-1001hz /arg0/ { @[execname] = count(); }'
dtrace: description 'profile-1001hz ' matched 1 probe
^C
[…]
mpathadm 1102
fsflush 2160
tnslsnr 4541
sched 37200
oracle 496331

 

Le temps système provient des process Oracle DB. Une bonne chose mais cela reste étrange. Que fait Oracle pour consommer autant de temps système ?

 

# dtrace -n 'profile-1001hz /arg0 && execname == "oracle" / { @[stack()] = count(); } tick-60s { trunc(@,5); exit(0);}'
dtrace: description 'profile-1001hz ' matched 2 probes
CPU ID FUNCTION:NAME
19 73222 :tick-60s

unix`mutex_delay_default+0x7
unix`mutex_vector_enter+0x99
ipc`ipc_get+0x62
shmsys`shmget+0x4a
shmsys`shmsys+0x7e
unix`sys_syscall+0x17b
83649

unix`mutex_delay_default+0xa
unix`mutex_vector_enter+0x99
ipc`ipc_lock_internal+0x4b
ipc`ipc_lock+0x11
shmsys`shm_detach+0x5c
shmsys`shmdt+0x90
shmsys`shmsys+0x6d
unix`sys_syscall+0x17b
94488

unix`mutex_delay_default+0x7
unix`mutex_vector_enter+0x99
ipc`ipc_lock_internal+0x4b
ipc`ipc_lock+0x11
shmsys`shm_detach+0x5c
shmsys`shmdt+0x90
shmsys`shmsys+0x6d
unix`sys_syscall+0x17b
108405

unix`mutex_delay_default+0xa
unix`mutex_vector_enter+0x99
ipc`ipc_lock_internal+0x4b
ipc`ipc_lookup+0x29
shmsys`shmat+0x70
shmsys`shmsys+0x59
unix`sys_syscall+0x17b
129651

unix`mutex_delay_default+0x7
unix`mutex_vector_enter+0x99
ipc`ipc_lock_internal+0x4b
ipc`ipc_lookup+0x29
shmsys`shmat+0x70
shmsys`shmsys+0x59
unix`sys_syscall+0x17b
147262

Fort intéressant !? Lors des appels systèmes shmat() et shmdt(), le système consomme son temps dans des mutex. Regardons cela de plus près. S'aggissant de locks type adaptive mutex, deux choses sont à vérifier : 

  • le temps d'acquisition de la ressource (cpu off donc mutex adaptive block)
  • le temps écoulé pendant l'obtention de la ressource (cpu on donc mutex spin)

 

J'ai écrit rapidement un petit script Dtrace me permettant de quantifier rapidement ces deux temps (j'utilise notamment la probe lockstat). Ci-joint le résultat

 

# ./ipc_lock.d

558462664068813 cpu  4 exec oracle pid 23796: adaptive-block(0) took 1015 ms
558461944173547 cpu 28 exe oracle pid 23864: adaptive-block(0) took 1185 ms
558462329451173 cpu 30 exe oracle pid 23886: adaptive-spin(0) took 2570 ms
558462329430767 cpu 31 exe oracle pid 23724: adaptive-spin(0) took 1930 ms
558463436775114 cpu  0 exec oracle pid 23906: adaptive-spin(0) took 1963 ms
558463900687630 cpu  0 exec oracle pid 22498: adaptive-spin(0) took 1598 ms
558463900815833 cpu  0 exec oracle pid 23165: adaptive-block(0) took 1088 ms
558463119973512 cpu  1 exec oracle pid 23840: adaptive-spin(0) took 2979 ms
558463900250335 cpu  2 exec oracle pid 23868: adaptive-spin(0) took 3515 ms
558463436925731 cpu  5 exec oracle pid 23786: adaptive-block(0) took 1397 ms
558463900448070 cpu  6 exec oracle pid 23808: adaptive-block(0) took 1199 ms
558463900426025 cpu 10 exec oracle pid 22343: adaptive-spin(0) took 1766 ms
558463436944972 cpu 14 exec oracle pid 23881: adaptive-block(0) took 1203 ms
558463775141403 cpu 15 exec oracle pid 23903: adaptive-spin(0) took 3979 ms
558463646477100 cpu 16 exec oracle pid 23858: adaptive-spin(0) took 3374 ms
558463545080417 cpu 17 exec oracle pid 23842: adaptive-block(0) took 1299 ms
558463775195434 cpu 20 exec oracle pid 23838: adaptive-block(0) took 1164 ms
558463775112272 cpu 21 exec oracle pid 23900: adaptive-spin(0) took 1893 ms
558464220990762 cpu  8 exec oracle pid 23471: adaptive-spin(0) took 1754 ms
558464221051681 cpu 15 exec oracle pid 23136: adaptive-spin(0) took 1967 ms
558466485966584 cpu  9 exec oracle pid 23903: adaptive-spin(0) took 1040 ms
558466153296593 cpu 16 exec oracle pid 23918: adaptive-spin(0) took 1597 ms
558467238545528 cpu  1 exec oracle pid 23855: adaptive-spin(0) took 1206 ms
558467660401004 cpu  8 exec oracle pid 23888: adaptive-spin(0) took 1917 ms
558466980614425 cpu  9 exec oracle pid 23938: adaptive-block(0) took 1141 ms
558466980595351 cpu 11 exec oracle pid 23930: adaptive-block(0) took 1354 ms
558467779687829 cpu 14 exec oracle pid 23955: adaptive-spin(0) took 2318 ms
558467976549814 cpu  4 exec oracle pid 23908: adaptive-spin(0) took 1210 ms
558467976490096 cpu  5 exec oracle pid 23641: adaptive-spin(0) took 1278 ms
558469750980230 cpu  3 exec oracle pid 23936: adaptive-spin(0) took 3297 ms
558469308862236 cpu  5 exec oracle pid 23911: adaptive-spin(0) took 1332 ms
558469308776939 cpu  7 exec oracle pid 23920: adaptive-spin(0) took 3390 ms
558469308793235 cpu  8 exec oracle pid 23890: adaptive-spin(0) took 3219 ms
558469308812116 cpu 10 exec oracle pid 23955: adaptive-spin(0) took 1413 ms
ˆC
558469750890183 cpu 11 exec oracle pid 23991: adaptive-spin(0) took 1774 ms

 

Ca se passe de commentaire non !? Plus de 3 secondes en moyenne pour les adaptive spin !!! Mais que se passe t'il exactement ? Lors de chaque attachement ou détachement à la SGA, le système lock la ressource IPC. En moyenne, il y a environ 20 attachements / détachements seconde sur cette base de données avec plus de 1000 connexions actives en simultanées (voir la colonne NATTCH).

 

# ipcs -mopi -z zonexxxx
IPC status from <running system> as of Tue Oct 23 10:14:51 CET 2011
T         ID      KEY        MODE        OWNER    GROUP NATTCH  CPID  LPID ISMATTCH
Shared Memory:
m  520093698   0x77adb4f8 --rw-rw----   oracle      dba   1338 29340 18826     1338    

 

Voyons un peu plus dans le détail les différentes stack() kernel obtenus lors des locks adaptive spin et block.

 

# ./ipc_stack.d

   unix`htable_release+0x93
   unix`hati_load_common+0x12d
   unix`hat_share+0x281
   genunix`segspt_shmattach+0xd2
   genunix`as_map_locked+0x102
   genunix`as_map+0x4a
   shmsys`shmat+0x500
   shmsys`shmsys+0x59
   genunix`dtrace_systrace_syscall+0xc7
   unix`sys_syscall+0x17b
   225

 

   unix`htable_lookup+0x8c
   unix`hati_load_common+0x5b
   unix`hat_share+0x281
   genunix`segspt_shmattach+0xd2
   genunix`as_map_locked+0x102
   genunix`as_map+0x4a
   shmsys`shmat+0x500
   shmsys`shmsys+0x59
   genunix`dtrace_systrace_syscall+0xc7
   unix`sys_syscall+0x17b
   606 

 

   unix`htable_lookup+0x8c
   unix`hat_unshare+0x7e
   genunix`segspt_shmunmap+0x81
   genunix`as_unmap+0x137
   shmsys`shm_detach+0x4b
   shmsys`shmdt+0x90
   shmsys`shmsys+0x6d
   genunix`dtrace_systrace_syscall+0xc7
   unix`sys_syscall+0x17b
   897

 

La fonction hat_share() semble assez intéressante à étudier. En regardant d'un peu plus près le code source, on constate l'élément suivant : suite à différentes conditions, soit la table de pages est partagée soit elle ne l'est pas (goto share - goto unshare). Si vous avez lu l'article précédant, un des avantages d'utiliser un segment ISM est justement de pouvois partager sa table de pages entre les différents processus se connectant à ce segment.

 

La fonction hati_load_command() exécutée dans la fonction hat_share() se déclenche uniquement dans le goto unshare. Tient donc, on utilise ISM et on ne partage pas la table de pages entre les différents processus !? Une des conditions provoque ce dysfonctionnement mais laquelle ? La taille de la SGA influence t'elle quelques choses ? Y a t'il une limite à la SGA ?

 

J'ai décidé de reprendre cette analyse sur différentes bases Oracles ayant des tailles de SGA différentes. Le résultat est surprenant... Pour chaque attachement à la SGA, la stack est identique. Cela veut dire que la table de pages n'est jamais partagée sur un Solaris 10x86 quand l'ISM est activé !!! Oupppsss !!! Cependant les temps de locks sont nettement inférieurs à la seconde et augementent quand la taille de la SGA augmente.

 

Pour résumé, l'ISM activé sur Solaris 10x86 ne partage pas la table de pages entre les différents processus qui y accèdent. Plus il y a d'attachements simultanés plus le phénomène s'accentue. Plus la taille de l'ISM est important plus les temps de locks sont importants. Avec toute ces petites informations j'ai ouvert un call chez Oracle. Le diagnostique s'avère exact, un bug a été ouvert en interne avec la référence suivante Bug 7127336: page table not shared for ISM segment on x64.

 

La correction du Bug semble assez complexe à mettre en oeuvre. J'ai donc travaillé avec les ingénieurs Oracle afin de trouver une solution temporaire à ce problème... Il va falloir attendre un peu pour les solutions...

 

Ci-joint quelques références sur ce sujet :

 

 

Par gloumps - Publié dans : kernel
Ecrire un commentaire - Voir les 1 commentaires

Lundi 9 janvier 2012 1 09 /01 /Jan /2012 18:13

 

Petit sujet qui m'a tenu en haleine. Pour faciliter sa compréhension je le découpe en deux parties : une première partie sur un problème d'initialisation d'un segment de type ISM et une seconde partie sur un dysfonctionnement de l'ISM. Les deux sous Solaris x86 uniquement.

 

Mais de quoi parlons nous ? Quelques explications sont nécessaires. Pour partager des données et synchroniser des évènements entre processus, le système Solaris utilise un framework nommé IPC (InterProcess Communication). Ce framework contient plusieurs objets IPC dont le standard POSIX IPC : POSIX semaphores, POSIX shared memory et POSIX message queues. 

 

J'évoque ici l'objet IPC : POSIX shared memory. Cet objet est notamment utilisé dans les bases de données (en tout cas Oracle et Sybase). Pour les "spécialistes" de ces produits, il s'agit ni plus ni moins de la fameuse SGA. Pour nous, les "spécialistes" du système nous appelons cela un segment SHM (Segment sHared Memory). Lors du démarrage d'une instance Sybase ou Oracle, un segment SHM est initialisé avec une taille spécifique. Si cette taille n'est pas disponible, l'instance ne s'active pas. 

 

Par défaut, la création d'un segment SHM : 

  • n'est pas locké en mémoire (donc swappable).
  • utilise des tailles de pages par défaut (soit 4K sous Solaris x86 et 8K sous Solaris sparc).
  • n'utilise pas de table de translation d'addresse commune entre tous les processus utilisants ce segment.

Les ingénieurs Solaris ont donc optimisé la gestion de ce segment SHM : ISM (Intimate Shared Memory).

 

L'ISM corrige les problèmatique d'un segment SHM classique : 

  • taille de pages optimisée.
  • création d'une table de partage d'adresse pour optimiser les translation.
  • segment automatiquement locké en mémoire.

L'utilisation de ce type de segment est devenu le standard pour les bases de données : la SGA fonctionne donc avec un segment ISM sous Solaris.

 

D'où mon problème : ma base de données Oracle 11g r2 sous Solaris 10x86 (update 9) n'utilise pas un segment ISM mais un simple segment SHM !!! Analysons un peu tout cela. 

 

En espectant l'espace d'adresse du process Oracle (ici pmon), j'ai étais surpris de constater que la SGA utilisait un segment SHM classique : 

 

# pmap -x 10735
10735:  ora_pmon_XXXX22
         Address   Kbytes       RSS    Anon   Locked Mode   Mapped File
0000000000400000   222240     91144       -       - r-x--   oracle
000000000DD17000     1180       676     208       - rw---   oracle
000000000DE3E000      136        32      32       - rw---   oracle
000000000DE60000     1828      1644    1632       - rw---   [ heap ]
0000000060000000        4         4       -       - r--s-   [ shmid=0x4000003c ]
0000000060001000  2097156   2028692       -       - rwxs-   [ shmid=0x4000003c ]
FFFFFD7FFCAA0000       64         8       8       - rwx--   [ anon ]
FFFFFD7FFCABE000       72         8       8       - rw---   [ anon ]
FFFFFD7FFCAD0000       64        12      12       - rw---   [ anon ]
[...] 

 

L'initialisation d'un segment type ISM provient du demandeur et non du système. J'ai donc décidé de vérifier les logs de démarrage de l'instance Oracle (fichier alert.log). Je suis tombé sur ce message fort intéressant : 

 

Mon Nov 21 16:38:40 2011
Starting ORACLE instance (normal)
WARNING: Not enough physical memory for SHM_SHARE_MMU segment of size 0x0000000080002000 [flag=0x4000] 

 

Lors de l'activation de l'instance, Oracle a tenté d'activer un segment type ISM sans y être parvenu. Le message indiquant l'erreur suivante : Not enough physical memory for SHM_SHARE_MMU segment. Tiens donc pas assez de mémoire ? Alors que la SGA demandée correspondait à seulement 2 Go ? La vérité était ailleurs... 

 

Pour mieux reproduire le problème, j'ai décidé d'écrire un petit programme C me permettant de créer un segment type ISM. Contrairement à ce que je pensais, ce n'est pas lors de la création du segment que le type ISM est spécifié mais lors d'un attachement. 

 

La création et l'attachement correspondent aux appels suivants :

 

shmget(2, size, 0660 | IPC_CREAT | IPC_EXCL)

shmat(shmid, (void *)0, SHM_SHARE_MMU) 

 

Le flag SHM_SHARE_MMU de la fonction shmat permet l'utilisation de l'ISM. L'exécution de mon petit programme C m'a permis d'activer sans problème un segment ISM de 10 Go. 

 

# ./ishm
shmid: 1526726689


# ipcs -m
IPC status from <running system> as of Tue Jan 10 11:26:10 CET 2012
T         ID      KEY        MODE        OWNER    GROUP
Shared Memory:
m 1526726689   0x2        --rw-rw----     root     root

[...]

 

# pmap -x 24680
24680:  ./ishm
         Address   Kbytes       RSS  Anon    Locked Mode   Mapped File
0000000000400000        4         4     -         - r-x--  ishm
0000000000410000        8         8     8         - rw---  ishm
FFFFFD7F80000000  1048576   1048576     -   1048576 rwxsR  [ ism shmid=0x5b000021 ]
FFFFFD7FFF210000       64        64    64         - rwx--  [ anon ]
FFFFFD7FFF230000       24        12    12         - rwx--  [ anon ]
FFFFFD7FFF240000     1276       712     -         - r-x--  libc.so.1
FFFFFD7FFF380000        4         4     4         - rwx--  [ anon ]
FFFFFD7FFF38F000       36        36    36         - rw---  libc.so.1
FFFFFD7FFF398000       16         4     4         - rw---  libc.so.1
FFFFFD7FFF3AE000      244       244     -         - r-x--  ld.so.1
FFFFFD7FFF3F0000        4         4     4         - rwx--  [ anon ]
FFFFFD7FFF3FB000        8         8     8         - rwx--  ld.so.1
FFFFFD7FFF3FD000        8         8     8         - rwx--  ld.so.1
FFFFFD7FFFDFE000        8         8     8         - rw---  [ stack ]
---------------- -------- --------- ----- ---------
        total Kb  1050280   1049692   156   1048576 

 

Mais où était mon problème ? Oracle doit en faire un peu plus ? J'ai donc tracé les appels systèmes lors du démarrage d'une instance. 

 

[...]
6362:   shmget(672617948, 1073754112, 0660|IPC_CREAT|IPC_EXCL) = 83886086
6362:   shmget(672617949, 0, 0)                         Err#2 ENOENT
6362:   shmget(672617950, 0, 0)                         Err#2 ENOENT
6362:   shmget(672617951, 0, 0)                         Err#2 ENOENT
6362:   shmat(83886086, 0x60000000, 040000)             Err#22 EINVAL
6362:   shmat(83886086, 0x60000000, 0)                  = 0x60000000
[...]

 

Oracle s'attache en spécifiant une adresse mémoire 0x60000000. J'ai donc modifié mon petit programme C en spécifiant la même adresse d'attachement et j'ai obtenu à ma grande surprise l'erreur suivante : 

 

# ./ishm
shmat: Invalid argument

 

J'ai obtenu la même erreur que le démarrage de la base Oracle. Bingo ! Lors de l'appel à la fonction shmat (si on spécifie l'adresse 0x60000000) l'attachement ne s'effectue pas. Mais pourquoi ? Dépassant un peu mes compétances j'ai ouvert un call au support Oracle. 

 

Réponse du support Oracle : la valeur 0x60000000 n'est pas divisible (valeur entière) par l'ensemble des tailles de pages disponibles sur le système Solaris 10x86. Il faut donc désactiver la taille de pages posant problème (option désactivée dans le kernel patch suivant 144489-17). Le workaround n'est pas applicable en production (boot en mode kernel debugging + modification avant chargement du kernel de la valeur largepagesupport). 

 

En vérifiant mes tailles de pages disponibles sur mon serveur DL380 G7, j'obtiens le résultat suivant : 

 

# pagesize -a
4096
2097152
1073741824 

 

Tiens donc, on peut utiliser des tailles de pages de 1Go !? Et bizarrement c'est avec cette taille de pages où la valeur 0x60000000 n'est pas divisible en une valeur entière. L'application du patch supprime la possibilité d'utiliser cette taille de pages. 

 

Voilà donc la fin de la 1er partie sur ISM et Solaris 10x86. La 2ème partie fait référence à un bug dans la gestion de l'ISM uniquement pour Solaris 10x86 (et Solaris 11x86). Bug que j'ai eu le privilège de découvrir en exclusivité... 

 

Ci-joint quelques références sur ce sujet : 

 

Par gloumps - Publié dans : kernel
Ecrire un commentaire - Voir les 1 commentaires

Lundi 24 octobre 2011 1 24 /10 /Oct /2011 20:05

 

Petite anlyse d'un problème survenu sur un serveur Solaris 10. Le contexte était le suivant : dysfonctionnement applicatif, impossible de se connecter au serveur bien que la couche IP semblait active.

 

Généralement je me pose pas de question dans ce genre de cas : je force une prise de dump (afin d'analyser le problème) et reboote le serveur (minimiser l'impact utilisateurs).

 

Avant de se lancer dans l'analyse du core, essayons de comprendre ce message. Le système tente de créer de nouveaux "processus" mais n'y parvient pas par manque de ressource.

 

Questions :

 

- Quelles sont les ressources nécessaires pour la création d'un nouveau processus ?

- Quelles sont les limites possibles ?

 

Un petit tour dans notre librairie : Solaris Internals et plus spécifiquement le chapitre 2 "The Solaris Process Model". La lecture est un peu longue mais très enrichissante... Bref, en vulgarisant beaucoup (désolé pour les puristes), il existe deux limites possibles : une est appliquée au Process, l'autre au Thread.

 

Le système Solaris est capable de créer un nombre déterminé de processus et de threads. Les deux limites Process et Thread sont utilisées à cet effet. La 1er ressource nécessaire à la création d'un processus (ou d'un thread) reste la mémoire (notons cela dans le coin de notre tête). 

 

Revenons un peu à notre crash... Qu'avons nous ?

 

> ::showrev
Hostname: myserver
Release: 5.10
Kernel architecture: sun4u
Application architecture: sparcv9
Kernel version: SunOS 5.10 sun4u Generic_142909-17
Platform: SUNW,SPARC-Enterprise

 

 

Vérifions le nombre de process et threads actif sur le serveur au moment du crash

 

> ::walk proc !wc -l
   14041

> ::walk thread !wc -l
   63017

 

Les limites ne sont pas atteintes, cependant le nombre de threads semble assez important. Une autre façon de savoir si le nombre de process a été atteinte est d'utiliser la variable suivante :

 

> fork_fail_pending/D
fork_fail_pending:
fork_fail_pending:       0  

 

 

Le problème semble provenir d'une allocation mémoire. Deux cas possible, le serveur ne disposait plus de mémoire virtuelle ou la table mémoire d'allocation des process (ou thread) est pleine. Le 1er cas ne semble pas possible (on aurait saturé la totalité de la mémoire virtuelle, ce qui provoque du swap... lire ce petit article). Intéressons nous au 2ème cas. L'allocation mémoire dans la table kernel concerne les threads.

 

> ::kmastat
cache                        buf    buf    buf    memory     alloc alloc
name                        size in use  total    in use   succeed  fail
------------------------- ------ ------ ------ --------- --------- -----
kmem_magazine_1               16  10662  27940    450560    244998     0
kmem_magazine_3               32   5701  32258   1040384    498170     0
kmem_magazine_7               64   5318  23495   1515520    436661     0
kmem_magazine_15             128   4544  24822   3227648    454626     0

[...]

segkp_16384                16384      0      0         0         0     0
segkp_24576                24576      0      0         0         0     0
segkp_32768                32768  63080  63080 2067005440  14589775 1429945523
segkp_40960                40960      0      0         0         0     0
[...]

------------------------- ------ ------ ------ --------- --------- -----
Total [static]                                 110821376 1078194013     0
Total [hat_memload]                            483278848 1120195850     0
[...]
Total [umem_np]                                 12320768    556204     0
Total [segkp]                                  2146041856 186166476 1429945523
Total [zfs_file_data_buf]                      3911852032   9675276     0

[...]

 

 

Nous avons plusieurs demandes d'allocation en erreur pour le cache segkp. La taille de ce cache semble trop petite par rapport au nombre important de threads que le système gére. Pour résoudre ce problème il est nécessaire d'augmenter la taille de ce cache (un peu de lecture).

 

Conseil, si vous utilisez un serveur fortement mutualisé (bcp de process et threads), n'oublie pas d'allouer un peu plus de mémoire au kernel (notamment la table segkp).

Par gloumps - Publié dans : kernel
Ecrire un commentaire - Voir les 1 commentaires

Samedi 20 août 2011 6 20 /08 /Août /2011 10:05

 

Petit sujet qui m'a tenu en haleine un petit moment... Pour situer un peu le contexte, nous obtenions des hangs sur plusieurs bases de données Oracle (hang pouvant dépasser l'heure) situés sur plusieurs serveurs et plusieurs baies SAN. La seule alerte obtenue était ce message d'erreur "WARNING: aiowait timed out" dans l'alert.log des bases. Pour le support Oracle bases de données, ce type de message provient d'un problème sur la couche IO du serveur.

 

Analysons déjà ce que veut dire cette alerte : Oracle effectue une écriture de type KAIO sur un fichier. Le temps de réalisation de cette écriture ne doit pas dépasser 10 minutes sinon Oracle l'indique via ce message d'erreur. Ce qui veut dire qu'entre la demande et la réalisation de cette écriture il y a eu un délai supérieur à 10 minutes... 10 minutes pour réaliser une IO ??? De quoi devenir fou...

 

Ne disposant d'aucune alerte système, l'investigation commençait difficilement. La première chose à faire dans ce type de cas s'est d'obtenir un maximum de traces pour pouvoir investiguer correctement le problème. Nous avons donc mis en place un script détectant l'anomalie dans l'alert.log des bases. Ce script exécute à la fois un Livecore et une prise de traces via l'outil Guds (je me suis inspiré de l'article suivant).

 

Je vous passe le fait que le script n'a pas fonctionné tout le temps... Les prises de traces exploitables n'ont absolument rien montré qui pouvaient expliquer notre problème (rien dans les traces iostat, la charge des systèmes était correcte, etc..). Je me suis concentré uniquement sur les IO. Pour ne pas m'éparpiller entre les différents serveurs, baies, bases, j'ai décidé d'analyser le problème sur une seule base (un serveur et une baie mutualisés).

 

J'ai écrit un petit script Dtrace me permettant de calculer le temps passé pour chaque appel KAIO. Ceci m'a permis de vérifier, cette latence de 10 minutes que la base de données Oracle indiquée.

 

# cat ./aiowait.d
#!/usr/sbin/dtrace -qs

 fbt:kaio:aiowait:entry
/execname == "oracle"/
{
        self->ts = timestamp;
}

fbt:kaio:aiowait:return
/self->ts && (timestamp - self->ts)/1000000 > 60/
{
        self->duration = (timestamp - self->ts)/1000000;
        printf("%Y %20s %8d %12d %12d\n", walltimestamp, execname, pid, tid, self->duration);
        self->duration = 0;
}

 

# ./aiowait.d
[...]
2011 Jul 19 23:45:40       oracle    14583       1        67
2011 Jul 19 23:45:39       oracle    14583       1        89
2011 Jul 19 23:45:40       oracle    14583       1        61
2011 Jul 19 23:45:40       oracle      714       1       127
[...]
2011 Jul 19 23:58:39       oracle    14583       1    600100
2011 Jul 19 23:58:39       oracle    14583       1      3014
2011 Jul 19 23:58:38       oracle    14583       1       908
2011 Jul 19 23:58:39       oracle    14583       1     36730 
[...] 

 

Si vous interprétez correctement cet output, on remarque des temps de latence entre l'entrée et la sortie de la fonction aiowait supérieurs à 60 millisecondes pour la plupart des KAIO mais surtout une latence supérieur à 10 minutes. Incroyable voilà ce que je me suis dis... Une latence de 10 minutes pour une écriture... Oracle dit vrai !!!

 

Ce qu'il faut bien comprendre c'est qu'une demande de lecture et / ou écriture se décompose en plusieurs couches dans le système. Une couche logique (opération vfs, opération vnode, file system, cache) et ensuite une couche physique. Suite à ma première constatation j'ai d'abord vérifié la couche physique (c'est la plus facile à analyser). Pour ce faire, j'ai utilisé le petit script Dtrace suivant.

 

# cat ./fsiolantency.d
#!/usr/sbin/dtrace -Cs

#pragma D option quiet
#pragma D option defaultargs

dtrace:::BEGIN
{
#if defined(ZONENAME)
        uzone = ZONENAME;
#else
        uzone = "";
#endif

#if defined(EXECNAME)
        uexec = EXECNAME;
#else
        uexec = "";
#endif

#define PROBE_SWITCH \
        ((uzone == "" || uzone == zonename) && \
                (uexec == "" || uexec == execname))
}

io:::start
/PROBE_SWITCH/
{
        start[arg0] = timestamp;
}

io:::done
/start[arg0]/
{
        @time["disk I/O latency (ns)", args[2]->fi_mount, args[0]->b_flags & B_READ ? "R" : "W"] = quantize(timestamp - start[arg0]);
        start[arg0] = 0;
}


# ./fsiolantency.d -D ZONENAME='"zone1'" -D EXECNAME='"oracle"'
^C 

disk I/O latency (ns)     /zones/zone01/root/ZONE01/oradata02         W                                              
           value  ------------- Distribution ------------- count
         1048576 |                                         0
         2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           1112
         4194304 |@@@@@@@@@@                               104
         8388608 |                                         0

 disk I/O latency (ns)    /zones/zone01/root/ZONE01/oradata03         R                                             
           value  ------------- Distribution ------------- count
          131072 |                                         0
          262144 |@@@@@@@@@@@@@@@@@@@                      2408
          524288 |@@                                       231
         1048576 |@@                                       230
         2097152 |                                         0
         4194304 |@@@@@                                    1023
         8388608 |@@@@@@@@@@@@                             1940
        16777216 |                                         0

 disk I/O latency (ns)    /zones/zone01/root/ZONE01/oraredo01         W                                             
           value  ------------- Distribution ------------- count
         1048576 |                                         0
         2097152 |@@@@@@@@@@@@@@@@@@@@@@@                  2013
         4194304 |@@@@@@@@@@@@@@@@@                        1870
         8388608 |                                         0

 disk I/O latency (ns)    /zones/zone01/root/ZONE01/oradata01         R                                              
           value  ------------- Distribution ------------- count
          131072 |                                         0
          262144 |@@@@@@@                                  498
          524288 |@@                                       156
         1048576 |                                         0
         2097152 |                                         0
         4194304 |@@@@@@@@@@@@                             750
         8388608 |@@@@@@@@@@@@@@@@@@                       1134
        16777216 |@@                                       134
        33554432 |                                         0

 disk I/O latency (ns)    <none>                                      R                                              
           value  ------------- Distribution ------------- count
          131072 |                                         0
          262144 |@@@@@@@@@@@@@@@                          158
          524288 |@@                                       27
         1048576 |                                         0
         2097152 |                                         0
         4194304 |@@@@@@@@@@@@@                            139
         8388608 |@@@@@@@@@@@                              114
        16777216 |                                         0

 disk I/O latency (ns)    /zones/zone01/root/ZONE01/oradata01         W                                              
          value  ------------- Distribution ------------- count
          524288 |                                         0
         1048576 |@@@@@@@                                  44
         2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           202
         4194304 |@@@                                      519
         8388608 |                                         153
        16777216 |                                         0

 disk I/O latency (ns)    /zones/zone01/root/ZONE01/oradata03         W                                             
           value  ------------- Distribution ------------- count
          524288 |                                         0
         1048576 |@@@@@@@                                  968
         2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@           2309
         4194304 |@@@                                      528
         8388608 |                                         42
        16777216 |                                         0

 disk I/O latency (ns)    <none>                                      W                                             
           value  ------------- Distribution ------------- count
          524288 |                                         0
         1048576 |@@@@@@@@@@@                              913
         2097152 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@             13482
         4194304 |@                                        418
         8388608 |                                         25
        16777216 |                                         0

 

 

Les résultats obtenus étaient correctes. Les IO physiques (lecture et écriture) se déroulaient dans des temps très convenables. Le problème ne se situait donc pas sur les baies. Donc dans le système... Mais où ? Je me suis donc plonger dans la lecture de "Solaris Internals" et "Configuring and Tuning Databases on the Solaris Platform" pour compendre ce qui se passait entre l'écriture demandée par Oracle (usermode) et l'écriture sur le device (IO physique). J'imaginais qu'il y avait un lock mais lequel ?

 

Une chose s'est révélée intéressante : les "Reader/Writer" locks (voir chapitre 17.6 dans "Solaris Internals"). Un seul thread à la fois peut accéder en écriture à un fichier. Voilà quelque chose de fort intéressant... J'ai donc écrit un petit script Dtrace en utilisant la probe lockstat (spécifiquement rw-block) pour obtenir les temps d'attente pour ce type de lock.

 

# cat rwlock.d
#!/usr/sbin/dtrace -Cs

#pragma D option quiet

lockstat::rw_enter:rw-block
/execname == "oracle" && arg1 > 1000000000 && zonename == "zone01"/

{
          printf("%Y %20s %8d %12d %12d %12d",walltimestamp,execname,pid,tid,arg1,arg2);
}

 

# ./rwlock.d
2011 Jul 21 00:01:13     oracle    21289       223   4238043920        0
2011 Jul 21 00:01:13     oracle    21289        88   4628837600        0
2011 Jul 21 00:01:13     oracle    21289       212   4351952245        0
2011 Jul 21 00:01:13     oracle    21289       238   4929624480        0
[...]

2011 Jul 21 00:01:18     oracle    21289       208   8635095680        0
[...]

2011 Jul 21 00:01:20     oracle    21289       195  12103783200        0
2011 Jul 21 00:01:20     oracle    21289       235  11806798240        0
2011 Jul 21 00:01:20     oracle    21289        43  11860924640        0
^C
2011 Jul 21 00:01:21     oracle    21289       226  13598520640        0
2011 Jul 21 00:01:21     oracle    21289        26  13602492640        0
2011 Jul 21 00:01:21     oracle    21289        46  13493121680        0
2011 Jul 21 00:01:21     oracle    21289        56  13310176960        0
2011 Jul 21 00:01:21     oracle    21289        64  13236565680        0
2011 Jul 21 00:01:21     oracle    21289        73  13197836080        0
2011 Jul 21 00:01:21     oracle    21289        75  13198641840        0
2011 Jul 21 00:01:21     oracle    21289        76  13199566320        0
2011 Jul 21 00:01:21     oracle    21289        71  12498137520        0

 

J'obtenais des "Writer" Locks supérieurs à 12 secondes !!! J'ai donc décicidé de faire tourner ces deux petits scripts (rwlock.d et aiowait.d) en même temps afin de voir si mes soupçons étaient corrects. Et bingo... Lors d'un message "WARNING: aiowait timed out", la somme des temps pour les "Writer Locks" était supérieur à 10 minutes (certains "Writer Lock" dépassaient 1 minute).

 

Mon gros soucis avec cette analyse était la suivante. J'avais la conviction que le soucis se situer sur ce type de lock mais impossible de l'affirmer. En effet, l'analyse s'avère exact si et seulement si il s'agit du même fichier qui est accéder. J'ai donc demandé au support Oracle système de me fournir un script Dtrace pouvant m'indiquer à la fois le type de lock "Reader/Writer", le temps de lock mais surtout le nom du fichier sur lequel le lock attendait. Le script fournit par le support - un grand Merci à Alexandre et Alain - nous a permis de mettre en relation l'alerte Oracle "WARNING: aiowait timed out" avec le nom du fichier (le plus souvent les fichiers undo et les tempfiles). 

 

Résumons la situation : des temps IO vu d'Oracle dépassant les 10 minutes, des IO physiques inférieurs à 30 millisecondes, des "Writers Locks" dépensant la minutes... ???!!! Lors d'une demande d'écriture sur un fichier, le système vérifie si le fichier est déjà accédé, si celui-ci est accédé alors il place cette demande dans une queue de type turnstile. Une fois la ressource disponible (ici le fichier) l'écriture physique peut s'effectuer. Lors d'une forte activité d'écriture sur un fichier, toutes les demandes s'empilent dans la queue. La dernière requête de la queue prendra donc un certains à se réaliser (c'est une FIFO). Il s'agit du mode fonctionnement POSIX d'un système de fichiers (UFS, VxFS, TMPFS).

 

Comment contourner ce problème ? Plusieurs solutions possibles : l'une d'elles est d'augmenter le nombre de fichiers (pour nous il s'agissait des fichiers undo et tempfiles). En augmentant le nombre de fichiers on augmente le nombre de queues (donc moins de locks par queue). L'autre solution consite à passer les systèmes de fichiers en accès directio. En effet le mode directio supprime les "Reader/Writer" locks : la couche applicative se débrouille pour gérer les accès concurents aux fichiers. Les bases de données Oracle savent très bien le faire (quelques infos dans cette article). Mais voilà, le passage en directio supprime certes ces locks mais supprime aussi l'effect du "cache filesystem". Toutes les lectures s'effectueront directement sur les disques physiques (pour pallier à ce problème il faut augmenter impérativement les SGA de vos bases de données).

 

Un sacré problème réglé...

 

P.S. : c'est pas évident d'être clair, n'hésitez pas à me demander des informations supplémentaires sur ces aspects. Je tiens à le souligner encore mais sans un outil comme Dtrace (n'oublions pas mdb) ce type d'analyse est pratiquement impossible. Un grand merci au support Oracle (base de données et système) pour toute l'aide apporté à la résolution de ce problème.

Par gloumps - Publié dans : kernel
Ecrire un commentaire - Voir les 1 commentaires

Mercredi 17 août 2011 3 17 /08 /Août /2011 20:26

 

Même si je ne pratique pas depuis longtemps dans le monde Unix (un peu plus de 10 ans) c'est l'une des 1er fois où je rencontre un cas de "Hard Swapping" sous Solaris. Situons un peu le contexte : depuis plusieurs jours un serveur sous Solaris 10 se retrouvait pratiquement tous les jours sur le prompt avec aucun message d'erreur (console et système). Malgrè la mise à jour corrective de l'OBP, rien n'y faisait, le serveur continuait à se retrouver continuellement sur le prompt. En intervenant par hasard sur un autre problème, j'ai intercepté une alerte provenant de ce fameux serveur "serveur non joignable".

 

L'examen via le déport m'indiquait aucune anomalie : alimentation, aucun message à la console, aucune interruption hard. La console répondait bizarrement aux commandes mais aucune réponse du système... Hop un petit break et une génération d'un petit core au passage histoire d'analyser un peu tout ça. Mon expérience dans ce type de cas m'oriente généralement vers un problème de "Swapping".

 

Je commence par vérifier ce que contenait mes queues CPU lors du crash...


# mdb -k 0

>
> ::cpuinfo
ID ADDR        FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD      PROC
  0 30003990000  1d    7    0  98  yes    no t-134  2a100781ca0 pageout
  1 30003994000  1d    2    6  -1   no    no t-0    2a100629ca0 (idle)
  2 30003998000  1d    1    0  -1   no    no t-0    2a100679ca0 (idle)
  3 0000183a628  1b    7    0 165  yes    no t-11   2a100047ca0 sched

 

C'est vraiment intéressant cette fonction pageout()... Cela confirme mon soupçon sur un problème provoqué par du "swapping"


> 30003990000::cpuinfo -v

 ID ADDR        FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD      PROC
  0 30003990000  1d    7    0  98  yes    no t-134  2a100781ca0 pageout
                  |    |
       RUNNING <--+    +-->  PRI THREAD      PROC
      QUIESCED                60 30008786380 cron
        EXISTS                60 30004861c20 aws_orb
        ENABLE                60 3000e307840 nsrexecd
                              60 300052d41c0 java 
                              60 3000539d0c0 inetd
                              60 300052d8200 svc.configd
                              60 30007789ae0 dataserver

 

Regardons de plus près ce que la cpu "id 3" tentait de faire

 

> 0000183a628::cpuinfo -v
ID ADDR        FLG NRUN BSPL PRI RNRN KRNRN SWITCH THREAD      PROC
  3 0000183a628  1b    7    0 165  yes    no t-11   2a100047ca0 sched
                  |    |    |
       RUNNING <--+    |    +--> PIL THREAD
         READY         |           6 2a100047ca0
        EXISTS         |           - 2a100751ca0 pageout
        ENABLE         |
                       +-->  PRI THREAD      PROC
                              60 30008784360 cron
                              60 30007164760 adclient
                              60 30007fa1c40 dataserver
                              60 30005128400 python
                              60 3000dcc8b00 java
                              60 3000d7b9280 aws_sadmin
                              60 30003b563e0 naviagent

> 2a100751ca0::threadlist -v
            ADDR             PROC              LWP CLS PRI            WCHAN000002a100751ca0      60027254468                0   0  97                0

  PC: ktl0+0x48    THREAD: pageout_scanner()
  stack pointer for thread 2a100751ca0: 2a100750f91
  [ 000002a100750f91 ktl0+0x48() ]
    checkpage+0x78()
    pageout_scanner+0x3f4()
    thread_start+4()

 

Le "Page scanner" est bien en cours de fonctionnement (voir sched.c). Vérifions un peu les valeurs liées aux "Swapping".


> avefree/E

avefree:
avefree:          2871
> minfree/E
minfree:
minfree:          8029
> freemem/E
freemem:
freemem:          2888
> needfree/E
needfree:
needfree:        18322
> freemem_wait/D
freemem_wait:
freemem_wait:      426

 

Pour le coup le rapport avefree < minfree est avéré... confirmation de mon hypothèse... On ne dispose plus beaucoup de pages libre (freemem) et le nombre de thread en attente est de 426 (freemem_wait). Voir dans le code vm_page.c pour les explications.

 

Nous sommes donc en présence d'un cas de "Hard Swapping". Ce mode est beaucoup plus agressif que le "Soft Swapping". Une fois activé l'algorithme peut décider de unloader un module kernel non utilisé pour libérer des pages mémoires. Ce qui explique que mon serveur ne répondait plus...

 

> ::modinfo !grep ip
 58         7b600000   144040   1 ip (IP STREAMS driver 1.47)
 82         7bb61cd8      590   1 ip6 (IP6 STREAMS driver 1.9)
146                0        0   0 ipsecesp (?)
147                0        0   0 ipsecah (?)
200                0        0   0 ippctl (?)
223         7afcc000     83a8   1 fcip (SunFC FCIP v20091105-1.50)
242         7aa42000    2dd90   1 ipf (IP Filter: v4.1.9)
253         7b7f8d38     1300   1 ipc (common ipc code)

 

Pour les habitués il manque le "module ip". Petite vérification sur le serveur en fonctionnement


# modinfo | grep ip

58 7b600000 144040   3   1  ip (IP STREAMS driver 1.47)
58 7b600000 144040   -   1  ip (IP STREAMS module 1.47)
[. . .] 

 

J'ai réussi à mettre en pratique un cas rare que j'avais étudié il y a déjà quelques temps. Faut dire des problèmes de "Swapping" sur les infras actuelles sont de plus en plus rare. Pour les mordus de lecture, je vous renvois au chapitre 10 de "Solaris Internals".

Par gloumps - Publié dans : kernel
Ecrire un commentaire - Voir les 0 commentaires

Présentation

Informations personnelles

  • Passionné d'informatique, je travaille actuellement comme expert système Solaris. Vous trouverez plus de renseignements à mon sujet sur mon profil Linkedin.

Flux RSS

  • Flux RSS des articles

Recherche

Calendrier

Février 2012
L M M J V S D
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29        
<< < > >>
Créer un blog gratuit sur over-blog.com - Contact - C.G.U. - Signaler un abus - Articles les plus commentés