Overblog
Suivre ce blog
Editer l'article Administration Créer mon blog
9 janvier 2012 1 09 /01 /janvier /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 : 

 

Partager cet article

Published by gloumps - dans kernel
commenter cet article

commentaires

Gege 15/01/2012 10:10

Mais a quand la suite ?? J'attends avec impatience le dénouement de cette histoire.