Revisão do RMAN CONVERT DATABASE: Migração de 6TB entre Linux e Solaris com downtime de 30 minutos

maio 10th, 2012 por Ricardo Portilho Proni

E olha que 20 minutos foi para rodar o utlrp.

Há alguns dias eu fiz um post sobre o RMAN CONVERT DATABASE, que permite que um banco de dados seja migrado para outra plataforma e arquitetura. No caso do meu teste, a migração foi de CentOS 4.8 x32-64 para Solaris 10 x32-64, ambos com Oracle Database 10.2.0.4.
Mas o tempo de parada possível para o cliente não permitia a migração desta forma, pois os servidores estão acessíveis apenas por rede, e não via Storage, e o banco possui alguns bons TB.
O Oracle Golden Gate não é uma opção para o cliente, pois ele não está disponível para sua plataforma origem (RHEL 4 PowerPC).

Quais minhas opções então?

Fui estudar melhor o RMAN CONVERT DATABASE. O comando é executado na plataforma origem, que cria um script (a ser executado na plataforma destino) e uma cópia dos DATAFILEs já convertidos para a plataforma destino, informada no comando. O meu problema é o tempo de criação destes DATAFILEs em uma área temporária (com o banco de dados origem em estado READ ONLY), mais a cópia para a nova plataforma via rede, mais a migração para ASM na plataforma destino. Fora o espaço necessário para as áreas temporárias de origem e destino, ou ter apenas a área no destino e monstar na origem como NFS.

CONVERT DATABASE NEW DATABASE 'CLIENTE' TRANSPORT SCRIPT '/home/oracle/transportscript.sql' to platform 'Solaris Operating System (x86-64)' DB_FILE_NAME_CONVERT '+DADOS/cliente/datafile/' '/stage/';

E o que faz o script gerado por este comando? Nada de complexo. Resumidamente, ele cria o controlfile, abre o banco de dados em RESETLOGs, e por fim invalida e recompila todas as Procedures.

-- The following commands will create a new control file and use it
-- to open the database.
-- Data used by Recovery Manager will be lost.
-- The contents of online logs will be lost and all backups will
-- be invalidated. Use this only if online logs are damaged.

-- After mounting the created controlfile, the following SQL
-- statement will place the database in the appropriate
-- protection mode:
--  ALTER DATABASE SET STANDBY DATABASE TO MAXIMIZE PERFORMANCE

STARTUP NOMOUNT PFILE='/u01/app/oracle/product/10.2.0/db_1/dbs/init_00naj11c_1_0.ora'

-- Create SPFILE
CREATE SPFILE FROM PFILE = '/u01/app/oracle/product/10.2.0/db_1/dbs/init_00naj11c_1_0.ora';

STARTUP FORCE NOMOUNT
CREATE CONTROLFILE REUSE SET DATABASE "CLIENTE" RESETLOGS  ARCHIVELOG
    MAXLOGFILES 16
    MAXLOGMEMBERS 3
    MAXDATAFILES 100
    MAXINSTANCES 8
    MAXLOGHISTORY 292
LOGFILE
  GROUP 1 SIZE 50M,
  GROUP 2 SIZE 50M,
  GROUP 3 SIZE 50M,
  GROUP 4 SIZE 100M
DATAFILE
  '/stage/system.256.782246323',
  '/stage/undotbs1.258.782246325',
  '/stage/sysaux.257.782246325',
  '/stage/users.259.782246325',
  '/stage/example.265.782246405',
  '/stage/users.267.782246635',
  '/stage/users.269.782246711',
  '/stage/users.270.782246711',
  '/stage/users.271.782246713',
  '/stage/users.272.782246713',
  '/stage/users.273.782246713',
  '/stage/users.274.782246713',
  '/stage/users.275.782246721',
  '/stage/users.276.782246721',
  '/stage/users.277.782246721',
  '/stage/users.278.782246723'
CHARACTER SET WE8ISO8859P1
;

-- Database can now be opened zeroing the online logs.
ALTER DATABASE OPEN RESETLOGS;

-- Commands to add tempfiles to temporary tablespaces.
-- Online tempfiles have complete space information.
-- Other tempfiles may require adjustment.
ALTER TABLESPACE TEMP ADD TEMPFILE
     SIZE 20971520  AUTOEXTEND ON NEXT 655360  MAXSIZE 32767M;
-- End of tempfile additions.
--

set echo off
prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prompt * Your database has been created successfully!
prompt * There are many things to think about for the new database. Here
prompt * is a checklist to help you stay on track:
prompt * 1. You may want to redefine the location of the directory objects.
prompt * 2. You may want to change the internal database identifier (DBID)
prompt *    or the global database name for this database. Use the
prompt *    NEWDBID Utility (nid).
prompt ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

