Últimos Cambios |
||
Blog personal: El hilo del laberinto |
Última Actualización: 10 de enero de 2012
Desde que Solaris 10 permite arrancar el sistema desde un "zpool", mis servidores tienen un "zpool" llamado "datos", que contiene TODO. Las ventajas fundamentales de tener un "zpool" unificado son:
La gran ventaja de tener el sistema separado en su propio "zpool" es que existen restricciones en la configuración de un "zpool" "root". Por ejemplo, no se permite utilizar RAIDZ/Z2/Z3, o un ZIL separado en su propio dispositivo SSD. O podemos hacer cosas como tener una versión "zpool" baja, compatible con un GRUB antiguo y con cosas como OpenSolaris u OpenIndiana, mientras que los datos en sí residen en otro "zpool" utilizando la última versión de ZFS.
En este artículo voy a describir cómo dividir un "zpool" unificado en dos, uno para el sistema operativo y otro para los datos. En una máquina en producción.
Esta máquina tiene dos discos duros en "mirror" ZFS, formando un "zpool" unificado. También tiene dos SSD utilizados como L2ARC y sistema de recuperación catastrófico. También se usarán como ZIL en cuanto divida el "zpool", porque no se puede usar un ZIL separado en un "zpool" "root". De hecho éste es el motivo para dividir el "zpool".
[root@XXX /]# zpool remove datos c4t0d0s2 [root@XXX /]# zpool create sistema c4t0d0s2 [root@XXX /]# zfs set compression=on sistema [root@XXX /]# cat datos/boot/grub/menu.lst [...] title Solaris10u10FLASH #findroot (BE_Solaris10u10,0,a) root (hd0,0,c) bootfs sistema/ROOT/Solaris10u10 kernel$ /platform/i86pc/multiboot -B $ZFS-BOOTFS module /platform/i86pc/boot_archive title Solaris10u10FLASH failsafe #findroot (BE_Solaris10u10,0,a) root (hd0,0,c) bootfs sistema/ROOT/Solaris10u10 kernel /boot/multiboot -s module /boot/amd64/x86.miniroot-safe title Solaris10u10 #findroot (BE_Solaris10u10,0,a) root (hd2,0,a) bootfs datos/ROOT/Solaris10u10 kernel$ /platform/i86pc/multiboot -B $ZFS-BOOTFS module /platform/i86pc/boot_archive title Solaris10u10 failsafe #findroot (BE_Solaris10u10,0,a) root (hd2,0,a) bootfs datos/ROOT/Solaris10u10 kernel /boot/multiboot -s module /boot/amd64/x86.miniroot-safe [root@XXX /]# zfs snapshot datos@FLASH; zfs snapshot -r datos/ROOT@FLASH [root@XXX /]# zfs send datos@20110801-14:26 | zfs receive -Fduv sistema receiving full stream of datos@20110801-14:26 into sistema@20110801-14:26 received 172MB stream in 4 seconds (43.0MB/sec) [root@XXX /]# zfs send -I @20110801-14:26 datos@FLASH | zfs receive -Fduv sistema [...] [root@XXX /]# zfs send -R datos/ROOT@FLASH | time zfs receive -Fduv sistema [...] real 17:29.8 user 0.0 sys 1:24.9 [root@XXX /]# zpool set bootfs=sistema/ROOT/Solaris10u10 sistema [root@XXX /]# zpool set failmode=continue sistema [root@XXX /]# init 6 [...]
Lo primero que hacemos es quitar uno de los SSD del servicio L2ARC y crear el nuevo "zpool" "sistema" en él. Activar la compresión por defecto (usa LZJB) nos permite ganar un poco de espacio manteniendo un "zpool" compatible con el arranque vía GRUB y con una carga de CPU despreciable. A continuación configuramos el "menu.lst" para permitir arrancar desde la SSD (la máquina está hospedada de forma remota, pero tenemos acceso por KVM, teclado, video y ratón virtuales).
El siguiente paso es hacer un "snapshot" del sistema operativo y enviarlo a la SSD. Como se puede ver, la operación es bastante rápida, 17 minutos, y la máquina sigue en producción todo el tiempo. Gracias al uso de "snapshots", sabemos que la copia que estamos haciendo va a ser consistente, aunque la copia lleve un tiempo y el disco se sigue modificando.
El último paso consiste en configurar un par de propiedades del "zpool" y reiniciar el servidor. Y cruzar los dedos, claro
En el menú de arranque GRUB seleccionaremos "Solaris10u10FLASH". Si hubiese cualquier tipo de problema, bastaría arrancar de forma normal, "Solaris10u10", arrancando del disco duro. Hasta ahora no hemos hecho nada irreversible.
El arranque funciona a la primera, y nos aseguramos de que estamos cargando el sistema operativo desde el nuevo "dataset" "sistema". Bien.
Sigamos...
[root@XXX /]# zfs destroy -r datos@FLASH [root@XXX /]# zpool scrub datos [root@XXX /]# zpool status datos pool: datos state: ONLINE scan: scrub in progress since Sat Jan 7 09:11:58 2012 5.14M scanned out of 1.20T at 478K/s, (scan is slow, no estimated time) 5.14M scanned out of 1.20T at 478K/s, 747h14m to go 0 repaired, 0.00% done config: NAME STATE READ WRITE CKSUM datos ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 c4t2d0s0 ONLINE 0 0 0 c4t3d0s0 ONLINE 0 0 0 cache c4t1d0s2 ONLINE 0 0 0 errors: No known data errors (Esperamos a que el "scrub" se complete. En mi caso supone unas 8 horas) [root@XXX /]# format (Reconfiguramos los "slices" Solaris del disco duro) [root@XXX /]# zpool attach sistema c4t0d0s2 c4t2d0s0 Make sure to wait until resilver is done before rebooting. [root@XXX /]# zpool status sistema pool: sistema state: ONLINE status: One or more devices is currently being resilvered. The pool will continue to function, possibly in a degraded state. action: Wait for the resilver to complete. scan: resilver in progress since Sat Jan 7 09:21:53 2012 981M scanned out of 12.0G at 39.2M/s, 0h4m to go 981M scanned out of 12.0G at 39.2M/s, 0h4m to go 980M resilvered, 7.97% done config: NAME STATE READ WRITE CKSUM sistema ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 c4t0d0s2 ONLINE 0 0 0 c4t2d0s0 ONLINE 0 0 0 (resilvering) errors: No known data errors (Esperamos a que el "resilvering" termine) [root@XXX< /]# zpool status sistema pool: sistema state: ONLINE scan: resilvered 12.0G in 0h7m with 0 errors on Sat Jan 7 09:28:58 2012 config: NAME STATE READ WRITE CKSUM sistema ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 c4t0d0s2 ONLINE 0 0 0 c4t2d0s0 ONLINE 0 0 0 errors: No known data errors [root@XXX /]# zfs destroy -r datos/ROOT [root@XXX /]# cat /sistema/boot/grub/menu.lst [...] title Solaris10u10 #findroot (BE_Solaris10u10,0,a) root (hd2,0,a) bootfs sistema/ROOT/Solaris10u10 kernel$ /platform/i86pc/multiboot -B $ZFS-BOOTFS module /platform/i86pc/boot_archive title Solaris10u10 failsafe #findroot (BE_Solaris10u10,0,a) root (hd2,0,a) bootfs sistema/ROOT/Solaris10u10 kernel /boot/multiboot -s module /boot/amd64/x86.miniroot-safe (Editamos el entorno de "Live Upgrade", en "/etc/lu/ICF.*" y "/etc/lutab")
A continuación borramos los "snapshots" origen, que ya no necesitamos. Lo que haremos a continuación es romper el "mirror" ZFS. Esto, claro, siempre me pone nervioso (con razón), así que lo primero que hago es realizar un "scrubbing" del "mirror", de forma que estamos seguros de que ambos discos duros funcionan bien y todos los datos son correctos en AMBOS. Si hubiese cualquier tipo de error en un disco, se corregiría con el contenido el otro. El tiempo necesario para que esta operación se complete depende del volumen de datos que tengamos en el disco, no de su capacidad. En mi caso, este proceso termina en unas ocho horas. Ambos discos están bien.
El riesgo que conjuramos aquí es romper el "mirror" y luego encontrarnos con que el disco que nos queda contiene errores que YA no es posible corregir, porque no tiene "mirror". Haciendo un "scrub" nos aseguramos de que todo va bien. La única ventana de error ahora entonces es que el disco que queda desarrolle errores en las horas que tardaremos en completar el procedimiento, y antes de volver a asociarle un "mirror". Es un riesgo calculado. Instintivamente compruebo, poniéndome en el peor de los casos, que mis backups son recientes y funcionan, y echo cuentas mentales de cuánto tardaría en recuperar el servicio en el improbable pero posible caso de que ocurra un fallo hardware del disco duro durante esta ventana.
Una vez que hemos hecho lo posible para evitar problemas, rompemos el "mirror". Ahora "datos" reside solo en uno de los discos, el otro está "libre". Lo "formateamos", creando dos "slices" Solaris que ocupan todo el disco duro. El primer "slice", de unos 27 GB, lo pongo en la parte exterior del disco duro, donde la transferencia es más rápida. Ese tamaño es el tamaño del "zpool" "sistema" que creamos en el SSD. El resto del disco duro lo asigno a otro "slice", que contendrá un futuro "zpool" llamado "datos".
Pongo el sistema en la parte rápida del disco duro porque el "zpool" del sistema no va a tener cacheo L2ARC (lectura) ni ZIL (escritura).
Añadimos a "sistema" el "slice" que acabamos de crear, como "mirror". Solaris empezará a copiar a toda la velocidad el contenido de la SSD al disco duro. Copiar 12 GB tarda 7 minutos (salen unos 28MB/s).
Ahora que tenemos "sistema" en "mirror" en la SSD y uno de los discos duros, borramos el sistema operativo de "datos" (estas dos versiones no se "pegan" entre sí, porque sus "datasets" están configurados para no ser montados por defecto, sino que solo se monta automáticamente al arrancar el sistema el "dataset" que efectivamente hemos seleccionado en el GRUB). Reconfiguramos el GRUB de nuevo para arrancar desde el disco duro (que ahora contiene uno de los "mirrors" de "sistema"). Osea, lo dejamos como al principio, cambiando "datos" por "sistema".
Como uso "Live Upgrade", me toca editar a mano un par de ficheros de configuración. Los cambios deberían ser evidentes, y se trata de ficheros de texto pequeños.
Por supuesto, la máquina sigue en producción TODO el tiempo (salvo los reinicios que se indican).
[root@XXX /]# zpool create datos2 c4t2d0s1 [root@XXX /]# umount /datos2 [root@XXX /]# zfs snapshot -r datos@CONVERSION [root@XXX /]# zfs send -R datos@CONVERSION | time zfs receive -Fduv datos2 [...] real 6:08:55.3 user 0.2 sys 23:33.1 [root@XXX /]# zfs snapshot -r datos@CONVERSION2 [root@XXX /]# zfs send -R -I @CONVERSION datos@CONVERSION2 | time zfs receive -Fduv datos2 [...] real 7:17.7 user 0.2 sys 9.9 (Paramos las zonas Solaris) [root@XXX /]# zfs snapshot -r datos@CONVERSION3 [root@XXX /]# zfs send -R -I @CONVERSION2 datos@CONVERSION3 | time zfs receive -Fduv datos2 real 3:19.3 user 0.1 sys 1.2 (Entramos al servidor vía KVM) (Reiniciamos el servidor y entramos en modo "failsafe") # mkdir z # zpool import -f -R /tmp/root/z datos # zpool destroy datos # zpool import -f -R /tmp/root/z datos2 datos # init 6
El siguiente paso es replicar "datos" en el disco B en el segundo "slice" del disco A. Creo un "zpool" llamado "datos2", hago un "snapshot" de los datos originales y los copio en "datos2". Es más de un terabyte de datos, así que lleva un buen rato. La máquina sigue en producción, todo el tiempo, haciendo cambios en el disco (bases de datos, correo, logs, etc), pero como hemos hecho un "snapshot", sabemos que la copia será consistente.
Por supuesto los cambios que se produzcan en el disco duro original no se propagan a la copia. Normal, estamos mandando un "snapshot". Así que tras duplicar los datos originales, unas seis horas, hacemos un segundo "snapshot" y enviamos los cambios INCREMENTALES que se han producido en estas seis horas. Esa transferencia supone unos siete minutos. Ahora paramos las "zonas" Solaris, que son las que están haciendo cambios en el disco. Como todos mis servicios están en zonas Solaris, si dejamos funcionando solo la zona "global", los cambios en el disco son mínimos y limitados al sistema operativo, que ya hemos separado en "sistema". A efectos prácticos, "datos" ya no se modifica, o no en formas que nos importe conservar. Ahora hacemos un tercer "snapshot" y lo transferimos en tres minutos.
En este momento, "datos" y "datos2" contienen lo mismo.
Ahora llega la parte delicada: arrancamos el ordenador en el modo a prueba de fallos, donde no se monta apenas nada, ni se arranca ningún servicio. Destruimos "datos" y renombramos "datos2" a "datos". Obśervese cómo se renombra un "zpool": se renombra haciendo un "import" indicando un nombre de importación explícito. No lo sabía, he tenido que buscarlo :-).
Reiniciamos y cruzamos los dedos. Todo funciona a la perfección.
Continuemos...
[root@XXX /]# format (Reconfiguramos los "slices" Solaris en el segundo disco duro de forma idéntica al primer disco duro) [root@XXX /]# zpool attach sistema c4t2d0s0 c4t3d0s0 Make sure to wait until resilver is done before rebooting. [root@XXX /]# zpool status sistema pool: sistema state: ONLINE scan: resilvered 12.2G in 0h7m with 0 errors on Sat Jan 7 18:08:43 2012 config: NAME STATE READ WRITE CKSUM sistema ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 c4t0d0s2 ONLINE 0 0 0 c4t2d0s0 ONLINE 0 0 0 c4t3d0s0 ONLINE 0 0 0 errors: No known data errors [root@XXX /]# zpool detach datos c4t0d0s2 [root@XXX /]# zfs destroy -r sistema@FLASH [root@XXX /]# zfs destroy -r datos@CONVERSION [root@XXX /]# zfs destroy -r datos@CONVERSION2 [root@XXX /]# zfs destroy -r datos@CONVERSION3 [root@XXX /]# zpool add datos cache c4t0d0s2 [root@XXX /]# zpool add datos cache c4t1d0s2 [root@XXX /]# zpool add datos log mirror c4t0d0s1 c4t1d0s1 [root@XXX /]# zpool attach datos c4t2d0s1 c4t3d0s1 [root@XXX /]# zpool status datos pool: datos state: ONLINE status: One or more devices is currently being resilvered. The pool will continue to function, possibly in a degraded state. action: Wait for the resilver to complete. scan: resilver in progress since Sat Jan 7 18:16:13 2012 623M scanned out of 1.18T at 13.5M/s, 25h25m to go 623M scanned out of 1.18T at 13.5M/s, 25h25m to go 623M resilvered, 0.05% done config: NAME STATE READ WRITE CKSUM datos ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 c4t2d0s1 ONLINE 0 0 0 c4t3d0s1 ONLINE 0 0 0 (resilvering) logs mirror-1 ONLINE 0 0 0 c4t0d0s1 ONLINE 0 0 0 c4t1d0s1 ONLINE 0 0 0 cache c4t0d0s2 ONLINE 0 0 0 c4t1d0s2 ONLINE 0 0 0 errors: No known data errors (Esperamos a que termine la sincronización del "mirror") [root@XXX /]# zpool status datos pool: datos state: ONLINE scan: resilvered 1.18T in 3h54m with 0 errors on Sat Jan 7 22:11:10 2012 config: NAME STATE READ WRITE CKSUM datos ONLINE 0 0 0 mirror-0 ONLINE 0 0 0 c4t2d0s1 ONLINE 0 0 0 c4t3d0s1 ONLINE 0 0 0 logs mirror-1 ONLINE 0 0 0 c4t0d0s1 ONLINE 0 0 0 c4t1d0s1 ONLINE 0 0 0 cache c4t0d0s2 ONLINE 0 0 0 c4t1d0s2 ONLINE 0 0 0 errors: No known data errors
Ahora que hemos destruido el "zpool" "datos", el segundo disco duro está vació. Lo formateamos con una configuración idéntica al primer disco (dos "slices" Solaris, el pequeño en la parte exterior y rápida del disco duro). Añado un tercer "mirror" al "zpool" "sistema". Ahora tenemos una copia en cada disco duro y en una "SSD".
Una vez que la reconstrucción del tercer componente del "mirror" termina, quitamos la SSD del "mirroring", liberándola. Nos quedamos con un "mirror" de dos componentes, los dos discos duros. Es de señalar que durante la reconstrucción del disco duro B, dos tercios de los datos provienen de la SSD, y un tercio del otro disco duro.
Luego hacemos limpieza, eliminando los "snapshots" que creamos para transferir la información.
El siguiente paso es añadir las SSD como L2ARC y ZIL, tal y como explico en "ZFS y SSD's".
Por último, añadimos el "slice" grande del segundo disco al "zpool" "datos" y esperamos a que la sincronización del "mirror" se complete.
El resultado es la separación completa de un "zpool" unificado a dos "zpools": sistema operativo y datos. De forma rápida, limpia y segura.
Un par de detalles:
[root@XXX z]# cat cache_display.txt disk 2 cache read_cache display quit write_cache display quit quit disk 3 cache read_cache display quit write_cache display quit quit [root@XXX z]# format -e <cache_display.txt Searching for disks...done [...] Specify disk (enter its number): selecting c4t2d0 [disk formatted] /dev/dsk/c4t2d0s0 is part of active ZFS pool sistema. Please see zpool(1M). /dev/dsk/c4t2d0s1 is part of active ZFS pool datos. Please see zpool(1M). [...] read_cache> Read Cache is enabled [...] write_cache> Write Cache is enabled [....] Specify disk (enter its number)[2]: selecting c4t3d0 [disk formatted] /dev/dsk/c4t3d0s0 is part of active ZFS pool sistema. Please see zpool(1M). /dev/dsk/c4t3d0s1 is part of active ZFS pool datos. Please see zpool(1M). [...] read_cache> Read Cache is enabled [...] write_cache> Write Cache is enabled
Si no fuese el caso, habría que escribir un script SMF para activar la caché de escritura de forma manual al reiniciar el ordenador. En este caso Solaris es lo bastante inteligente como para decidir que es seguro activar la caché de escritura (ZFS envía "cache flush" cuando es necesario).
Más información sobre los OpenBadges
Donación BitCoin: 19niBN42ac2pqDQFx6GJZxry2JQSFvwAfS