Lançado na versão Oracle 10g Release 1, o ASM passou por muitas mudanças até chegar onde chegou.
Os números abaixo além de impressionar, mostra um pouco até onde o ASM pode ir:
- Você pode ter até 63 disk group.
- Cada disk group pode ter até 10,000 ASM disks
- Cada disk group pode suportar um armazenamento de até 2TB.
- Cada diskgroup pode gerenciar até 1.000.000 (um milhão) de arquivos.
- Com a externa redundância: O tamanho máximo suportado por um datafile no Oracle ASM é de 140PB.
- Com a normal redundância: O tamanho máximo suportado por um datafile no Oracle ASM é de 42PB.
- Com a high redundância: O tamanho máximo suportado por um datafile no Oracle ASM é de 15PB.
Leram bem né?! Um datafile de 140 PB ….
Asynchronous I/O é uma maneira diferente de processar os dados de input/output. Utilizando Async I/O permite que outros processos continue antes da transmissão ter sido concluída, fornecendo assim grande ganho de performance para operações de IO.
Para verificar se está característica está habilitado checamos através do slabinfo. O slabinfo mantém todas as estatísticas sobre os objetos em memória, assim podemos verificar as operações de AIO já que ele trata os objetos na memória virtual.
cat /proc/slabinfo | grep kio
Caso o seu ASYNC IO esteja habilitado o retorno do comando acima deve parecer assim:
kioctx 188 244 128 9 9 1 : 252 126 kiocb 43010 43010 96 1652 1652 1 : 252 126
Agora, se o seu AIO não está habilitado o kiocb deve estar seguido de dois 0 (zeros).
kioctx 28 60 192 20 1 : tunables 120 60 8 : slabdata 3 3 0 kiocb 0 0 128 30 1 : tunables 120 60 8 : slabdata 0 0 0
Com o a utilizando do ASMLib, esse comportamento não pode ser seguido já que o ASMLib não utiliza as funções POSIX aio_*(), então nunca vamos ver o kiocb em ação.
Quando o ASMLib é utilizado podemos simplesmente checar através do parâmetro disk_asynch_io na instância ASM, você pode inclusive habilitar e desabilitar o AIO apenas definindo o parâmetro disk_asynch_io para TRUE ou FALSE.
O erro acontece quando você tenta desmontar ou remover um diskgroup em que existe um (ou mais) arquivo sendo utilizado atualmente pelo ASM.
SQL> alter diskgroup dgroup1 dismount; alter diskgroup dgroup1 dismount * ERROR at line 1: ORA-15032: not all alterations performed ORA-15027: active use of diskgroup "DGROUP1" precludes its dismount SQL> drop diskgroup DGROUP1 including contents; drop diskgroup DGROUP1 including contents * ERROR at line 1: ORA-15039: diskgroup not dropped ORA-15027: active use of diskgroup "DGROUP1" precludes its dismount
O ASM por si só, é muito inteligente e sabe que se o diskgroup for desmontado ou removido, poderá ocorrer qualquer perca de dados. Você pode por exemplo incluir a opção force no comando para desmontar o diskgroup de maneira “forçada” sem nenhuma checagem de perca de dados, que isso pode trazer grande dores de cabeça … já que pode haver perca de dados …
SQL> alter diskgroup dgroup1 dismount; alter diskgroup dgroup1 dismount * ERROR at line 1: ORA-15032: not all alterations performed ORA-15027: active use of diskgroup "DGROUP1" precludes its dismount SQL> alter diskgroup dgroup1 dismount force; Diskgroup altered.
Como então desmontar/remover o diskgroup sem qualquer perca de dados? No meu caso o problema estava com o spfile do ASM, ele estava justamente no diskgroup que gostaria de remover (+DGROUP1). Como eu descobri isso? Simples … através da view v$asm_file:
SQL> select f.group_number, d.name, f.file_number, f.bytes, f.type 2 from v$asm_file f, v$asm_diskgroup d 3 where f.group_number = d.group_number; GROUP_NUMBER NAME FILE_NUMBER BYTES TYPE ------------ ------------------------------ ----------- ---------- ---------------------------------------------------------------- 1 DGROUP1 253 1536 ASMPARAMETERFILE
Ok, mais qual solução? Mover o spfile do ASM para um outro diskgroup disponível:
SQL> select name, state from v$asm_diskgroup; GROUP_NUMBER NAME STATE ------------ ------------------------------ ----------- 1 DGROUP1 MOUNTED 2 DGROUP2 MOUNTED SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production With the Automatic Storage Management option [oracle@oracle11g ~]$ asmcmd ASMCMD> spget +DGROUP1/asm/asmparameterfile/registry.253.784483237
Veja acima que tenho dois diskgroup, quero passar então o meu parameter file para o DISKGROUP2:
SQL> create pfile='/u01/app/oracle/init+ASM.ora' from spfile; File created. SQL> shut immediate; ASM diskgroups dismounted ASM instance shutdown SQL> startup pfile='/u01/app/oracle/init+ASM.ora'; ASM instance started Total System Global Area 284565504 bytes Fixed Size 1344456 bytes Variable Size 258055224 bytes ASM Cache 25165824 bytes ASM diskgroups mounted SQL> show parameter spfile NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ spfile string
Veja que agora como subi o ASM através do pfile, nenhum spfile está configurado para ele. Agora iremos criar um spfile para a o diskgroup DGROUP2 através do pfile que acabamos de criar.
SQL> create spfile='+DGROUP2/init.ora' from pfile='/u01/app/oracle/init+ASM.ora'; File created. SQL> shut immediate; ASM diskgroups dismounted ASM instance shutdown SQL> startup ASM instance started Total System Global Area 284565504 bytes Fixed Size 1344456 bytes Variable Size 258055224 bytes ASM Cache 25165824 bytes ASM diskgroups mounted SQL> show parameter spfile NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ spfile string +DGROUP2/init.ora SQL> SQL> Disconnected from Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production With the Automatic Storage Management option [oracle@oracle11g oracle]$ asmcmd ASMCMD> spget +DGROUP2/init.ora ASMCMD> exit
Agora que temos o spfile do ASM apontando para o DGROUP2 e não mais para o DGROUP1, podemos sem problema nenhum desmontar/remover o diskgroup desejado.
SQL> alter diskgroup dgroup1 dismount; Diskgroup altered. SQL> alter diskgroup dgroup1 mount; Diskgroup altered. SQL> drop diskgroup dgroup1 including contents; Diskgroup dropped. SQL> select group_number, name, state from v$asm_diskgroup; GROUP_NUMBER NAME STATE ------------ ------------------------------ ----------- 2 DGROUP2 MOUNTED
O ASM é sem dúvida um dos maiores avanços de gerenciamento de disco e muitas coisas relacionadas a I/O (performance, gerenciamento, etc..). Em um outro post estarei mostrando as vantagens de um ambiente utilizando ASM e como ele é benéfico para o ambiente.
Apesar de todas essas vantagens, ainda hoje existem muitos ambientes em que não é utilizado o ASM. Pensando nisso hoje estaremos vendo como utilizar o RMAN (apenas o RMAN) para realizar uma migração de um filesystem comum como ext3 para ASM.
No nosso caso, estaremos movendo todos os datafiles e tempfiles do banco dbtst para o diskgroup +DGROUP1.
[oracle@oracle11gR3 ~]$ rman target / Recovery Manager: Release 11.2.0.3.0 - Production on Wed Jan 4 13:56:46 2012 Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved. connected to target database: DBTST (DBID=2987787466) -- Habilitando o Oracle Managed File RMAN> sql "alter system set db_create_file_dest=''+DGROUP1'' scope=spfile"; using target database control file instead of recovery catalog sql statement: alter system set db_create_file_dest=''+DGROUP1'' scope=spfile -- Mudando a localização do controlfile RMAN> sql "alter system set control_files=''+DGROUP1'' scope=spfile"; using target database control file instead of recovery catalog sql statement: alter system set control_files=''+DGROUP1'' scope=spfile RMAN> shutdown immediate; database closed database dismounted Oracle instance shut down -- Subimos o banco em modo NOMOUNT RMAN> startup nomount connected to target database (not started) Oracle instance started Total System Global Area 839282688 bytes Fixed Size 2233000 bytes Variable Size 511708504 bytes Database Buffers 318767104 bytes Redo Buffers 6574080 bytes
Nesse momento vamos restaurar o nosso control file atual (‘/u01/app/oracle/oradata/dbtst/control01.ctl’ ou ‘/u01/app/oracle/oradata/dbtst/control02.ctl’) para o diskgroup DGROUP1. O grande lance aqui é que como mudamos o parâmetro control_files para o +DGROUP1 e habilitamos o Oracle Managed Files e temos uma cópia consistência do control files pois baixamos o banco de maneira adequada, simplesmente restaurando o control file atual ele irá gerar no caminho do diskgroup DGROUP1.
Observe a saída do comando:
RMAN> restore controlfile from '/u01/app/oracle/oradata/dbtst/control01.ctl'; Starting restore at 04-JAN-12 allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=137 device type=DISK channel ORA_DISK_1: copied control file copy output file name=+DGROUP1/dbtst/controlfile/current.256.771688895 Finished restore at 04-JAN-12
Como já temos nosso control file restaurado para o DGROUP1, podemos inicializar o banco em mount.
RMAN> alter database mount; database mounted released channel: ORA_DISK_1
Agora vamos realizar um backup do tipo copy formatando para o diskgroup DGROUP1.
RMAN> BACKUP AS COPY DATABASE DATABASE FORMAT '+DGROUP1'; Starting backup at 04-JAN-12 allocated channel: ORA_DISK_1 channel ORA_DISK_1: SID=137 device type=DISK channel ORA_DISK_1: starting datafile copy input datafile file number=00001 name=/u01/app/oracle/oradata/dbtst/system01.dbf output file name=/u01/app/oracle/product/11.2.0/dbhome_1/dbs/data_D-DBTST_I-2987787466_TS-SYSTEM_FNO-1_01mvu2gt tag=TAG20120104T140308 RECID=2 STAMP=771689052 channel ORA_DISK_1: datafile copy complete, elapsed time: 00:01:06 channel ORA_DISK_1: starting datafile copy ... input datafile file number=00004 name=/u01/app/oracle/oradata/dbtst/users01.dbf output file name=+DGROUP1/dbtst/datafile/users.262.771689571 tag=TAG20120104T140308 RECID=13 STAMP=771689575 channel ORA_DISK_1: datafile copy complete, elapsed time: 00:00:07 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set including current SPFILE in backup set channel ORA_DISK_1: starting piece 1 at 04-JAN-12 channel ORA_DISK_1: finished piece 1 at 04-JAN-12 piece handle=/u01/app/oracle/product/11.2.0/dbhome_1/dbs/0dmvu33a_1_1 tag=TAG20120104T140308 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:01 channel ORA_DISK_1: starting full datafile backup set channel ORA_DISK_1: specifying datafile(s) in backup set including current SPFILE in backup set channel ORA_DISK_1: starting piece 1 at 04-JAN-12 channel ORA_DISK_1: finished piece 1 at 04-JAN-12 piece handle=+DGROUP1/dbtst/backupset/2012_01_04/nnsnf0_tag20120104t140308_0.263.771689581 tag=TAG20120104T140308 comment=NONE channel ORA_DISK_1: backup set complete, elapsed time: 00:00:03 Finished backup at 04-JAN-12
Com a image copy do banco de dados feito, o vamos migrar nossos datafiles para esses arquivos de copias de backup. Isso tudo é feito através do comando SWITCH DATABASE TO COPY, que sempre quando utilizado deve-se realizar um recover do banco de dados.
RMAN> SWITCH DATABASE TO COPY; RMAN> RECOVER DATABASE;
Agora abrimos o banco e adicionamos um novo tempfile para o tablespace TEMP e removemos o tempfile ‘/u01/app/oracle/oradata/dbtst/temp01.dbf’ antigo. Como nosso OMF está apontando para o diskgroup DGROUP1 não precisamos especificar o caminho do tempfile na sua criação.
RMAN> SQL "ALTER DATABASE OPEN"; RMAN> SQL "ALTER TABLESPACE TEMP ADD TEMPFILE"; RMAN> SQL "ALTER DATABASE TEMPFILE ''/u01/app/oracle/oradata/dbtst/temp01.dbf'' DROP";
Após esses passos seus datafiles e tempfiles estarão todos no ASM.
SQL> desc v$asm_diskgroup
Name Null? Type
----------------------------------------- -------- ----------------------------
GROUP_NUMBER NUMBER
NAME VARCHAR2(30)
SECTOR_SIZE NUMBER
BLOCK_SIZE NUMBER
ALLOCATION_UNIT_SIZE NUMBER
STATE VARCHAR2(11)
TYPE VARCHAR2(6)
TOTAL_MB NUMBER
FREE_MB NUMBER
REQUIRED_MIRROR_FREE_MB NUMBER
USABLE_FILE_MB NUMBER
OFFLINE_DISKS NUMBER
COMPATIBILITY VARCHAR2(60)
DATABASE_COMPATIBILITY VARCHAR2(60)
SQL> select GROUP_NUMBER, NAME, STATE from v$asm_diskgroup;
GROUP_NUMBER NAME STATE
------------ ------------------------------ -----------
1 ORADATA MOUNTED
0 ORADATA1 DISMOUNTED
SQL> ALTER DISKGROUP ALL DISMOUNT;
Diskgroup altered.
SQL> select GROUP_NUMBER, NAME, STATE from v$asm_diskgroup;
GROUP_NUMBER NAME STATE
------------ ------------------------------ -----------
0 ORADATA DISMOUNTED
0 ORADATA1 DISMOUNTED
SQL> ALTER DISKGROUP ALL MOUNT;
Diskgroup altered.
SQL> select GROUP_NUMBER, NAME, STATE from v$asm_diskgroup;
GROUP_NUMBER NAME STATE
------------ ------------------------------ -----------
1 ORADATA MOUNTED
0 ORADATA1 MOUNTED
Maneira simples de mover o control file para o ASM, tudo é feito através do RMAN.
[oracle@oel510gasm oradata]$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on Wed Mar 16 21:52:56 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> show parameter control_files NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ control_files string /u01/app/oracle/oradata/control01.ctl, /u01/app/oracle/oradata/control02.ctl, /u01/app/oracle/oradata/control03.ctl SQL> shutdown immediate; Database closed. Database dismounted. ORACLE instance shut down. SQL> exit Disconnected from Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options [oracle@oel510gasm oradata]$ rman target / Recovery Manager: Release 10.2.0.1.0 - Production on Wed Mar 16 21:54:17 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. connected to target database (not started) RMAN> startup nomount; Oracle instance started Total System Global Area 167772160 bytes Fixed Size 1218316 bytes Variable Size 67111156 bytes Database Buffers 96468992 bytes Redo Buffers 2973696 bytes RMAN> restore controlfile to '+DGROUP1/orcl/controlfile/control01.ctl' from '/u01/app/oracle/oradata/control01.ctl'; Starting restore at 16-MAR-11 using channel ORA_DISK_1 channel ORA_DISK_1: copied control file copy Finished restore at 16-MAR-11 RMAN> restore controlfile to '+DGROUP1/orcl/controlfile/control02.ctl' from '/u01/app/oracle/oradata/control01.ctl'; Starting restore at 16-MAR-11 using channel ORA_DISK_1 channel ORA_DISK_1: copied control file copy Finished restore at 16-MAR-11 RMAN> restore controlfile to '+DGROUP1/orcl/controlfile/control03.ctl' from '/u01/app/oracle/oradata/control01.ctl'; Starting restore at 16-MAR-11 using channel ORA_DISK_1 channel ORA_DISK_1: copied control file copy Finished restore at 16-MAR-11
Após fazer o RESTORE do control file no ASM é necessário sinalizar ao spfile.
RMAN> sql 'alter system set control_files=" 2> +DGROUP1/orcl/controlfile/control01.ctl", 3> "+DGROUP1/orcl/controlfile/control02.ctl", 4> "+DGROUP1/orcl/controlfile/control03.ctl" 5> scope=spfile'; sql statement: alter system set control_files="+DGROUP1/orcl/controlfile/control01.ctl", "+DGROUP1/orcl/controlfile/control02.ctl", "+DGROUP1/orcl/controlfile/control03.ctl" scope=spfile RMAN> startup connected to target database (not started) Oracle instance started database mounted database opened Total System Global Area 167772160 bytes Fixed Size 1218316 bytes Variable Size 67111156 bytes Database Buffers 96468992 bytes Redo Buffers 2973696 bytes [oracle@oel510gasm oradata]$ sqlplus / as sysdba SQL*Plus: Release 10.2.0.1.0 - Production on Wed Mar 16 22:02:21 2011 Copyright (c) 1982, 2005, Oracle. All rights reserved. Connected to: Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production With the Partitioning, OLAP and Data Mining options SQL> show parameter control_files NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ control_files string +DGROUP1/orcl/controlfile/cont rol01.ctl, +DGROUP1/orcl/contr olfile/control02.ctl, +DGROUP1 /orcl/controlfile/control03.ctl