SHUTDOWN IMMEDIATE
STARTUP UPGRADE
@@ ?/rdbms/admin/utlirp.sql
SHUTDOWN IMMEDIATE
STARTUP
-- The following step will recompile all PL/SQL modules.
-- It may take serveral hours to complete.
@@ ?/rdbms/admin/utlrp.sql
set feedback 6;

Para agilizar a migração, minha idéia era a de migrar o banco, mas continuar aplicando ARCHIVEs na nova plataforma, que foram gerados na antiga plataforma. Mas o script criado pelo RMAN CONVERT DATABASE não permitiria isso, pois abre o banco em RESETLOGs, criando uma nova incarnação do banco de dados, inviabilizando a aplicação de ARCHIVEs da incarnação antiga.

Tentei também aplicar os ARCHIVEs antes do OPEN RESETLOGs, mas recebi um ORA-00600 informando que não era possível executar o RECOVER em um DATAFILE de UNDO. Esta pista é importante, veja mais a seguir.

Pesquisando mais a respeito, encontrei esta nota no MOS (My Oracle Support) a respeito da migração entre plataformas com o mesmo endian (meu caso). Vejam o que ela diz:

Cross-Platform Database Migration (across same endian) using RMAN Transportable Database [ID 1401921.1]
It’s default behavior is to perform datafile conversion on all datafiles in the database. However, only datafiles that contain undo data require conversion including all datafiles beloging to SYSTEM tablespace and all UNDO tablespaces.

O comando CONVERT DATABASE não faz ABSOLUTAMENTE NADA nos DATAFILEs de dados! Só é necessário converter os DATAFILEs das TABLESPACEs SYSTEM e UNDO, e não o banco todo. E a TABLESPACE SYSTEM só sofrerá conversão nos segmentos de ROLLBACK, que não são utilizados, pois estou utilizando UNDO_MANAGEMENT=AUTO.

Partindo desta premissa e de acordo com a nota, considerei que um RESTORE de RMAN normal funcionaria, e após o RESTORE, executar o CONVERT DATAFILE apenas no que é necessário, e em seguida executar RECOVER, aplicando ARCHIVEs até o dia da migração, onde só então executo o OPEN RESETLOGs após aplicar o último ARCHIVE. O CONTROLFILE posso recuperar facilmente com um RESTORE CONTROLFILE FROM, também via RMAN..

Então o procedimento é o seguinte:
- Servidor VELHO: Cria PFILE e copia para Servidor NOVO;
- Servidor NOVO: Adapta diretórios do PFILE, se necessário. Se caminhos mudaram, adicione parâmetros DB_FILE_NAME_CONVERT e LOG_FILE_NAME_CONVERT;
ALTER SYSTEM SET DB_FILE_NAME_CONVERT=’+DADOS’,'+CLIENTE’ SCOPE=SPFILE;
ALTER SYSTEM SET LOG_FILE_NAME_CONVERT=’+FRA’,'+CLIENTE’ SCOPE=SPFILE;
- Servidor NOVO: Inicia em NOMOUNT;
- Servidor VELHO: Cria BACKUP do CONTROLFILE por RMAN, copia o BACKUPPIECE para Servidor NOVO (BACKUP CURRENT CONTROLFILE);
- Servidor NOVO: Restaura o CONTROLFILE pelo RMAN (RESTORE CONTROLFILE FROM ‘/stage/o1_mf_ncnnf_TAG20120510T030757_7tppsy3n_.bkp’;);
- Servidor NOVO: Passa a instância para o estado MOUNT;
- Servidor VELHO: Executa BACKUPSET quente via RMAN, e copia para Servidor NOVO;
- Servidor NOVO: Executa CATALOG nos BACKUPSETs copiados via RMAN;
- Servidor NOVO: Executa RESTORE DATABASE via RMAN:
RMAN> {
RESTORE DATABASE;
SWITCH DATAFILE ALL;
SWITCH TEMPFILE ALL;
}
- Servidor VELHO: Verificar quais DATAFILEs tem segmentos de UNDO:
SQL> SELECT FILE_ID “Datafiles requiring Conversion” FROM DBA_DATA_FILES WHERE TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM DBA_ROLLBACK_SEGS);
- Servidor NOVO: Verificar nomes dos DATAFILEs informados no passo anterior:
SQL> SELECT NAME “Datafiles requiring Conversion” FROM V$DATAFILE WHERE FILE# IN (1,2);
- Servidor NOVO: Executa CONVERT em todos DATAFILEs com segmentos de UNDO:
RMAN> CONVERT DATAFILE ‘+CLIENTE/cliente/datafile/system.260.782918365′ FROM PLATFORM ‘Linux x86 64-bit’;
RMAN> CONVERT DATAFILE ‘+CLIENTE/cliente/datafile/undotbs1.274.782918689′ FROM PLATFORM ‘Linux x86 64-bit’;
- Servidor VELHO: Copia Archives para Servidor NOVO;
- Servidor NOVO: Executa CATALOG nos Archives copiados;
- Servidor NOVO: Executa RECOVER DATABASE;

