En mai 2005, la documentation Partitions sur disque Solaris (format, prtvtoc, newfs) présentait la création de partitions sur un disque et le montage de systèmes de fichiers ufs sous Solaris 8. Avec Solaris 10, la nouveauté des ZFS (Zone File Systems) simplifie énormément la configuration des volumes et systèmes de fichiers avec des éléments de configuration évolués (compression, checksum, recordsize, casesensitivity, utf8only etc...). Des fonctionnalités encore plus puissantes sont disponibles avec ZFS comme les snapshots mais ne sont pas abordées ici. Il s'agit uniquement d'une prise en main rapide de ZFS.
Dans ce guide pratique, sans rentrer dans les détails très techniques systèmes de l'OS, des systèmes de fichiers ZFS sont créés pour monter une instance Oracle 10gR2 sur une plateforme Solaris X86 64bits. Quelques paragraphes abordent également le cache ARC de ZFS pour configurer et récupérer les statistiques mémoire pour ZFS.
L'article n'aborde pas la mise en place de RAIDs ou de miroirs disques dans les zones de stockage ZFS.
Les systèmes de fichiers ZFS ci-dessous sont créés pour une nouvelle instance Oracle :
| Point de montage ZFS | Taille (Gb) | Taille de bloc |
|---|---|---|
| /sop/oracle/SOPT1ORA | 40 | 8k |
| /sop/oracle/SOPT1ORA/redolog | 2 | 128k |
| /sop/oracle/SOPT1ORA/archivelog | 10 | 128k |
Dans les préconisations Oracle autour de ZFS, il est conseillé de définir la taille du bloc ZFS égale à la taille de bloc définie dans l'instance Oracle pour les données: la taille de bloc du système ZFS /sop/oracle/SOPT1ORA supportant les fichiers de données de l'instance Oracle est donc définie à 8k, la taille de bloc définie au niveau de l'instance Oracle étant à 8k (db_block_size=8192).
Pour les fichiers de redo log et archivelog, avec leur caractère circulaire, il est conseillé d'utiliser la taille de bloc ZFS système, soit 128k : les systèmes de fichiers ZFS /sop/oracle/SOPT1ORA/redolog et /sop/oracle/SOPT1ORA/archivelog supportant respectivement les fichiers de redo log et archivelog sont ainsi définis avec une taille de bloc à 128k.
Le compte Unix oracle est créé avec la commande useradd avec le super utilisateur root. Dans la norme de cet article, le compte oracle a pour userid 1001 et il est affecté dans le groupe dba (id : 101).
Pour vérifier que le groupe dba existe effectivement avec le groupe id 101, consulter le fichier /etc/group :
shell> cat /etc/group | grep 'dba'
dba::101:
Si ce groupe n'existe pas, la commande Unix groupadd avec le compte root peut être utilisée :
shell> groupadd [ -g gid [-o]] group
groupadd -g 101 dba
Le compte Unix oracle est alors créé avec la commande useradd :
shell> useradd [-c comment] [-d dir] [-e expire] [-f inactive]
[-g group] [-G group [, group...]] [-m [-k skel_dir]]
[-u uid [-o]] [-s shell] [-A authorization [,authorization...]]
[-P profile [,profile...]] [-R role [,role...]]
[-p projname] [-K key=value] login
Dans ce cas pratique, pour le compte Unix Oracle, le shell par défaut est Korn Shell ( -s /bin/ksh), son groupe est dba ( -g101 ou -Gdba), son id est 1001 (-u1001) et son répertoire par défaut est /Software/oracle (-d /Software/oracle).
shell> useradd -d /Software/oracle -g101 -u1001 -s/bin/ksh oracle
Pour vérifier la bonne création du compte Unix oracle, consulter le fichier /etc/passwd :
shell> cat /etc/passwd | grep 'oracle'
oracle:x:1001:101::/Software/oracle:/bin/ksh
À l'issue de la création du compte unix Oracle, son répertoire par défaut /Software/oracle est créé avec la commande mkdir et oracle devient le propriétaire du répertoire /Software/oracle avec la commande chown :
shell> mkdir /Software/oracle
shell> chown oracle:dba /Software/oracle
Le mot de passe du compte Unix oracle est ensuite initialisé avec le binaire passwd :
shell> passwd oracle New Password: ******* Re-enter new Password: ******* passwd: password successfully changed for oracle
Avec Solaris 10, un nouveau service de contrôle de ressources (resource control facility) fait son entrée. Ce contrôleur de ressources permet de définir des paramètres systèmes spécifiques (comme la mémoire partagée, les sémaphores etc...) à un compte Unix ou un groupe de comptes Unix. Les paramètres systèmes ne sont donc plus définis globalement pour tous les comptes dans le fichier /etc/system, ils peuvent être définis au cas par cas, ce qui se révèle être particulièrement pratique pour des comptes Unix comme oracle, mq etc... qui ont des besoins très particuliers sur la mémoire partagée, les sémaphores etc... paramètres que l'on ne souhaite pas forcément appliquer en environnement mutualisé pour d'autres comptes applicatifs Unix présents sur la machine.
Pour définir ces contrôles de ressources, un projet est créé pour un compte Unix ou un groupe Unix, projet qui est ensuite activé.
Ainsi dans un premier temps, le projet user.oracle est ajouté avec la commande projadd pour le compte Unix oracle :
shell> projadd -U <user> <project_name>
shell> projadd -U oracle user.oracle
Le projet user.oracle est alors automatiquement démarré lors de la première connexion avec le compte oracle sur la machine. Lorsqu'il n'y a pas de projet user.oracle démarré (0 connexion avec le compte oracle), ce projet peut être démarré manuellement avec la commande newtask en tant que super utilisateur (root) :
shell> newtask -p <project_name>
shell> newtask -p user.oracle
La commande prstat -J indique effectivement la mise en route du projet user.oracle :
shell> prstat -J
PROJID NPROC SWAP RSS MEMORY TIME CPU PROJECT
0 42 700M 799M 2.4% 58:55:02 0.3% system
100 2 2156K 5276K 0.0% 0:00:00 0.0% user.oracle
3 4 1596K 3500K 0.0% 0:03:54 0.0% default
1 8 3456K 6136K 0.0% 0:00:06 0.0% user.root
En se connectant avec le compte oracle, la commande id -p donne le projet associé :
oracle@ERBIUM# id -p
uid=1001(oracle) gid=101(dba) projid=100(user.oracle)
Depuis la version 10 de Solaris, la configuration système de la mémoire partagée, des sémaphores et des "message queues" autorisée pour un compte Unix n'est plus définie dans le fichier /etc/system mais dans le nouveau fichier des projets /etc/project, fichier mis à jour avec les binaires projmod ou prctl.
Beaucoup de paramètres systèmes pour la mémoire partagée et les sémaphores ont désormais des valeurs par défaut qui ont été augmentées avec Solaris 10 ou bien sont devenus obsolètes. D'une façon générale, les valeurs par défaut des paramètres systèmes Solaris étant supérieures aux préconisations Oracle, seule la mémoire partagée maximale doit être généralement définie pour le compte oracle.
Le tableau ci-dessous récapitule les paramètres Solaris modifiés ou devenus obsolètes entre la version 9 et la version 10. Les valeurs par défaut pour Solaris 10 sont données pour comparaison avec les préconisations des valeurs minimales Oracle.
| Solaris 9 /etc/system | Préconisation Oracle | Solaris 10 /etc/project | Valeur par défaut Solaris 10 | |
|---|---|---|---|---|
| noexec_user_stack | 1 | x Obsolète | x | |
| semsys:seminfo_semmni | 100 | project.max-sem-ids | 128 | |
| semsys:seminfo_semmns | 1024 | x Obsolète | x | |
| semsys:seminfo_semmsl | 256 | project.max-sem-nsems | 512 | |
| semsys:seminfo_semvmx | 32767 | x Obsolète | x | |
| shmsys:shminfo_shmmax | 4294967295 | project.max-shm-memory | 2 Gb | |
| shmsys:shminfo_shmmin | 1 | x Obsolète | x | |
| shmsys:shminfo_shmmni | 100 | project.max-shm-ids | 128 | |
| shmsys:shminfo_shmseg | 10 | x Obsolète | x |
Le tableau montre clairement que bien souvent la mémoire partagée doit être définie pour Oracle avec Solaris 10.
Le paramètre shmsys.shminfo_shmmax pour la valeur maximale de la mémoire partagée anciennement défini dans le fichier /etc/system est remplacé par project.max-sh-memory avec le contrôleur de ressources Solaris 10.
Une mémoire partagée maximale de 8 Gb (max-sh-memory, max value of shared memory segment) est définie pour le projet user.oracle avec la commande projmod :
shell> projmod -sK "project.max-shm-memory=(priv,8G,deny)" user.oracle
Elle peut être également définie avec le binaire prctl
shell> prctl -n project.max-shm-memory -v 8gb -r -i project user.oracle
Le fichier /etc/project donne alors les entrées ci-dessous :
shell> cat /etc/project
system:0:::: user.root:1:::: noproject:2:::: default:3:::: group.staff:10:::: user.oracle:100::oracle::project.max-shm-memory=(priv,8589934592,deny)
Pour tous les autres paramètres systèmes (max-sem-ids etc...), il suffit juste de vérifier que les valeurs par défaut de la machine Solaris 10 sont supérieures aux préconisations Oracle avec la commande prctl pour le projet user.oracle.
Exemple pour le paramètre max-sem-ids recommandé à 100 par oracle
shell> prctl -n project.max-sem-ids -i project user.oracle
project: 100: user.oracle
NAME PRIVILEGE VALUE FLAG ACTION RECIPIENT
project.max-sem-ids
privileged 128 - deny -
system 16.8M max deny -
Si ce n'est pas le cas, la valeur est modifiée également pour le projet user.oracle avec le binaire prctl.
Exemple :
prctl -n project.max-sem-ids -v 100 -r -i project user.oracle
La commande zfs list permet de répertorier les zones de stockage ZFS disponibles avec leurs éventuels points de montage déjà associés (mountpoint).
shell> zfs list
shell> zfs list NAME USED AVAIL REFER MOUNTPOINT DEVICES1 117K 535G 18K none DEVICES2 117K 402G 18K none rpool 67.0G 66.9G 35.5K /rpool rpool/ROOT 3.89G 20.1G 18K legacy rpool/ROOT/s10x_u6wos_07b 3.89G 20.1G 3.89G / rpool/SOFTWARE 21.5K 8.00G 21.5K /Software rpool/UNIXADM 61.5M 962M 61.5M /unixadm rpool/dump 1.00G 66.9G 1.00G - rpool/export 199M 825M 19K /export rpool/export/home 199M 825M 199M /export/home rpool/swap 32G 98.9G 16K -
Dans la configuration initiale, 2 ZFS DEVICES1 (535 Gb) et DEVICES2 (402 Gb) sont disponibles.
La zone de stockage ZFS DEVICES1 va être utilisée pour créer les points de montage pour l'instance Oracle, à savoir :
/sop/oracle/SOPT1ORA
/sop/oracle/SOPT1ORA/redolog
/sop/oracle/SOPT1ORA/archivelog
La commande zpool et ses paramètres multiples permet de créer, lister, configurer les propriétés et supprimer des réservoirs (pools) de stockage ZFS depuis les disques. zpool status est utilisé pour visualiser le statut des pools de stockage ZFS et notamment le(s) disques associé(s), le(s) miroir(s), le(s) RAID(s). La création et la suppression de ces pools ZFS depuis les disques ne sont pas couvertes dans cet article.
shell> zpool status <device>
shell> zpool status DEVICES1
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
DEVICES1 ONLINE 0 0 0
c4t0d0 ONLINE 0 0 0
errors: No known data errors
L'exemple ci-dessus permet de voir rapidement que la zone de stockage ZFS DEVICES1 est associé au disque c4t0d0.
Lorsque du miroir est mis en place ou du RAID, les informations renvoyées par la commande zpool status sont plus complexes mais bien plus lisibles que dans les versions précédentes de Solaris. Voici un exemple de miroir :
shell> zpool status rpool
pool: rpool
state: ONLINE
scrub: none requested
config:
NAME STATE READ WRITE CKSUM
rpool ONLINE 0 0 0
mirror ONLINE 0 0 0
c3t2d0s0 ONLINE 0 0 0
c3t0d0s0 ONLINE 0 0 0
errors: No known data errors
3 zones ZFS vont être créées dans le device DEVICES1 avec la commande zfs create :
| Zone ZFS | Point de montage futur | Description |
|---|---|---|
| DEVICES1/SOPT1ORA_DATA | /sop/oracle/SOPT1ORA | Fichier de données de l'instance Oracle (8k) |
| DEVICES1/SOPT1ORA_RLOG | /sop/oracle/SOPT1ORA/redolog | Fichiers de redo log de l'instance Oracle (128k) |
| DEVICES1/SOPT1ORA_ALOG | /sop/oracle/SOPT1ORA/archivelog | Fichiers archive log de l'instance Oracle (128k) |
Voici l'enchaînement de la création de ces 3 zones :
zfs create DEVICES1/SOPT1ORA_DATA zfs create DEVICES1/SOPT1ORA_RLOG zfs create DEVICES1/SOPT1ORA_ALOG
Pour appliquer les quota nécessaires (40 Gb pour le futur système de fichiers /sop/oracle/SOPT1ORA par exemple) et la taille des blocs, la commande "zfs set" est utilisée avec la propriété adéquate :
zfs set property=value filesystem|volume
Pour les quotas :
zfs set quota=<n>K|M|G filesystem|volume
zfs set quota=40G DEVICES1/SOPT1ORA_DATA zfs set quota=2G DEVICES1/SOPT1ORA_RLOG zfs set quota=10G DEVICES1/SOPT1ORA_ALOG
Pour les tailles de blocs lorsqu'il ne s'agit pas de volumes, c'est la propriété recsize ou recordsize (les deux syntaxes sont acceptées) : la taille des blocs est forcément une puissance de deux supérieure ou égale à 512 octets et inférieure ou égale à 128Ko.
zfs set recsize=[512b ... 128k] filesystem|volume
Cette propriété peut être modifiée à chaud, mais il faut garder à l'esprit que seuls les nouveaux fichiers créés auront la taille des blocs nouvellement appliquée dans la zone.
zfs set recsize=8k DEVICES1/SOPT1ORA_DATA zfs set recsize=128k DEVICES1/SOPT1ORA_RLOG zfs set recsize=128k DEVICES1/SOPT1ORA_ALOG
À noter que l'application des propriétés quota et recsize est également possible depuis la commande zfs create avec l'option -o :
zfs create -orecsize=8k -oquota=40g DEVICES1/SOPT1ORA_DATA zfs create -orecsize=128k -oquota=2g DEVICES1/SOPT1ORA_RLOG zfs create -orecsize=128k -oquota=10g DEVICES1/SOPT1ORA_ALOG
La commande zfs get permet de lister les propriétés appliquées à une zone ZFS.
zfs get "all"|property[,...] [filesystem|volume|snapshot]
Lorsque le système de fichiers, le volume ou le snapshot n'est pas spécifié, les propriétés de toutes les zones ZFS sont affichées en sortie.
Exemple :
zfs get recsize,quota DEVICES1/SOPT1ORA_ALOG NAME PROPERTY VALUE SOURCE DEVICES1/SOPT1ORA_ALOG recordsize 128K local DEVICES1/SOPT1ORA_ALOG quota 10G local
La définition des points de montage pour les systèmes de fichiers ZFS créés précédemment peut alors être réalisée avec la commande zfs set mountpoint.
zfs set mountpoint=<répertoire de point de montage> filesystem|volume
Les points de montage qui vont être créés sont les suivants
Les 2 propriétés canmount et mountpoint des ZFS sont très importantes :
zfs get mountpoint,canmount DEVICES1/SOPT1ORA_DATA NAME PROPERTY VALUE SOURCE DEVICES1/SOPT1ORA_DATA mountpoint none local DEVICES1/SOPT1ORA_DATA canmount on default
Si la propriété mountpoint est à legacy ou none et qu'elle est remplacée, le système de fichiers ZFS est automatiquement monté. La propriété canmount permet également de déterminer si les systèmes de fichiers peuvent être montés.
Le répertoire /sop/oracle/SOPT1ORA est donc créé dans un premier temps, sans créér les sous répertoires /sop/oracle/SOPT1ORA/archivelog et /sop/oracle/SOPT1ORA/redolog, en effet si les répertoires archivelog et redolog sont créés, l'avertissement suivant est donné au moment de la définition de la propriété mountpoint :
zfs set mountpoint=/sop/oracle/SOPT1ORA DEVICES1/SOPT1ORA_DATA cannot mount '/sop/oracle/SOPT1ORA': directory is not empty property may be set but unable to remount filesystem
De même, il ne faut pas se positionner dans le répertoire /sop/oracle/SOPT1ORA lors la définition de la propriété mounpoint. Dans ce cas là, l'avertissement suivant est donné :
zfs set mountpoint=/sop/oracle/SOPT1ORA DEVICES1/SOPT1ORA_DATA cannot mount 'DEVICES1/SOPT1ORA_DATA': mountpoint or dataset is busy property may be set but unable to remount filesystem
La cinématique suivante de définition des propriétés mountpoint est donc la suivante :
shell> cd / shell> mkdir /sop shell> mkdir /sop/oracle shell> mkdir /sop/oracle/SOPT1ORA shell> zfs set mountpoint=/sop/oracle/SOPT1ORA DEVICES1/SOPT1ORA_DATA shell> mkdir /sop/oracle/SOPT1ORA/archivelog shell> zfs set mountpoint=/sop/oracle/SOPT1ORA/archivelog DEVICES1/SOPT1ORA_ALOG shell> mkdir /sop/oracle/SOPT1ORA/redolog shell> zfs set mountpoint=/sop/oracle/SOPT1ORA/redolog DEVICES1/SOPT1ORA_RLOG
La propriété canmount étant définie à on, dès l'application de la propriété mountpoint, la commande df -k montre immédiatement l'apparition des systèmes de fichiers zfs
shell> df -k
DEVICES1/SOPT1ORA_DATA
41943040 20 41943020 1% /sop/oracle/SOPT1ORA
DEVICES1/SOPT1ORA_ALOG
10485760 18 10485742 1% /sop/oracle/SOPT1ORA/archivelog
DEVICES1/SOPT1ORA_RLOG
2097152 18 2097134 1% /sop/oracle/SOPT1ORA/redolog
Par défaut tous les systèmes de fichiers ZFS sont montés lors de l'initialisation à l'aide du service SMF (Service Management Facility).
Lorsque le montage doit être réalisé manuellement et non en automatique, la commande zfs mount est utilisé :
zfs mount -a|filesystem
La commande mdb -k avec l'option ::memstat permet d'avoir une vision globale de la mémoire disponible sur une machine Solaris
echo ::memstat | mdb -k
Page Summary Pages MB %Tot ------------ ---------------- ---------------- ---- Kernel 587481 2294 7% Anon 180366 704 2% Exec and libs 6684 26 0% Page cache 7006 27 0% Free (cachelist) 13192 51 0% Free (freelist) 7591653 29654 91% Total 8386382 32759 Physical 8177488 31943
Dans l'exemple ci-dessus, il s'agit d'une machine disposant de 32 Gb de mémoire physique.
ZFS utilise un cache noyau (cache kernel) appelé ARC pour les I/Os. Pour connaître la taille du cache I/O à un instant t utilisée par ZFS, utiliser l'option kmastat avec la commande mdb -k et repérer la statistique Total [zio_buf] :
echo ::kmastat | mdb -k
cache buf buf buf memory alloc alloc name size in use total in use succeed fail ------------------------- ------ ------ ------ --------- --------- ----- ... Total [zio_buf] 1157632000 1000937 0 ...
Dans l'exemple ci-dessus, le cache I/O ZFS utilise 1,1 G en mémoire
Pour les machines disposant d'une quantité de mémoire très importante, il est préférable de limiter le cache I/O ZFS pour éviter tout débordement de mémoire sur les autres applications. Dans la pratique ce cache augmente et diminue dynamiquement en fonction des besoins des applications installées sur la machine, mais il est préférable de le limiter pour prévenir tout risque. Le paramètre zfs_arc_max (en bytes) dans le fichier /etc/system permet de limiter la quantité de mémoire au cache I/O ZFS. Ci-dessous un exemple ou le cache I/O ZFS est limité à 4Gb
cat /etc/system
... set zfs:zfs_arc_max = 4294967296 ...
De même il est possible de spécifier la quantité de mémoire minimale à allouer au cache I/O ZFS avec le paramètre zfs_arc_min dans le fichier /etc/system.
La commande kstat avec l'option zfs donne des statistiques détaillées sur le cache ZFS ARC (hits, misses, taille etc...) à un instant t : on retrouve la valeur maximale possible (c_max) pour ce cache, la taille courante (size) dans la sortie de cette commande. Dans l'exemple ci-dessous, le paramètre zfs_arc_max n'a pas encore été appliqué, ce qui explique que la taille maximale possible correspond à la mémoire physique de la machine.
kstat zfs
module: zfs instance: 0
name: arcstats class: misc
c 33276878848
c_max 33276878848
c_min 4159609856
crtime 121.419237623
deleted 497690
demand_data_hits 14319099
demand_data_misses 6491
demand_metadata_hits 45356553
demand_metadata_misses 33470
evict_skip 2004
hash_chain_max 4
hash_chains 1447
hash_collisions 1807933
hash_elements 40267
hash_elements_max 41535
hdr_size 6992496
hits 60821130
l2_abort_lowmem 0
l2_cksum_bad 0
l2_evict_lock_retry 0
l2_evict_reading 0
l2_evict_reading 0
l2_feeds 0
l2_free_on_write 0
l2_hdr_size 0
l2_hits 0
l2_io_error 0
l2_misses 0
l2_rw_clash 0
l2_size 0
l2_writes_done 0
l2_writes_error 0
l2_writes_hdr_miss 0
l2_writes_sent 0
memory_throttle_count 0
mfu_ghost_hits 3387
mfu_hits 53995731
misses 48704
mru_ghost_hits 1180
mru_hits 5891117
mutex_miss 0
p 21221559296
prefetch_data_hits 237031
prefetch_data_misses 3520
prefetch_metadata_hits 908447
prefetch_metadata_misses 5223
recycle_miss 0
size 1362924368
snaptime 14013729.1668961
module: zfs instance: 0
name: vdev_cache_stats class: misc
crtime 121.419271852
delegations 4453
hits 27353
misses 9753
snaptime 14013729.1677954
La commande zfs unmount permet de démonter un système de fichiers pour une zone ZFS. L'option -f est indispensable si des applications sont encore actives sur cette zone ZFS (à utiliser avec prudence)
shell> zfs unmount [-f] -a|filesystem|mountpoint
shell> zfs unmount /sop/oracle/SOPT1ORA/redolog
Tous les fichiers présents sur ce point de montage ne sont pas détruits avec la commande zfs unmount, ils sont là au remontage.
La commande zfs destroy permet de détruire une zone ZFS. Comme pour la commande zfs unmount, l'option -f est indispensable si des applications sont encore actives sur cette zone ZFS (à utiliser avec prudence). La commande zfs destroy détruit tous les fichiers éventuellement présents sur cette zone ZFS.
shell> zfs destroy [-rRf] filesystem|volume|snapshot
shell> zfs destroy DEVICES1/SOPT1ORA_RLOG
| Version | Date | Commentaires |
|---|---|---|
| 1.0 | 08/2009 | Version initiale |
Sun Solaris, Managing ZFS File Systems
ZFS Demonstration Tutorial
Oracle 10gR2, configuring Kernel
Parameters for Solaris X86 64 bits