Dès la version 12.2 d'Oracle, l'utilisation d'ASM devient quasi obligatoire... mais cela fait bien longtemps que je m'y suis mis compte tenu de tous les avantages que j'y trouve.
Ces jours, je dois passer d'une baie de disque à une autre. C'est une opération assez aisée... mais comment effectuer cette tâche sans déni de service ?
Voici ma méthode
Attribution de nouveaux disques
Mes administrateurs système m'ont fait apparaître les nouveaux disques dans mon /dev/mapper
J'ai donc mes anciens disques qui se nomment ORA_xxx et mes nouveaux qui se nomment SAN_xxx
Via ASM, il faut donc ajouter les nouveaux disques, puis supprimer les anciens... et laisser le système positionner les données sur les nouveaux disques
On peut le faire d'un coup, via la commande
Code SQL : | Sélectionner tout |
alter diskgroup ORA_DVP_DAT add disk '/dev/mapper/SAN_DVP_DAT' drop disk ORA_DVP_DAT_0000 rebalance power 11;
C'est une action asynchrone, donc il convient de bien attendre que cette phase de resynchroniation soit terminée
Code SQL : | Sélectionner tout |
1 2 | select NAME DG, OPERATION, O.STATE, EST_MINUTES, ERROR_CODE , POWER from v$asm_operation O inner join v$asm_diskgroup G on G.group_number=O.group_number ; |
Code SQL : | Sélectionner tout |
1 2 3 4 5 6 | set pagesize100 col path format a50 select G.name, D.name, D.free_MB, D.total_MB, ltrim(to_char(100-(100.0/D.total_MB*D.free_MB), '999G99')||'%','%') Restant, D.path from v$asm_disk D inner join v$asm_diskgroup G on G.group_number=D.group_number where D.STATE='DROPPING' ; |
Lorsque cela est terminé, les anciens disques semblent libres d'être décommissionnés...
Code SQL : | Sélectionner tout |
1 2 3 4 5 6 | select name, path from v$asm_disk where name is null ; NAME PATH ====== ==================================== [NULL] /dev/mapper/ORA_DVP_DAT [NULL] /dev/mapper/ORA_DVP_FRA |
Aïe !
... et c'est là que les choses se corsent...
Lorsque je demande au processus multipath de retirer un disque, j'obtiens cette erreur :
Code SHELL : | Sélectionner tout |
1 2 3 | [root ~]# multipath -f ORA_DVP_DAT -v3 Dec 06 07:33:21 | ORA_DVP_DAT: map in use Dec 06 07:33:21 | unloading const prioritizer |
...ce qui tente à prouver que, malgré ce que je crois, le disque semble encore occupé.
Bon... le support technique Oracle va donc vous demander de redémarrer ASM afin de "gommer" le problème... mais j'ai dit "SANS DoS"!
Via commande Linux, je peux effectivement noter qu'un processus Oracle à toujours un file descriptor ouvert sur mon disque.
Code SHELL : | Sélectionner tout |
1 2 3 4 5 6 7 | lsof /dev/mapper/ORA_WIN_DAT COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ora_lg00_ 831 oracle 256u BLK 253,11 0t0 22695 /dev/mapper/../dm-11 ora_lg01_ 835 oracle 256u BLK 253,11 0t0 22695 /dev/mapper/../dm-11 oracle_12 1200 oracle 256u BLK 253,11 0t0 22695 /dev/mapper/../dm-11 oracle_42 4230 oracle 256u BLK 253,11 0t0 22695 /dev/mapper/../dm-11 ora_rbal_ 9939 oracle 303u BLK 253,11 0t0 22695 /dev/mapper/../dm-11 |
Via ASMCMD et la commande lsof -G NomDG, on peut faire le lien entre disque et disk group.
En seconde colonne, on trouve donc les PID ayant un file descriptor encore ouvert
En 4e colonne, le descripteur (FD), ici 256
On se rend donc dna /proc/{No PID}/fd
Code SHELL : | Sélectionner tout |
1 2 3 4 | cd /proc/831/fd ls -d |grep dm lrwx------. 1 oracle oinstall 64 Sep 16 10:15 256 -> /dev/dm-11 lrwx------. 1 oracle oinstall 64 Nov 29 01:05 257 -> /dev/dm-47 |
Ensuite, on utilise gdb sur ce processus
Code SHELL : | Sélectionner tout |
1 2 3 | oracle:/proc/831/fd/ [+ASM3] gdb -p 831 GNU gdb (GDB) Red Hat Enterprise Linux (7.2-92.el6) ... |
et on ferme le descripteur
Code SHELL : | Sélectionner tout |
1 2 3 4 5 6 7 8 | (gdb) call close(256) $1 = 0 (gdb) quit A debugging session is active. Inferior 1 [process 831] will be detached. Quit anyway? (y or n) y |
On répète l'intervention sur tous les descripteurs et processus ouverts.
Ouf!
On peut ensuite décommissionner le disque sans souci... et sans arrêt/redémarrage de ASM.
Un grand merci à mon collègue Ray Fox qui m'a bien aidé sur ce coup !