Continuo executando uma atualização periodicamente até o dia da migração, dependendo do volume de ARCHIVEs gerados:
- Servidor VELHO: Copia Archives para Servidor NOVO;
- Servidor NOVO: Executa CATALOG nos Archives copiados;
- Servidor NOVO: Executa RECOVER DATABASE;

E no dia da migração:
- Servidor VELHO: Cria o último Archive: ALTER SYSTEM ARCHIVE LOG CURRENT;
- Servidor VELHO: Copia Archives para Servidor NOVO;
- Servidor NOVO: Executa CATALOG nos Archives copiados via RMAN;
- Servidor NOVO: Executa RECOVER DATABASE;
- Servidor NOVO: Abre o banco: ALTER DATABASE OPEN RESETLOGS;
- Servidor NOVO: Adiciona TEMPFILEs: ALTER TABLESPACE TEMP ADD TEMPFILE SIZE 20971520 AUTOEXTEND ON NEXT 655360 MAXSIZE 32767M;
- Servidor NOVO: SHUTDOWN IMMEDIATE;
- Servidor NOVO: STARTUP UPGRADE;
- Servidor NOVO: Invalidar todas as Procedures: @?/rdbms/admin/utlirp.sql;
- Servidor NOVO: SHUTDOWN IMMEDIATE;
- Servidor NOVO: STARTUP;
- Servidor NOVO: Recompilar todas as procedures: @?/rdbms/admin/utlrp.sql;

Para facilitar e agilizar ainda mais o processo, eu poderia até montar a FRA origem como NFS no destino, mas não foi necessário.
Teoricamente, eu poderia criar até um Data Guard Physical Standby na nova arquitetura, mas eu preferi evitar ao máximo procedimentos não homologados pela Oracle, que podem custar o suporte ao produto.

Não coloquei o teste todo aqui, porque no final foi praticamente um RESTORE / RECOVER normal, como se fosse em outro servidor mas da mesma plataforma. Mas quis compartilhar o planejamento aqui com vocês (e para mim também, mês que vem já terei esquecido como se fazia isso).

Solaris 11: Log de Pools do ZFS

maio 10th, 2012 por Ricardo Portilho Proni

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:~$

Solaris 11: Verificação de desempenho de I/O no ZFS

maio 10th, 2012 por Ricardo Portilho Proni

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:~$

Solaris 11: ZFS Self Healing

maio 9th, 2012 por Ricardo Portilho Proni

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:~$

Solaris 11: Disco com problema no ZFS

maio 9th, 2012 por Ricardo Portilho Proni

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:~$

Comemoração

maio 8th, 2012 por Ricardo Portilho Proni

Hoje os Treinamentos na Nerv fazem dois anos.

Trabalhamos bastante, mas o resultado é excelente.

Nestes dois anos realizamos exatamente TRINTA E SETE Treinamentos. Praticamente um a cada 20 dias, na média.
Tivemos até o momento 120 alunos (para mim são 120 amigos). Preenchemos 180 vagas, o que significa que a maioria dos alunos faz mais que um Treinamento. Quem vem, volta.
Mais da metade dos alunos não é do estado de São Paulo.
Nunca cancelamos uma turma.

E o mais importante, ensinei a vários profissionais o pouco que sei. Espero que este conhecimento tenha ajudado a eles e suas empresas.
Eu também aprendi muito, muito mesmo, porque dou aula a estes profissionais que estão no mercado, e sempre me trazem novos problemas e cenários.

Nada mal para uma empresa de duas pessoas. Nosso modelo não nos permite crescer, e nem queremos. São raríssimas as empresas grandes que prestam um bom serviço.

E para comemoramos, mais trabalho. Estou preparando novos Treinamentos.

Que venham os próximos dois anos!

http://nervinformatica.com.br

RMAN CONVERT DATABASE: Migrando de Linux para Solaris

maio 7th, 2012 por Ricardo Portilho Proni

O comando do RMAN CONVERT DATABASE na verdade é utilizado no banco de dados origem (também há uma técnica para executa-lo no banco de dados destino, mas acho mais fácil na origem) para criar uma cópia dos DATAFILEs, e um script que irá executar a migração na plataforma destino.
Este tipo de migração só é possível para as plataformas listadas na View V$TRANSPORTABLE_PLATFORM do banco de dados origem.
No teste abaixo, executarei a migração de um servidor Linux x86-64 (um RHEL 4) para outro servidor com Solaris 10, também na arquitetura Intel x86-64.

