mai 102012
 

No exemplo abaixo eu crio 10 arquivos de 1GB cada, para utilizar como discos para o ASM, para testes.

dd if=/dev/zero of=/asmdisks/_file_disk1 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk2 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk3 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk4 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk5 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk6 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk7 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk8 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk9 bs=1k count=1000000
dd if=/dev/zero of=/asmdisks/_file_disk10 bs=1k count=1000000

lofiadm -a /asmdisks/_file_disk1
lofiadm -a /asmdisks/_file_disk2
lofiadm -a /asmdisks/_file_disk3
lofiadm -a /asmdisks/_file_disk4
lofiadm -a /asmdisks/_file_disk5
lofiadm -a /asmdisks/_file_disk6
lofiadm -a /asmdisks/_file_disk7
lofiadm -a /asmdisks/_file_disk8
lofiadm -a /asmdisks/_file_disk9
lofiadm -a /asmdisks/_file_disk10

ls -lL /dev/lofi/*

mknod /asmdisks/vdisk1 c 144 1
mknod /asmdisks/vdisk2 c 144 2
mknod /asmdisks/vdisk3 c 144 3
mknod /asmdisks/vdisk4 c 144 4
mknod /asmdisks/vdisk5 c 144 5
mknod /asmdisks/vdisk6 c 144 6
mknod /asmdisks/vdisk7 c 144 7
mknod /asmdisks/vdisk8 c 144 8
mknod /asmdisks/vdisk9 c 144 9
mknod /asmdisks/vdisk10 c 144 10

chown oracle:dba /asmdisks/vdisk1
chown oracle:dba /asmdisks/vdisk2
chown oracle:dba /asmdisks/vdisk3
chown oracle:dba /asmdisks/vdisk4
chown oracle:dba /asmdisks/vdisk5
chown oracle:dba /asmdisks/vdisk6
chown oracle:dba /asmdisks/vdisk7
chown oracle:dba /asmdisks/vdisk8
chown oracle:dba /asmdisks/vdisk9
chown oracle:dba /asmdisks/vdisk10
mai 102012
 

Quando foi criado um Pool do ZFS? Quando tivemos problemas no espelhamento?
Toda a vida de um Pool ZFS pode ser verificada pelo comando zpool history, desde sua criação, até parâmetros alterados e manutenções executadas.
Se utilizado com um Pool como argumento do comando, retorna apenas dados deste Pool. Caso contrário, retorna de todos.

ricardo@solaris:~$ sudo zpool history test
History for 'test':
2012-05-03.08:21:07 zpool create test mirror c3t2d0 c3t3d0
2012-05-04.11:05:46 zfs set compression=on test
2012-05-04.11:08:06 zfs set compression=off test
2012-05-04.11:41:06 zfs set compression=on test
2012-05-04.11:44:10 zfs set compression=gzip-9 test
2012-05-07.05:59:36 zfs set compression=off test
2012-05-07.06:03:06 zfs set dedup=on test
2012-05-07.06:13:32 zfs set dedup=on test
2012-05-09.08:17:17 zpool scrub test
2012-05-09.08:21:47 zpool online test c3t2d0
2012-05-09.08:22:56 zpool online test c3t2d0
2012-05-09.08:23:28 zpool scrub test
2012-05-09.08:27:10 zpool detach test c3t2d0
2012-05-09.09:04:48 zpool attach test c3t3d0 c3t2d0
2012-05-09.09:53:02 zpool export test
2012-05-09.09:53:10 zpool import test
ricardo@solaris:~$ sudo zpool history oradata
History for 'oradata':
2012-05-09.14:18:55 zpool create oradata c3t4d0
ricardo@solaris:~$ sudo zpool history rpool
History for 'rpool':
2012-05-02.10:50:42 zpool create -f rpool c3t0d0s0
2012-05-02.10:50:42 zfs create -p -o mountpoint=/export rpool/export
2012-05-02.10:50:43 zfs set mountpoint=/export rpool/export
2012-05-02.10:50:43 zfs create -p rpool/export/home
2012-05-02.10:50:43 zfs create -p -V 1024m rpool/swap
2012-05-02.10:50:45 zfs set primarycache=metadata rpool/swap
2012-05-02.10:50:45 zfs create -p -V 512m rpool/dump
2012-05-02.11:28:22 zpool set bootfs=rpool/ROOT/solaris rpool
2012-05-02.11:42:22 zfs unmount rpool/ROOT/solaris
2012-05-02.13:30:09 zfs set primarycache=metadata rpool/swap
2012-05-02.13:30:12 zfs create -p rpool/export/home/ricardo
2012-05-02.13:38:04 zfs volsize=8g rpool/swap
2012-05-02.13:38:42 zfs set primarycache=metadata rpool/swap
2012-05-02.13:46:48 zfs set primarycache=metadata rpool/swap
2012-05-02.13:48:16 zfs create -V 8G rpool/swap02
2012-05-02.13:48:52 zfs set primarycache=metadata rpool/swap02
2012-05-03.08:09:00 zfs set primarycache=metadata rpool/swap
2012-05-03.08:14:16 zfs set primarycache=metadata rpool/swap
2012-05-04.07:25:42 zfs set primarycache=metadata rpool/swap
2012-05-04.08:41:03 zfs set primarycache=metadata rpool/swap
2012-05-04.11:03:35 zfs set primarycache=metadata rpool/swap
2012-05-07.05:57:30 zfs set primarycache=metadata rpool/swap
2012-05-08.11:53:31 zfs set primarycache=metadata rpool/swap
2012-05-09.07:36:34 zfs set primarycache=metadata rpool/swap
2012-05-09.07:47:16 zfs set primarycache=metadata rpool/swap
2012-05-09.08:03:48 zfs set primarycache=metadata rpool/swap
2012-05-09.09:01:05 zfs set primarycache=metadata rpool/swap
2012-05-09.10:31:33 zfs set primarycache=metadata rpool/swap
2012-05-09.11:13:24 zfs set primarycache=metadata rpool/swap
2012-05-09.14:17:49 zfs set primarycache=metadata rpool/swap

ricardo@solaris:~$
mai 092012
 

O desempenho de I/O em Pools ZFS deve ser verificado com o comando zpool iostat, e não com o iostat do Solaris.

A opção -Td imprime a data e horário da coleta.
A opção -v traz mais informações sobre cada vdev (discos) indidualmente.
O 10 no final do comando irá imprimir o resultado continuamente a cada 10 segundos, parando somente com Control+C.
O oradata é o Pool que quero monitorar. Se quiser monitorar todos, basta não informar um Pool.

ricardo@solaris:~$ zpool iostat -Td -v -l oradata 10
Wednesday, May  9, 2012 02:33:42 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.91G  97.6G      4     24   848K  3.33M
  c3t4d0    1.91G  97.6G      4     24   848K  3.33M
----------  -----  -----  -----  -----  -----  -----

Wednesday, May  9, 2012 02:33:52 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.90G  97.6G     12     18  1.64M   630K
  c3t4d0    1.90G  97.6G     12     18  1.64M   630K
----------  -----  -----  -----  -----  -----  -----

Wednesday, May  9, 2012 02:34:02 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.90G  97.6G      8      7  3.49M   327K
  c3t4d0    1.90G  97.6G      8      7  3.49M   327K
----------  -----  -----  -----  -----  -----  -----

Wednesday, May  9, 2012 02:34:12 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.90G  97.6G      0     14   205K  1.36M
  c3t4d0    1.90G  97.6G      0     14   205K  1.36M
----------  -----  -----  -----  -----  -----  -----

Wednesday, May  9, 2012 02:34:22 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.93G  97.6G      0     14  51.3K   762K
  c3t4d0    1.93G  97.6G      0     14  51.3K   762K
----------  -----  -----  -----  -----  -----  -----

Wednesday, May  9, 2012 02:34:32 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.93G  97.6G      1      9   154K   604K
  c3t4d0    1.93G  97.6G      1      9   154K   604K
----------  -----  -----  -----  -----  -----  -----

^C
ricardo@solaris:~$ zpool iostat -Td -v -l 10
Wednesday, May  9, 2012 02:34:40 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.93G  97.6G      4     23   859K  3.17M
  c3t4d0    1.93G  97.6G      4     23   859K  3.17M
----------  -----  -----  -----  -----  -----  -----
rpool       34.6G  64.9G     47     29  1.44M  3.25M
  c3t0d0s0  34.6G  64.9G     47     29  1.44M  3.25M
----------  -----  -----  -----  -----  -----  -----
test        1.28G  8.66G      0      0    109    760
  mirror    1.28G  8.66G      0      0    109    760
    c3t3d0      -      -      0      0    744    787
    c3t2d0      -      -      0      0    669    787
----------  -----  -----  -----  -----  -----  -----

Wednesday, May  9, 2012 02:34:50 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.95G  97.5G      3     44   500K   508K
  c3t4d0    1.95G  97.5G      3     44   500K   508K
----------  -----  -----  -----  -----  -----  -----
rpool       34.8G  64.7G     13     76  2.61M  30.9M
  c3t0d0s0  34.8G  64.7G     13     76  2.61M  30.9M
----------  -----  -----  -----  -----  -----  -----
test        1.28G  8.66G      0      0      0      0
  mirror    1.28G  8.66G      0      0      0      0
    c3t3d0      -      -      0      0      0      0
    c3t2d0      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

Wednesday, May  9, 2012 02:35:00 PM BRT
               capacity     operations    bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
oradata     1.95G  97.5G     36     30  8.28M  8.33M
  c3t4d0    1.95G  97.5G     36     30  8.28M  8.33M
----------  -----  -----  -----  -----  -----  -----
rpool       34.8G  64.7G     10      0  1.25M      0
  c3t0d0s0  34.8G  64.7G     10      0  1.25M      0
----------  -----  -----  -----  -----  -----  -----
test        1.28G  8.66G      0      0      0      0
  mirror    1.28G  8.66G      0      0      0      0
    c3t3d0      -      -      0      0      0      0
    c3t2d0      -      -      0      0      0      0
----------  -----  -----  -----  -----  -----  -----

^C
ricardo@solaris:~$
mai 092012
 
projadd -U oracle -K "project.max-shm-memory=(priv,4g,deny)" user.oracle
projmod -sK "project.max-shm-memory=(priv,4g,deny)" user.oracle
projmod -sK "project.max-sem-nsems=(priv,512,deny)" user.oracle
projmod -sK "project.max-sem-ids=(priv,128,deny)" user.oracle
projmod -sK "project.max-shm-ids=(priv,128,deny)" user.oracle
projmod -sK "process.max-file-descriptor=(priv,65536,deny)" user.oracle
mai 092012
 

O ZFS possui a capacidade de self healing, ou seja, auto correção. Quando outro Volume Manager espalharia uma possível corupção de dados, ele faz o contrário.

Para testar esta capacidade no pool test, primeiro verificamos que não há erros.

ricardo@solaris:~$ sudo zpool list
Password:
NAME    SIZE  ALLOC   FREE  CAP  DEDUP  HEALTH  ALTROOT
rpool  99.5G  22.5G  77.0G  22%  1.00x  ONLINE  -
test   9.94G  1.28G  8.66G  12%  4.18x  ONLINE  -
ricardo@solaris:~$ sudo zpool status test
  pool: test
 state: ONLINE
  scan: resilvered 1.28G in 0h9m with 0 errors on Wed May  9 09:12:50 2012
config:

        NAME        STATE     READ WRITE CKSUM
        test        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            c3t3d0  ONLINE       0     0     0
            c3t2d0  ONLINE       0     0     0

errors: No known data errors

Agora vamos criar um arquivo extra para testes, e verificar sua integridade.

ricardo@solaris:/test$ mkfile 1g /test/ArquivoTeste
ricardo@solaris:/test$ md5sum /test/ArquivoTeste > /test/ArquivoTeste.md5
ricardo@solaris:/test$ md5sum --check /test/ArquivoTeste.md5
/test/ArquivoTeste: OK
ricardo@solaris:/test$ ls -lh /test/
total 2097435
-rw-------   1 ricardo  staff       1.0G May  9 09:49 ArquivoTeste
-rw-r--r--   1 ricardo  staff         53 May  9 09:49 ArquivoTeste.md5
drwxr-xr-x   3 ricardo  staff          3 May  7 06:13 Docs01
drwxr-xr-x   3 ricardo  staff          3 May  7 06:16 Docs02
drwxr-xr-x   3 ricardo  staff          3 May  7 06:22 Docs03
drwxr-xr-x   3 ricardo  staff          3 May  7 06:38 Docs04
ricardo@solaris:/test$ df -h /test/
Filesystem             Size   Used  Available Capacity  Mounted on
test                    15G   6.2G       8.4G    43%    /test

Agora vamos causar diversas corrupções em um dos discos, com o comando dd.
Fiz três gravações de dados aleatórios no disco, uma de 1MB, outra de 10MB, e depois uma de 100MB.

ricardo@solaris:/test$ sudo dd if=/dev/urandom of=/dev/dsk/c3t3d0 bs=1024 count=1024
Password:
1024+0 records in
1024+0 records out
ricardo@solaris:/test$ sudo dd if=/dev/urandom of=/dev/dsk/c3t3d0 bs=1024 count=10240
10240+0 records in
10240+0 records out
ricardo@solaris:/test$ sudo dd if=/dev/urandom of=/dev/dsk/c3t3d0 bs=1024 count=102400
102400+0 records in
102400+0 records out

Agora verificamos o estado do pool, e continua tudo em ordem.

ricardo@solaris:/test$ zpool status test
  pool: test
 state: ONLINE
  scan: resilvered 1.28G in 0h9m with 0 errors on Wed May  9 09:12:50 2012
config:

        NAME        STATE     READ WRITE CKSUM
        test        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            c3t3d0  ONLINE       0     0     0
            c3t2d0  ONLINE       0     0     0

errors: No known data errors

Como o ZFS faz um grande uso de cache em memória, acho que ele não detectou ainda a corrupção feita diretamente no disco físico. Vamos então desmontar e montar o pool, e refazer a verificação.

ricardo@solaris:/test$ sudo zpool export test
cannot unmount '/test': Device busy
ricardo@solaris:/test$ cd
ricardo@solaris:~$ sudo zpool export test
ricardo@solaris:~$ sudo zpool import test
ricardo@solaris:~$ zpool status test
  pool: test
 state: ONLINE
status: One or more devices has experienced an unrecoverable error. An attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
        using 'zpool clear' or replace the device with 'zpool replace'.
   see: http://www.sun.com/msg/ZFS-8000-9P
  scan: resilvered 1.28G in 0h9m with 0 errors on Wed May  9 09:12:50 2012
config:

        NAME        STATE     READ WRITE CKSUM
        test        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            c3t3d0  ONLINE       0     0     7
            c3t2d0  ONLINE       0     0     0

errors: No known data errors

Agora sim o ZFS acusou o erro, mas como ele mesmo informa, foi feita uma tentativa de corrigir o erro, e aplicações não foram afetadas. Adicionalmente, o comando informa que deve ser melhor trocar o disco (ele não sabe que eu fiz o dd).
Conferindo a integridade do arquivo de teste, realmente ele continua ok.

ricardo@solaris:~$ ls -lh /test
total 2097435
-rw-------   1 ricardo  staff       1.0G May  9 09:49 ArquivoTeste
-rw-r--r--   1 ricardo  staff         53 May  9 09:49 ArquivoTeste.md5
drwxr-xr-x   3 ricardo  staff          3 May  7 06:13 Docs01
drwxr-xr-x   3 ricardo  staff          3 May  7 06:16 Docs02
drwxr-xr-x   3 ricardo  staff          3 May  7 06:22 Docs03
drwxr-xr-x   3 ricardo  staff          3 May  7 06:38 Docs04
ricardo@solaris:~$ md5sum --check /test/ArquivoTeste.md5
/test/ArquivoTeste: OK
ricardo@solaris:~$
mai 092012
 

Após desligar um servidor com Solaris 11 “no dedo”, várias vezes, um pool espelhado do ZFS teve um dos discos corrompido.
Como era espelhado, os dados continuaram acessíveis.
O comando zpool list mostrava o status problemático do pool.

login as: ricardo
Using keyboard-interactive authentication.
Password:
Last login: Wed May  9 08:09:44 2012 from 192.168.56.1
Oracle Corporation      SunOS 5.11      11.0    November 2011
ricardo@solaris:~$ df -h /test
Filesystem             Size   Used  Available Capacity  Mounted on
test                    14G   5.2G       8.4G    39%    /test
ricardo@solaris:~$ ls -lh /test/
total 12
drwxr-xr-x   3 ricardo  staff          3 May  7 06:13 Docs01
drwxr-xr-x   3 ricardo  staff          3 May  7 06:16 Docs02
drwxr-xr-x   3 ricardo  staff          3 May  7 06:22 Docs03
drwxr-xr-x   3 ricardo  staff          3 May  7 06:38 Docs04
ricardo@solaris:~$ sudo zpool list test
NAME   SIZE  ALLOC   FREE  CAP  DEDUP    HEALTH  ALTROOT
test  9.94G  1.28G  8.66G  12%  4.18x  DEGRADED  -

A comando zpool scrub examina todos os dados de um pool, e se possível, já corrige o problema.
O scrub continua acontecendo em background, e seu progresso (depende do tamanho do pool) pode ser conferido com o comando zpool status.

ricardo@solaris:~$ sudo zpool scrub test
ricardo@solaris:~$ sudo zpool list test
NAME   SIZE  ALLOC   FREE  CAP  DEDUP    HEALTH  ALTROOT
test  9.94G  1.28G  8.66G  12%  4.18x  DEGRADED  -
ricardo@solaris:~$ sudo zpool status test
  pool: test
 state: DEGRADED
status: One or more devices has been removed by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: scrub in progress since Wed May  9 08:16:44 2012
    357M scanned out of 1.28G at 11.9M/s, 0h1m to go
    0 repaired, 27.33% done
config:

        NAME        STATE     READ WRITE CKSUM
        test        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            c3t2d0  REMOVED      0     0     0
            c3t3d0  ONLINE       0     0     0

errors: No known data errors
ricardo@solaris:~$ sudo zpool status test
  pool: test
 state: DEGRADED
status: One or more devices has been removed by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: scrub in progress since Wed May  9 08:16:44 2012
    481M scanned out of 1.28G at 10.0M/s, 0h1m to go
    0 repaired, 36.77% done
config:

        NAME        STATE     READ WRITE CKSUM
        test        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            c3t2d0  REMOVED      0     0     0
            c3t3d0  ONLINE       0     0     0

errors: No known data errors
ricardo@solaris:~$ sudo zpool status test
  pool: test
 state: DEGRADED
status: One or more devices has been removed by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: scrub in progress since Wed May  9 08:16:44 2012
    1.27G scanned out of 1.28G at 7.14M/s, 0h0m to go
    0 repaired, 99.33% done
config:

        NAME        STATE     READ WRITE CKSUM
        test        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            c3t2d0  REMOVED      0     0     0
            c3t3d0  ONLINE       0     0     0

errors: No known data errors

Após o scrub terminar, nenhum erro foi encontrado nos dados, mas o pool continuava sem espelhamento, e o próprio comando zpool status recomendava a subistiuição do disco.

ricardo@solaris:~$ sudo zpool status test
  pool: test
 state: DEGRADED
status: One or more devices has been removed by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: scrub repaired 0 in 0h3m with 0 errors on Wed May  9 08:20:11 2012
config:

        NAME        STATE     READ WRITE CKSUM
        test        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            c3t2d0  REMOVED      0     0     0
            c3t3d0  ONLINE       0     0     0

errors: No known data errors

Tentei colocar o disco em estado online, mas ele continuava com defeito.

ricardo@solaris:~$ sudo zpool online test c3t2d0
warning: device 'c3t2d0' onlined, but remains in faulted state
use 'zpool replace' to replace devices that are no longer present
ricardo@solaris:~$ sudo zpool status test
  pool: test
 state: DEGRADED
status: One or more devices has been removed by the administrator.
        Sufficient replicas exist for the pool to continue functioning in a
        degraded state.
action: Online the device using 'zpool online' or replace the device with
        'zpool replace'.
  scan: scrub repaired 0 in 0h3m with 0 errors on Wed May  9 08:20:11 2012
config:

        NAME        STATE     READ WRITE CKSUM
        test        DEGRADED     0     0     0
          mirror-0  DEGRADED     0     0     0
            c3t2d0  REMOVED      0     0     0
            c3t3d0  ONLINE       0     0     0

errors: No known data errors

Substituí então o disco defeituoso, e refiz o mirror. O comando zpool attach faz com que o segundo disco informado como opção seja adicionado como um espelho do primeiro, já existente e com dados.

ricardo@solaris:~$ sudo zpool detach test c3t2d0
ricardo@solaris:~$ sudo zpool status test
  pool: test
 state: ONLINE
  scan: scrub repaired 0 in 0h2m with 0 errors on Wed May  9 08:25:39 2012
config:

        NAME      STATE     READ WRITE CKSUM
        test      ONLINE       0     0     0
          c3t3d0  ONLINE       0     0     0

errors: No known data errors
ricardo@solaris:~$ sudo zpool attach test c3t3d0 c3t2d0
ricardo@solaris:~$ sudo zpool status test
Password:
  pool: test
 state: ONLINE
  scan: resilvered 1.28G in 0h9m with 0 errors on Wed May  9 09:12:50 2012
config:

        NAME        STATE     READ WRITE CKSUM
        test        ONLINE       0     0     0
          mirror-0  ONLINE       0     0     0
            c3t3d0  ONLINE       0     0     0
            c3t2d0  ONLINE       0     0     0

errors: No known data errors
ricardo@solaris:~$ ls -lh /test
total 12
drwxr-xr-x   3 ricardo  staff          3 May  7 06:13 Docs01
drwxr-xr-x   3 ricardo  staff          3 May  7 06:16 Docs02
drwxr-xr-x   3 ricardo  staff          3 May  7 06:22 Docs03
drwxr-xr-x   3 ricardo  staff          3 May  7 06:38 Docs04
ricardo@solaris:~$
mai 072012
 

Além da compressão, o ZFS também possui o recurso de deduplicação, que faz com que dois (ou mais) arquivos extamente iguais ocupem apenas o espaço de um.

Irei habilitar este recurso no Pool test, que possui 10GB, e está vazio.

ricardo@solaris:~$ uname -a
SunOS solaris 5.11 11.0 i86pc i386 i86pc
ricardo@solaris:~$ ls -lh /test/
total 0
ricardo@solaris:~$ df -h /test/
Filesystem Size Used Available Capacity Mounted on
test 9.8G 31K 9.8G 1% /test

Antes de popular o Pool com uma massa de dados, verifico e habilito o parâmetro de deduplicação para o Pool.

ricardo@solaris:~$ sudo zfs get dedup test
NAME  PROPERTY  VALUE          SOURCE
test  dedup     off            local
ricardo@solaris:~$ sudo zfs set dedup=on test
ricardo@solaris:~$ sudo zfs get dedup test
NAME  PROPERTY  VALUE          SOURCE
test  dedup     on             local

Agora crio dois diretórios no Pool, e copio um conteúdo para um deles, verificando o espaço utilizado em seguida.

ricardo@solaris:~$ mkdir /test/Docs01
ricardo@solaris:~$ mkdir /test/Docs02
ricardo@solaris:~$ cp -rf Documents/Documentação/ /test/Docs01
ricardo@solaris:~$ du -sh /test/Docs01/
 1.2G   /test/Docs01
ricardo@solaris:~$ df -h /test/
Filesystem             Size   Used  Available Capacity  Mounted on
test                   9.8G   1.2G       8.6G    13%    /test

Em seguida copio o mesmo conteúdo para o outro diretório.
Com o comando du, verifico que cada um deles ocupa 1.3GB (antes o primeiro ocupava 1.2GB), mas o comando df me mostra que o sistema de arquivos está com 8.5GB livres (antes tinha 8.6GB livres), mas o espaço total cresceu (!) de 9.8GB para 11GB, assim como o espaço utilizado (de 1.2GB para 2.6GB).

ricardo@solaris:~$ cp -rf Documents/Documentação/ /test/Docs02
ricardo@solaris:~$ du -sh /test/Docs01/
 1.3G   /test/Docs01
ricardo@solaris:~$ du -sh /test/Docs02/
 1.3G   /test/Docs02
ricardo@solaris:~$ df -h /test/
Filesystem             Size   Used  Available Capacity  Mounted on
test                    11G   2.6G       8.5G    24%    /test

Executo a cópia mais uma vez, para um terceiro diretório. O sistema de arquivos continua com 8.5GB livres, mas agora ele “cresceu” para 12GB, e o espaço utilizado para 3.9GB.

ricardo@solaris:~$ mkdir /test/Docs03
ricardo@solaris:~$ cp -rf Documents/Documentação/ /test/Docs03
ricardo@solaris:~$ du -sh /test/Docs03/
 1.3G   /test/Docs03
ricardo@solaris:~$ df -h /test/
Filesystem             Size   Used  Available Capacity  Mounted on
test                    12G   3.9G       8.5G    32%    /test

Isto acontece porque os comandos du e df não são apropriados para tratar a deduplicação do ZFS. Esta verificação deve ser feita com os comandos zfs e zpool, como está abaixo. Veja que o tamanho do Pool está com o tamanho correto (9.94GB), o espaço alocado possui o tamanho de apenas um dos diretórios copiados, e a coluna DEDUP mostra que a deduplicação está em 3.13x (já que temos três diretórios com o mesmo conteúdo).

ricardo@solaris:~$ zfs list test
NAME   USED  AVAIL  REFER  MOUNTPOINT
test  3.92G  8.47G  3.91G  /test
ricardo@solaris:~$ zpool list test
NAME   SIZE  ALLOC   FREE  CAP  DEDUP  HEALTH  ALTROOT
test  9.94G  1.27G  8.67G  12%  3.13x  ONLINE  -

E repetindo mais uma vez, com um quarto diretório, a análise continua incorreta pelos comandos du e df, mas correta pelo zlist e zpool. Veja que deduplicação passou para 4.18x.

ricardo@solaris:~$ mkdir /test/Docs04
ricardo@solaris:~$ cp -rf Documents/Documentação/ /test/Docs04
ricardo@solaris:~$ df -h /test/
Filesystem             Size   Used  Available Capacity  Mounted on
test                    14G   5.2G       8.4G    39%    /test
ricardo@solaris:~$ du -sh /test/Docs04
 1.3G   /test/Docs04
ricardo@solaris:~$ zfs list test
NAME   USED  AVAIL  REFER  MOUNTPOINT
test  5.22G  8.44G  5.21G  /test
ricardo@solaris:~$ zpool list test
NAME   SIZE  ALLOC   FREE  CAP  DEDUP  HEALTH  ALTROOT
test  9.94G  1.28G  8.66G  12%  4.18x  ONLINE  -
ricardo@solaris:~$

Imagine os benefícios em um File Server de uma grande empresa, onde é comum existirem várias cópias de um mesmo documento.

mai 042012
 

O ZFS possui diversas funcionalidades avançadas para sistemas de arquivos, como a compressão. Como tudo no ZFS, a habilitação da compressão é fácil, embora só irá valer para arquivos copiados após a alteração.

Para habilita-la é fácil, e pode até ser habilitado o algoritmo e opções.

No exemplo abaixo, alcançamos facilmente uma compressão de 50% ou mais. Obviamente esta opção não deve ser utulizada para um banco de dados, mas para um servidor de arquivos a vantagem é grande.

ricardo@solaris:~$ sudo zfs get compression test
NAME  PROPERTY     VALUE     SOURCE
test  compression  off       local
ricardo@solaris:~$ df -h /test/
Filesystem             Size   Used  Available Capacity  Mounted on
test                   9.8G    31K       9.8G     1%    /test
ricardo@solaris:~$ ls -lh /test/
total 0
ricardo@solaris:~$ sudo zfs set compression=on test
ricardo@solaris:~$ sudo zfs get compression test
NAME  PROPERTY     VALUE     SOURCE
test  compression  on        local
ricardo@solaris:~$ du -sh /home/ricardo/Documents/Documentação/
 1.3G   /home/ricardo/Documents/Documentação
ricardo@solaris:~$ sudo cp -rf /home/ricardo/Documents/Documentação/ /test/
ricardo@solaris:~$ df -h /test
Filesystem             Size   Used  Available Capacity  Mounted on
test                   9.8G   773M       9.0G     8%    /test
ricardo@solaris:~$ ls -lh /test/
total 3
drwxr-xr-x  18 root     root          19 May  4 11:42 Documentação
ricardo@solaris:~$ sudo zfs set compression=gzip-9 test
ricardo@solaris:~$ sudo zfs get compression test
NAME  PROPERTY     VALUE     SOURCE
test  compression  gzip-9    local
ricardo@solaris:~$ sudo rm -rf /test/Documentação/
ricardo@solaris:~$ sudo cp -rf /home/ricardo/Documents/Documentação/ /test/
ricardo@solaris:~$ df -h /test
Filesystem             Size   Used  Available Capacity  Mounted on
test                   9.8G   601M       9.2G     7%    /test
ricardo@solaris:~$ ls -lh /test/
total 3
drwxr-xr-x  18 root     root          19 May  4 11:45 Documentação
ricardo@solaris:~$