Olá,
Para melhor gerenciar o tamanho de um arquivo de dados ou até mesmo otimizar o desempenho geral de E/S do banco de dados, pode ser necessário mover um ou mais arquivos de dados (data files) de uma tablespace para um local diferente. Não só arquivos de dados, como também arquivos de controle (control files) e arquivos de redo log online (redo log files) podem sem movidos para localizações diferentes quando necessário. O propósito deste artigo é demonstrar os passos e comandos necessários para mover os arquivos de bancos de dados para outras localizações. Estes mesmos passos poderão ser executados também para renomear um arquivo de bancos de dados. Irei abordar os comandos necessários para mover não só os data files, como também os control files e os redo log files. Ao final, irei demonstrar um novo comando do Oracle 12c (ALTER DATABASE MOVE) que permite a movimentação ONLINE dos arquivos de dados. Esse novo comando é uma das novidades do Oracle 12c que foi mencionada no artigo de Junho/2013.
Movendo arquivos de controle (control files)
- Alterar o arquivo de inicialização spfile com a nova localização do control file (ALTER SYSTEM).
- Realizar shutdown do banco de dados.
- Mover o control file para a nova localização.
- Iniciar a instância e abrir o banco de dados (STARTUP).
Neste cenário irei abordar os arquivos de controle (control files). Abaixo podemos ver que os control files estão localizados em /oradata/BD01 conforme demonstrado tanto pelo resultado da view dinâmica de desempenho V$CONTROLFILE quanto pela infomação do arquivo de parâmetro de inicialização spfile. O objetivo será mover os control files para a nova localização em /oradata2/BD01.
$ sqlplus / as sysdba
SQL*Plus: Release 11.2.0.3.0 Production on Seg Ago 5 19:32:35 2013
Copyright (c) 1982, 2011, Oracle. All rights reserved.
Conectado a:
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - Production
With the Partitioning option
SQL> select * from v$controlfile;
STATUS NAME IS_ BLOCK_SIZE FILE_SIZE_BLKS
------- ------------------------------ ---- ---------- --------------
/oradata/BD01/control01.ctl NO 16384 594
/oradata/BD01/control02.ctl NO 16384 594
SQL> show parameter control_files;
NAME TYPE VALUE
------------------- ---------- ----------------------------
control_files string /oradata/BD01/control01.ctl,
/oradata/BD01/control02.ctl
SQL> alter system set control_files = '/oradata2/BD01/control01.ctl',
'/oradata2/BD01/control02.ctl' scope=SPFILE;
Sistema alterado.
SQL> shutdown immediate
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.
[oracle@linux1 /]$ mv /oradata/BD01/control*.ctl /oradata2/BD01/
SQL> startup
Instância ORACLE iniciada.
Total System Global Area 313860096 bytes
Fixed Size 1344652 bytes
Variable Size 109054836 bytes
Database Buffers 197132288 bytes
Redo Buffers 6328320 bytes
Banco de dados montado.
Banco de dados aberto.
SQL> select * from v$controlfile;
STATUS NAME IS_ BLOCK_SIZE FILE_SIZE_BLKS
------- ------------------------------ ---- ---------- --------------
/oradata2/BD01/control01.ctl NO 16384 594
/oradata2/BD01/control02.ctl NO 16384 594
Movendo arquivos de dados (data files) com o banco de dados fechado
- Realizar shutdown do banco de dados.
- Iniciar a instância e montar o banco de dados (STARTUP MOUNT).
- Copiar ou renomear o arquivo de dados para a nova localização.
- Atualizar o control file com a nova localização do arquivo de dados (ALTER DATABASE RENAME).
- Abrir o banco de dados (ALTER DATABASE OPEN).
- Deletar o arquivo de dados da localização antiga.
Neste cenário abordarei a movimentação dos arquivos de dados (data files). Abaixo podemos ver que o data file users01.dbf pertencente à tablespace USERS encontra-se localizado em /oradata/BD01 conforme demonstrado pela view de dicionário de dados DBA_DATA_FILES. O objetivo será mover o data file users01.dbf para a nova localização em /oradata2/BD01.
SQL> select file_id,file_name,tablespace_name
2 from dba_data_files
3 where tablespace_name='USERS';
FILE_ID FILE_NAME TABLESPACE_NAME
---------- ---------------------------------- ------------------
4 /oradata/BD01/users01.dbf USERS
SQL> shutdown immediate
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.
SQL> startup mount
Instância ORACLE iniciada.
Total System Global Area 313860096 bytes
Fixed Size 1344652 bytes
Variable Size 109054836 bytes
Database Buffers 197132288 bytes
Redo Buffers 6328320 bytes
Banco de dados montado.
SQL> !cp -a /oradata/BD01/users01.dbf /oradata2/BD01/users01.dbf
SQL> alter database rename file
2 '/oradata/BD01/users01.dbf'
3 to
4 '/oradata2/BD01/users01.dbf';
Banco de dados alterado.
SQL> alter database open;
Banco de dados alterado.
SQL> !rm /oradata/BD01/users01.dbf
SQL> select file_id,file_name,tablespace_name
2 from dba_data_files
3 where tablespace_name='USERS';
FILE_ID FILE_NAME TABLESPACE_NAME
---------- ---------------------------------- ------------------
4 /oradata2/BD01/users01.dbf USERS
Vale a pena salientar que neste cenário foi utilizado o comando ALTER DATABASE para mover o arquivo de dados. Esse método é útil quando precisamos mover arquivos de dados de tablespaces de sistema como as tablespaces SYSTEM, SYSAUX, UNDO e TEMP, pois essas tablespaces e seus data files não podem ser colocados OFFLINE enquanto o banco de dados estiver aberto.
Movendo arquivos de dados (data files) com o banco de dados aberto
- Colocar a tablespace do arquivo de dados no estado OFFLINE.
- Copiar ou renomear o arquivo de dados para a nova localização.
- Atualizar o control file com a nova localização do arquivo de dados (ALTER TABLESPACE RENAME).
- Colocar a tablespace do arquivo de dados no estado ONLINE.
- Deletar o arquivo de dados da localização antiga.
Neste cenário abordarei a movimentação dos arquivos de dados usando o comando ALTER TABLESPACE RENAME. Como já foi mencionado anteriormente, se o arquivo de dados que desejamos mover faz parte de uma outra tablespace alé da SYSTEM, SYSAUX, UNDO e TEMP, é preferível usar o método ALTER TABLESPACE para mover os data files por um motivo crucial: O banco de dados, exceto pela tablespace cujo arquivo de dados será movido, permanecerá disponível para acesso durante toda a operação.
SQL> alter tablespace users offline;
Tablespace alterado.
SQL> !cp -a /oradata/BD01/users01.dbf /oradata2/BD01/users01.dbf
SQL> alter tablespace users rename datafile
2 '/oradata/BD01/users01.dbf'
3 to
4 '/oradata2/BD01/users01.dbf';
Tablespace alterado.
SQL> alter tablespace users online;
Tablespace alterado.
SQL> !rm /oradata/BD01/users01.dbf
SQL> select file_id,file_name,tablespace_name
2 from dba_data_files
3 where tablespace_name='USERS';
FILE_ID FILE_NAME TABLESPACE_NAME
---------- ---------------------------------- ------------------
4 /oradata2/BD01/users01.dbf USERS
Movendo arquivos de redo log online (redo log files)
- Realizar shutdown do banco de dados.
- Copiar ou renomear o arquivo de redo log online para a nova localização.
- Iniciar a instância e montar o banco de dados (STARTUP MOUNT).
- Atualizar o control file com a nova localização do arquivo de redo log online (ALTER DATABASE RENAME).
- Abrir o banco de dados (ALTER DATABASE OPEN).
- Deletar o arquivo da localização antiga.
Neste cenário abordarei a movimentação de redo log files usando o comando ALTER DATABASE RENAME. Embora seja possível mover indiretamente arquivos de redo log online descartando grupos de redo log inteiros e adicionando-os novamente em um local diferente, essa solução poderá não ser bem sucedida caso o redo log file a ser descartado insistir em ficar com o status ACTIVE. Com esse status, o arquivo de redo log online não poderá ser excluído. No mais, o método usado abaixo é similar ao método usado para mover os arquivos de dados (data files). Abaixo podemos ver que os arquivos de redo log online encontram-se localizados em /oradata/BD01 conforme demonstrado pela view dinâmica de desempenho V$LOGFILE. O objetivo será mover o arquivo de redo log online redo01.log para a nova localização em /oradata2/BD01.
SQL> select * from v$logfile;
GROUP# STATUS TYPE MEMBER IS_
---------- ------- ------- ------------------------ ---
1 ONLINE /oradata/BD01/redo01.log NO
2 ONLINE /oradata/BD01/redo02.log NO
3 ONLINE /oradata/BD01/redo03.log NO
SQL> shutdown immediate
Banco de dados fechado.
Banco de dados desmontado.
Instância ORACLE desativada.
SQL> startup mount
Instância ORACLE iniciada.
Total System Global Area 313860096 bytes
Fixed Size 1344652 bytes
Variable Size 109054836 bytes
Database Buffers 197132288 bytes
Redo Buffers 6328320 bytes
Banco de dados montado.
SQL> !cp -a /oradata/BD01/redo01.log /oradata2/BD01/redo01.log
SQL> alter database rename file
2 '/oradata/BD01/redo01.log'
3 to
4 '/oradata2/BD01/redo01.log';
Banco de dados alterado.
SQL> alter database open;
Banco de dados alterado.
SQL> !rm /oradata/BD01/redo01.log
SQL> select * from v$logfile;
GROUP# STATUS TYPE MEMBER IS_
---------- ------- ------- ------------------------- ---
1 ONLINE /oradata2/BD01/redo01.log NO
2 ONLINE /oradata/BD01/redo02.log NO
3 ONLINE /oradata/BD01/redo03.log NO
Movendo arquivos de dados (data files) no Oracle 12c
No Oracle 12c, além de utilizarmos os métodos mostrados anteriormente, poderemos mover um arquivo de dados de forma ONLINE, ou seja, mesmo estando em uso pelo Oracle, fazendo uso do comando ALTER DATABASE MOVE. Com este método não precisaremos colocar a tablespace OFFLINE, nem mesmo copiar o arquivo utilizando comandos do sistema operacional. O comando ALTER DATABASE MOVE no Oracle 12c é capaz inclusive de criar o diretório da nova localização caso o mesmo não exista, ou seja, ele cria automaticamente os diretórios caso necessário e move o arquivo de dados. No exemplo abaixo, irei mover o arquivo de dados users01.dbf para a nova localização em /oradata2/BD01. Vale a pena salientar que o diretório /oradata2/BD01 não será criado previamente por mim de forma que o Oracle faça esse trabalho.
$ sqlplus / as sysdba
SQL*Plus: Release 12.1.0.1.0 Production on Seg Ago 5 19:48:47 2013
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Conectado a:
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
With the Partitioning, OLAP, Advanced Analytics and Real Application Testing options
SQL> alter database move datafile
2 '/oradata/BD01/users01.dbf'
3 to
4 '/oradata2/BD01/users01.dbf';
Banco de dados alterado.
SQL> select file_id,file_name,tablespace_name
2 from dba_data_files
3 where tablespace_name='USERS';
FILE_ID FILE_NAME TABLESPACE_NAME
---------- ---------------------------------- ------------------
4 /oradata2/BD01/users01.dbf USERS
No resultado acima, podemos verificar que o arquivo de dados foi movido com sucesso para a nova localização em /oradata2/BD01. Portanto, podemos verificar que o Oracle 12c criou o diretório BD01 em /oradata2 e moveu o arquivo de dados users01.dbf.
Para finalizar, segue abaixo um script que utilizo com uma certa frequência, quando preciso mover todos os arquivos de dados e redo log files de um banco de dados. O script detecta a origem dos arquivos e gera o comando ALTER DATABASE RENAME para todos eles. No exemplo abaixo, a origem dos arquivos é /oradata/BD01 e a nova localização na qual precisa ser informada é /oradata2.
SQL> SELECT 'alter database rename file '''
2 || name
3 || ''' to ''/oradata2/'
4 || (SELECT name FROM v$database)
5 || '/'
6 || SUBSTR (name, INSTR (name, '/', -1) + 1)
7 || ''';'
8 cmd
9 FROM v$datafile
10 UNION ALL
11 SELECT 'alter database rename file '''
12 || name
13 || ''' to ''/oradata2/'
14 || (SELECT name FROM v$database)
15 || '/'
16 || SUBSTR (name, INSTR (name, '/', -1) + 1)
17 || ''';'
18 FROM v$tempfile
19 UNION ALL
20 SELECT 'alter database rename file '''
21 || member
22 || ''' to ''/oradata2/'
23 || (SELECT name FROM v$database)
24 || '/'
25 || SUBSTR (member, INSTR (member, '/', -1) + 1)
26 || ''';'
27 FROM v$logfile;
CMD
-------------------------------------------------------------------------------------------
alter database rename file '/oradata/BD01/system01.dbf' to '/oradata2/BD01/system01.dbf';
alter database rename file '/oradata/BD01/undotbs01.dbf' to '/oradata2/BD01/undotbs01.dbf';
alter database rename file '/oradata/BD01/sysaux01.dbf' to '/oradata2/BD01/sysaux01.dbf';
alter database rename file '/oradata/BD01/users01.dbf' to '/oradata2/BD01/users01.dbf';
alter database rename file '/oradata/BD01/temp01.dbf' to '/oradata2/BD01/temp01.dbf';
alter database rename file '/oradata/BD01/redo01.log' to '/oradata2/BD01/redo01.log';
alter database rename file '/oradata/BD01/redo02.log' to '/oradata2/BD01/redo02.log';
alter database rename file '/oradata/BD01/redo03.log' to '/oradata2/BD01/redo03.log';
8 comentários:
Olá Eduardo,
Muito legal este post e seu blog! Parabéns.
Atenciosamente,
Camilla
Olá Camila,
Obrigado pela visita e pelo comentário ;-)
Abraços e até mais ...
Legatti
Valeu Eduardo, você me ajudou muito com este post!
Continue postando informações, assim você estará ajudando muita gente.
Obrigado.
Giovanni.
Olá Giovanni,
Obrigado pela visita!
Abraços e até mais
Legatti
Eduardo, parabéns pelo post meu caro. Bem didático, explicando em diversas situações e cenários. Muito bom!
Olá Alexandre,
Obrigado pela visita!
Abraços e até mais
Legatti
Ajudou muito, obrigado por disponibilizar seu conhecimento.
Olá Diego,
Obrigado pela visita!
Abraços,
Legatti
Postar um comentário