[oracle@GG01 ~]$ sqlplus / as sysdba

SQL*Plus: Release 10.2.0.4.0 - Production on Mon May 7 15:57:05 2012

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options

SQL> SET PAGES 1000
SQL> SET LINES 210
SQL> SELECT PLATFORM_NAME FROM V$DATABASE;

PLATFORM_NAME
—————————————————————————————————–
Linux x86 64-bit

SQL>  SELECT PLATFORM_NAME FROM V$TRANSPORTABLE_PLATFORM ORDER BY PLATFORM_NAME;

PLATFORM_NAME
—————————————————————————————————–
AIX-Based Systems (64-bit)
Apple Mac OS
HP IA Open VMS
HP Open VMS
HP Tru64 UNIX
HP-UX (64-bit)
HP-UX IA (64-bit)
IBM Power Based Linux
IBM zSeries Based Linux
Linux IA (32-bit)
Linux IA (64-bit)
Linux x86 64-bit
Microsoft Windows IA (32-bit)
Microsoft Windows IA (64-bit)
Microsoft Windows x86 64-bit
Solaris Operating System (x86)
Solaris Operating System (x86-64)
Solaris[tm] OE (32-bit)
Solaris[tm] OE (64-bit)

19 rows selected.

Ok, sendo possível a migração de acordo com a View, executarei a primeira verificação no banco de dados de origem, com a Package DBMS_TDB (TDB de Transportable DataBase).

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2  	DB_READY BOOLEAN;
  3  BEGIN
  4  	DB_READY := DBMS_TDB.CHECK_DB('Solaris Operating System (x86-64)',DBMS_TDB.SKIP_READONLY);
  5  END;
  6  /
Database is not open in READ-ONLY mode. Open the database in READ-ONLY mode and retry.

A verificação exibe o erro de que a migração só pode ser feita com o banco de dados aberto e em READ ONLY.
Então em seguida, abro o banco de dados desta forma e re-executo a verificação.

SQL> SHUTDOWN IMMEDIATE;
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> STARTUP MOUNT;
ORACLE instance started.

Total System Global Area  285212672 bytes
Fixed Size                  2083368 bytes
Variable Size              88081880 bytes
Database Buffers          188743680 bytes
Redo Buffers                6303744 bytes

Database mounted.
SQL> ALTER DATABASE OPEN READ ONLY;

Database altered.

SQL> SET SERVEROUTPUT ON
SQL> DECLARE
  2     DB_READY BOOLEAN;
  3  BEGIN
  4     DB_READY := DBMS_TDB.CHECK_DB('Solaris Operating System (x86-64)',DBMS_TDB.SKIP_READONLY);
  5  END;
  6  /

PL/SQL procedure successfully completed.

Tudo ok até agora. Mais uma verificação deve ser feita, para sabermos se há alguma External Tables e BFILEs no banco de dados de origem. Estes tipos de objetos terão que ser migradas manualmente, se for necessário.

SQL> DECLARE
  2     EXTERNAL BOOLEAN;
  3  BEGIN
  4     EXTERNAL := DBMS_TDB.CHECK_EXTERNAL;
  5  END;
  6  /
The following external tables exist in the database:
SH.SALES_TRANSACTIONS_EXT
The following directories exist in the database:
SYS.ORACLE_OCM_CONFIG_DIR, SYS.ADMIN_DIR, SYS.WORK_DIR, SYS.DATA_FILE_DIR, SYS.LOG_FILE_DIR, SYS.MEDIA_DIR, SYS.XMLDIR, SYS.SUBDIR, SYS.DATA_PUMP_DIR
The following BFILEs exist in the database:
PM.PRINT_MEDIA

PL/SQL procedure successfully completed.

SQL>

Ok, anotadas as External Table que precisaremos recriar, criamos um diretório temporário para armazenar o banco de dados. Este diretório terá o mesmo nome na origem e no destino, para facilitar a migração. O banco de dados origem está em ASM, e o destino não utilizará ASM, mas resolveremos isto logo mais.

[oracle@GG01 ~]$ su -
Password:
[root@GG01 ~]# mkdir /stage
[root@GG01 ~]# chown oracle:dba /stage/
[root@GG01 ~]# chown -R oracle:dba /stage/
[root@GG01 ~]# exit
logout

Após criar o diretório, executamos o CONVERT DATABASE no banco de dados origem, que irá criar uma cópia de cada DATAFILE no diretório recém-criado, e o script que depois será executado na plataforma destino.
Nno próprio comando eu utilizo a opção DB_FILE_NAME_CONVERT, para retirar os arquivos do ASM e passar para o diretório temporário.
Veja que durante a execução também são informados os Directories existentes e BFILEs, que teriam que ser migrados manualmente.

[oracle@GG01 ~]$ rman TARGET /

Recovery Manager: Release 10.2.0.4.0 - Production on Mon May 7 16:21:03 2012

Copyright (c) 1982, 2007, Oracle.  All rights reserved.

connected to target database: CLIENTE (DBID=1146878630)

RMAN> CONVERT DATABASE NEW DATABASE ‘CLIENTE’ TRANSPORT SCRIPT ‘/home/oracle/transportscript’ to platform ‘Solaris Operating System (x86-64)’ DB_FILE_NAME_CONVERT ‘+DADOS/autopass/datafile/’ ‘/stage/’;

Starting convert at 07-MAY-12
using target database control file instead of recovery catalog
allocated channel: ORA_DISK_1
channel ORA_DISK_1: sid=159 devtype=DISK

External table SH.SALES_TRANSACTIONS_EXT found in the database

Directory SYS.ORACLE_OCM_CONFIG_DIR found in the database
Directory SYS.ADMIN_DIR found in the database
Directory SYS.WORK_DIR found in the database
Directory SYS.DATA_FILE_DIR found in the database
Directory SYS.LOG_FILE_DIR found in the database
Directory SYS.MEDIA_DIR found in the database
Directory SYS.XMLDIR found in the database
Directory SYS.SUBDIR found in the database
Directory SYS.DATA_PUMP_DIR found in the database

BFILE PM.PRINT_MEDIA found in the database

User SYS with SYSDBA and SYSOPER privilege found in password file
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00001 name=+DADOS/autopass/datafile/system.256.782246323
converted datafile=/home/oracle/CLIENTE/system.256.782246323
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:25
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00003 name=+DADOS/autopass/datafile/sysaux.257.782246325
converted datafile=/home/oracle/CLIENTE/sysaux.257.782246325
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:15
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00005 name=+DADOS/autopass/datafile/example.265.782246405
converted datafile=/home/oracle/CLIENTE/example.265.782246405
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00006 name=+DADOS/autopass/datafile/users.267.782246635
converted datafile=/home/oracle/CLIENTE/users.267.782246635
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:07
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00007 name=+DADOS/autopass/datafile/users.269.782246711
converted datafile=/home/oracle/CLIENTE/users.269.782246711
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:07
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00008 name=+DADOS/autopass/datafile/users.270.782246711
converted datafile=/home/oracle/CLIENTE/users.270.782246711
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:25
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00009 name=+DADOS/autopass/datafile/users.271.782246713
converted datafile=/home/oracle/CLIENTE/users.271.782246713
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00010 name=+DADOS/autopass/datafile/users.272.782246713
converted datafile=/home/oracle/CLIENTE/users.272.782246713
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00011 name=+DADOS/autopass/datafile/users.273.782246713
converted datafile=/home/oracle/CLIENTE/users.273.782246713
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00012 name=+DADOS/autopass/datafile/users.274.782246713
converted datafile=/home/oracle/CLIENTE/users.274.782246713
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:07
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00013 name=+DADOS/autopass/datafile/users.275.782246721
converted datafile=/home/oracle/CLIENTE/users.275.782246721
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00014 name=+DADOS/autopass/datafile/users.276.782246721
converted datafile=/home/oracle/CLIENTE/users.276.782246721
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00015 name=+DADOS/autopass/datafile/users.277.782246721
converted datafile=/home/oracle/CLIENTE/users.277.782246721
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00016 name=+DADOS/autopass/datafile/users.278.782246723
converted datafile=/home/oracle/CLIENTE/users.278.782246723
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:03
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00002 name=+DADOS/autopass/datafile/undotbs1.258.782246325
converted datafile=/home/oracle/CLIENTE/undotbs1.258.782246325
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:01
channel ORA_DISK_1: starting datafile conversion
input datafile fno=00004 name=+DADOS/autopass/datafile/users.259.782246325
converted datafile=/home/oracle/CLIENTE/users.259.782246325
channel ORA_DISK_1: datafile conversion complete, elapsed time: 00:00:01
Run SQL script /home/oracle/transportscript on the target platform to create database
Edit init.ora file /u01/app/oracle/product/10.2.0/db_1/dbs/init_00nad5rn_1_0.ora. This PFILE will be used to create the database on the target platform
To recompile all PL/SQL modules, run utlirp.sql and utlrp.sql on the target platform
To change the internal database identifier, use DBNEWID Utility
Finished backup at 07-MAY-12

RMAN>

Veja que ao final do comando, o RMAN informou que já foi criado um PFILE para facilitar nossa migração.

Na plataforma destino, criamos o diretório temporário, com o mesmo nome da origem.

login as: oracle
Using keyboard-interactive authentication.
Password:
Last login: Mon May  7 12:45:17 2012 from 192.168.56.1
Oracle Corporation      SunOS 5.10      Generic Patch   January 2005
-bash-3.2$ su -
Password:
Oracle Corporation      SunOS 5.10      Generic Patch   January 2005
-bash-3.2# mkdir /stage
-bash-3.2# chown -R oracle:dba /stage/
-bash-3.2# exit
logout
-bash-3.2$

Agora copiamos todo o conteúdo do diretório temporário da origem para o destino. Ele também poderia ser montado como um sistema NFS, que eliminaria a necessidade da cópia.
E após copiar os DATAFILEs, copio também o PFILE criado pelo RMAN.

[oracle@GG01 ~]$ scp /stage/* 192.168.56.101:/stage/
The authenticity of host ‘192.168.56.101 (192.168.56.101)’ can’t be established.
RSA key fingerprint is c2:dc:d9:f3:e2:0d:07:93:da:76:6c:42:76:f0:c3:1c.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ‘192.168.56.101′ (RSA) to the list of known hosts.
Password:
example.265.782246405                                                                                                                 100%  100MB  20.0MB/s   00:05
sysaux.257.782246325                                                                                                                  100%  240MB   9.6MB/s   00:25
system.256.782246323                                                                                                                  100%  480MB  12.6MB/s   00:38
undotbs1.258.782246325                                                                                                                100%   25MB  25.0MB/s   00:01
users.259.782246325                                                                                                                   100% 5128KB   5.0MB/s   00:00
users.267.782246635                                                                                                                   100%  100MB  11.1MB/s   00:09
users.269.782246711                                                                                                                   100%  100MB  11.1MB/s   00:09
users.270.782246711                                                                                                                   100%  100MB  10.0MB/s   00:10
users.271.782246713                                                                                                                   100%  100MB  10.0MB/s   00:10
users.272.782246713                                                                                                                   100%  100MB  10.0MB/s   00:10
users.273.782246713                                                                                                                   100%  100MB  10.0MB/s   00:10
users.274.782246713                                                                                                                   100%  100MB  10.0MB/s   00:10
users.275.782246721                                                                                                                   100%  100MB   9.1MB/s   00:11
users.276.782246721                                                                                                                   100%  100MB  10.0MB/s   00:10
users.277.782246721                                                                                                                   100%  100MB  10.0MB/s   00:10
users.278.782246723                                                                                                                   100%  100MB  11.1MB/s   00:09
[oracle@GG01 ~]$ scp /u01/app/oracle/product/10.2.0/db_1/dbs/init_00nad5rn_1_0.ora 192.168.56.101:/opt/oracle/product/10.2.0/db_1/dbs/initCLIENTE.ora
Password:
init_00nad5rn_1_0.ora                                                                                                                 100% 1536     1.5KB/s   00:00
[oracle@GG01 ~]$ scp /home/oracle/transportscript 192.168.56.101:/stage
Password:
transportscript                                                                                                                       100% 2713     2.7KB/s   00:00
[oracle@GG01 ~]$

Certas adequações podem ser necessárias no script de migração, por exemplo, mudanças de diretórios. No meu caso, tive que alterar tudo o que era “/u01/oracle/” para “/opt/oracle”, como é o padrão no Solaris.
O PFILE também requereu algumas alterações parecidas, como os diretórios de DUMP.

-bash-3.2$ ls -lh /stage/transportscript
-rw-r--r--   1 oracle   oinstall    2.6K May  7 13:38 /stage/transportscript
-bash-3.2$ vi /stage/transportscript
"/stage/transportscript" 79 lines, 2685 characters

Em seguida, basta executar o script de migração na plataforma destino.

-bash-3.2$ mv /stage/transportscript /stage/transportscript.sql
-bash-3.2$ export ORACLE_SID=CLIENTE
-bash-3.2$ sqlplus / AS SYSDBA

SQL*Plus: Release 10.2.0.4.0 - Production on Mon May 7 14:03:53 2012

Copyright (c) 1982, 2007, Oracle.  All Rights Reserved.

Connected to an idle instance.

SQL> @/stage/transportscript.sql
ORACLE instance started.

Total System Global Area  285212672 bytes
Fixed Size                  2083368 bytes
Variable Size              88081880 bytes
Database Buffers          188743680 bytes
Redo Buffers                6303744 bytes

File created.

ORACLE instance started.

Total System Global Area  285212672 bytes
Fixed Size                  2083368 bytes
Variable Size              88081880 bytes
Database Buffers          188743680 bytes
Redo Buffers                6303744 bytes

Control file created.

Database altered.

Tablespace altered.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Your database has been created successfully!
* There are many things to think about for the new database. Here
* is a checklist to help you stay on track:
* 1. You may want to redefine the location of the directory objects.
* 2. You may want to change the internal database identifier (DBID)
*    or the global database name for this database. Use the
*    NEWDBID Utility (nid).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Database closed.
Database dismounted.
ORACLE instance shut down.
ORACLE instance started.

Total System Global Area  285212672 bytes
Fixed Size                  2083368 bytes
Variable Size              88081880 bytes
Database Buffers          188743680 bytes
Redo Buffers                6303744 bytes
Database mounted.
Database opened.
SQL>
SQL> WHENEVER SQLERROR EXIT;
SQL>
SQL> DOC
DOC>#######################################################################
DOC>#######################################################################
DOC>   The following statement will cause an "ORA-01722: invalid number"
DOC>   error if there the database was not opened in UPGRADE mode
DOC>
DOC>   If you encounter this error, execute "SHUTDOWN", "STARTUP UPGRADE" and
DOC>   re-execute utlirp.sql
DOC>#######################################################################
DOC>#######################################################################
DOC>#
SQL> SELECT TO_NUMBER('MUST_BE_OPEN_UPGRADE') FROM v$instance
  2  WHERE status != 'OPEN MIGRATE';

no rows selected

SQL>
SQL> Rem
SQL> Rem Store object numbers of all valid PL/SQL-based functional indexes
SQL> Rem
SQL> DROP TABLE utlirp_enabled_func_indexes;

Table dropped.

SQL> CREATE TABLE utlirp_enabled_func_indexes AS
  2     SELECT obj# FROM ind$
  3     WHERE  bitand(property, 2048) != 0 AND bitand(flags, 1024) = 0;

Table created.

SQL>
SQL> Rem invalidate all pl/sql modules and recompile standard and dbms_standard
SQL> @@utlip
...
SQL>
SQL> DOC
DOC> The following query reports the number of objects that have compiled
DOC> with errors (objects that compile with errors have status set to 3 in
DOC> obj$). If the number is higher than expected, please examine the error
DOC> messages reported with each object (using SHOW ERRORS) to see if they
DOC> point to system misconfiguration or resource constraints that must be
DOC> fixed before attempting to recompile these objects.
DOC>#
SQL> select COUNT(*) "OBJECTS WITH ERRORS" from obj$ where status = 3;

OBJECTS WITH ERRORS
-------------------
                  0

SQL>
SQL>
SQL> DOC
DOC> The following query reports the number of errors caught during
DOC> recompilation. If this number is non-zero, please query the error
DOC> messages in the table UTL_RECOMP_ERRORS to see if any of these errors
DOC> are due to misconfiguration or resource constraints that must be
DOC> fixed before objects can compile successfully.
DOC>#
SQL> select COUNT(*) "ERRORS DURING RECOMPILATION" from utl_recomp_errors;

ERRORS DURING RECOMPILATION
---------------------------
                          0

SQL>
SQL>
SQL> Rem =====================================================================
SQL> Rem Run component validation procedure
SQL> Rem =====================================================================
SQL>
SQL> SET serveroutput on
SQL> EXECUTE dbms_registry_sys.validate_components;

PL/SQL procedure successfully completed.

SQL> SET serveroutput off
SQL>
SQL>
SQL> Rem ===========================================================================
SQL> Rem END utlrp.sql
SQL> Rem ===========================================================================
SQL> set feedback 6;

Como o script finalizou sem erros, basta conferir o resultado na plataforma destino.

SQL> SELECT STATUS FROM V$INSTANCE;

STATUS
------------
OPEN

SQL> SELECT PLATFORM_NAME FROM V$DATABASE;

PLATFORM_NAME
--------------------------------------------------------------------------------
Solaris Operating System (x86-64)

SQL> SELECT FILE_NAME FROM DBA_DATA_FILES;

FILE_NAME
--------------------------------------------------------------------------------
/stage/users.278.782246723
/stage/users.277.782246721
/stage/users.276.782246721
/stage/users.275.782246721
/stage/users.274.782246713
/stage/users.273.782246713
/stage/users.272.782246713
/stage/users.271.782246713
/stage/users.270.782246711
/stage/users.269.782246711
/stage/users.267.782246635

FILE_NAME
--------------------------------------------------------------------------------
/stage/example.265.782246405
/stage/users.259.782246325
/stage/sysaux.257.782246325
/stage/undotbs1.258.782246325
/stage/system.256.782246323

16 rows selected.

Solaris 11: ZFS Deduplication

maio 7th, 2012 por Ricardo Portilho Proni

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.

Solaris 11: ZFS Compression

maio 7th, 2012 por Ricardo Portilho Proni

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:~$

Solaris 11: Criando um pool com espelhamento no ZFS

maio 3rd, 2012 por Ricardo Portilho Proni

O ZFS foi criado com foco na simplicidade. Ele é ao mesmo tempo um sistema de arquivos (como o ext4) e um gerenciador de volumes (como o LVM).
Na instalação padrão do Solaris 11, onde o sistema de arquivos root (/) é montado em ZFS, só tenho o pool rpool (de “root pool”), onde os sistemas de arquivos estão montados.

ricardo@solaris:~$ sudo zpool status
  pool: rpool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        rpool       ONLINE       0     0     0
          c3t0d0s0  ONLINE       0     0     0

errors: No known data errors
ricardo@solaris:~$ df -h
Filesystem             Size   Used  Available Capacity  Mounted on
rpool/ROOT/solaris      98G   3.2G        77G     5%    /
/devices                 0K     0K         0K     0%    /devices
/dev                     0K     0K         0K     0%    /dev
ctfs                     0K     0K         0K     0%    /system/contract
proc                     0K     0K         0K     0%    /proc
mnttab                   0K     0K         0K     0%    /etc/mnttab
swap                   9.5G   1.4M       9.5G     1%    /system/volatile
objfs                    0K     0K         0K     0%    /system/object
sharefs                  0K     0K         0K     0%    /etc/dfs/sharetab
/usr/lib/libc/libc_hwcap1.so.1
                        81G   3.2G        77G     5%    /lib/libc.so.1
fd                       0K     0K         0K     0%    /dev/fd
rpool/ROOT/solaris/var
                        98G   182M        77G     1%    /var
swap                   9.5G    12K       9.5G     1%    /tmp
rpool/export            98G    32K        77G     1%    /export
rpool/export/home       98G    32K        77G     1%    /export/home
rpool/export/home/ricardo
                        98G    12M        77G     1%    /export/home/ricardo
rpool                   98G    39K        77G     1%    /rpool
/export/home/ricardo    77G    12M        77G     1%    /home/ricardo
ricardo@solaris:~$

Pelo comando cfgadm, verifico se tenho mais discos disponíveis, além do utilizado no rpool.

ricardo@solaris:~$ sudo cfgadm -s “select=type(disk)”
Ap_Id                          Type         Receptacle   Occupant     Condition
sata6/0::dsk/c3t0d0            disk         connected    configured   ok
sata6/2::dsk/c3t2d0            disk         connected    configured   ok
sata6/3::dsk/c3t3d0            disk         connected    configured   ok

Crio então um pool chamado test, utilizando os dois discos disponíveis, com espelhamento entre eles.

ricardo@solaris:~$ sudo zpool create test mirror c3t2d0 c3t3d0
ricardo@solaris:~$ sudo zpool status
  pool: rpool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        rpool       ONLINE       0     0     0
          c3t0d0s0  ONLINE       0     0     0

errors: No known data errors

  pool: test
 state: ONLINE
  scan: none requested
config:

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

errors: No known data errors

Neste momento o sistema de arquivos já está montado e pronto para uso.

ricardo@solaris:~$ ls -lh /test/
total 0
ricardo@solaris:~$ sudo mkfile 1g /test/ArquivoTeste
ricardo@solaris:~$ ls -lh /test/
total 1963283
-rw——T   1 root     root        1.0G May  3 08:22 ArquivoTeste
ricardo@solaris:~$ sudo zpool status
  pool: rpool
 state: ONLINE
  scan: none requested
config:

        NAME        STATE     READ WRITE CKSUM
        rpool       ONLINE       0     0     0
          c3t0d0s0  ONLINE       0     0     0

errors: No known data errors

  pool: test
 state: ONLINE
  scan: none requested
config:

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

errors: No known data errors
ricardo@solaris:~$ df -h
Filesystem             Size   Used  Available Capacity  Mounted on
rpool/ROOT/solaris      98G   3.2G        77G     5%    /
/devices                 0K     0K         0K     0%    /devices
/dev                     0K     0K         0K     0%    /dev
ctfs                     0K     0K         0K     0%    /system/contract
proc                     0K     0K         0K     0%    /proc
mnttab                   0K     0K         0K     0%    /etc/mnttab
swap                   9.5G   1.4M       9.5G     1%    /system/volatile
objfs                    0K     0K         0K     0%    /system/object
sharefs                  0K     0K         0K     0%    /etc/dfs/sharetab
/usr/lib/libc/libc_hwcap1.so.1
                        81G   3.2G        77G     5%    /lib/libc.so.1
fd                       0K     0K         0K     0%    /dev/fd
rpool/ROOT/solaris/var
                        98G   182M        77G     1%    /var
swap                   9.5G    12K       9.5G     1%    /tmp
rpool/export            98G    32K        77G     1%    /export
rpool/export/home       98G    32K        77G     1%    /export/home
rpool/export/home/ricardo
                        98G    12M        77G     1%    /export/home/ricardo
rpool                   98G    39K        77G     1%    /rpool
/export/home/ricardo    77G    12M        77G     1%    /home/ricardo
test                   9.8G   1.0G       8.8G    11%    /test
ricardo@solaris:~$