quinta-feira, 26 de outubro de 2017

Copiando arquivos do ASM para uma instance ASM remota

Uma feature muito útil existente desde a versão 11.1 do Automatic Storage Management (ASM) Command-Line Utility (ASMCMD) é o cp, além de permitir a cópia local de arquivos permite também a cópia remota entre instances ASM (coisa que nem todos sabem). 

Realizando a cópia remota de arquivos do ASM para ASM, descarta-se a necessidade de uma unidade auxilar (NFS, file system, ..) para a transição do arquivo, além de realizar uma conversão transparente entre Little-Endian e Big-Endian caso necessário. Para copias de arquivos non-ASM ou para um diskgroup ASM não existe a conversão direta do endian sendo necessário a utilização de ferramentas complementares para isto (RMAN).

Sintaxe para cópia remota: (caso o password não seja informado no comando ele será solicitado posteriormente, conforme exemplo abaixo)

cp [FILE NAME] [REMOTE ASM USER]/[PASSWORD]@[SERVER NAME].[ASM INSTANCE]:[REMOTE DESTINTATION]


ASMCMD> cp TOOLS.732.947846879 sys@server2.+ASM:+DGDATA/TESTE/TOOLS01.dbf
Enter password: **********
copying +DGDATA/ORCL1/datafile/TOOLS.732.947846879 -> server2:+DGDATA/TESTE/TOOLS01.dbf

ASMCMD> pwd
+DGDATA/TESTE
ASMCMD> ls -lt
Type      Redund  Striped  Time             Sys  Name
                                            N    TOOLS01.dbf => +DGDATA/ASM/DATAFILE/TOOLS01.dbf.10182.958218431
ASMCMD>

Caso a instance ASM no servidor remoto possua uma porta diferente da default 1521, especifique a porta através da opção --port

ASMCMD> cp --port 1525 TOOLS.732.947846879 sys@server2.+ASM:+DGDATA/TESTE/TOOLS01.dbf

Limitações do cp:


  • Não permite a cópia de arquivos como OCR ou SPFILE;
  • Não pode copiar arquivos entre duas instâncias remotas. A instância local do Oracle ASM deve ser a origem ou o destino da operação. 

Além do cp do ASMCMD existe o DBMS_FILE_TRANSFER que também permite a cópia de arquivos de forma local e remota realizando automaticamente (por padrão) a conversão de endian (11.2.0.4 e posterior).

"From 12c and in 11.2.0.4 DBMS_FILE_TRANSFER does the conversion by default. Using DBMS_FILE_TRANSFER the destination database converts each block when it receives a file from a platform with different endianness. Datafiles can be imported after they are moved to the destination database as part of a transportable operation without RMAN conversion."



PUT_FILE:


-- remote database
SQL> create directory dir2 as '+DGDATA/TESTE2';

Directory created.

-- local database
SQL> create directory dir1 as '+DGDATA/TESTE2';

Directory created.

SQL> create database link remote connect to user_copy identified by pwd1 using 'ORCL1';

Database link created.

BEGIN
  DBMS_FILE_TRANSFER.put_file(
   source_directory_object      => 'DIR1',
   source_file_name             => 'EXEMPLO.DBF',
   destination_directory_object => 'DIR2',
   destination_file_name        => 'EXEMPLO.DBF',
   destination_database         => 'REMOTE');
END;
/

PL/SQL procedure successfully completed.

-- remote ASM
ASMCMD> ls -lt
Type        Redund  Striped  Time             Sys  Name
                                              N    EXEMPLO.DBF => +DGDATA/ORCL1/DATAFILE/FILE_TRANSFER/EXEMPLO.DBF.10195.958231667
GET_FILE:

-- remote database
SQL> create directory dir1 as '/u01/orcl1/datafile';

Directory created.

-- local database
SQL> create directory dir2 as '+DGDATA/TESTE2';

Directory created.

SQL> create database link remote connect to user_copy identified by pwd1 using 'ORCL1';

Database link created.

BEGIN
  DBMS_FILE_TRANSFER.get_file(
   source_directory_object      => 'DIR1',
   source_file_name             => 'EXEMPLO.DBF',
   source_database              => 'REMOTE',
   destination_directory_object => 'DIR2',
   destination_file_name        => 'EXEMPLO.DBF');
END;
/

PL/SQL procedure successfully completed.

-- local ASM
ASMCMD> ls -lt
Type        Redund  Striped  Time             Sys  Name
                                              N    EXEMPLO.DBF => +DGDATA/ORCL2/DATAFILE/FILE_TRANSFER/EXEMPLO.DBF.1774.958232287


Referências:

https://docs.oracle.com/cd/B28359_01/server.111/b31107/asm_util.htm#OSTMG94243
https://docs.oracle.com/database/122/OSTMG/asmcmd-file-commands.htm#OSTMG94462
How to Migrate to different Endian Platform Using Transportable Tablespaces With RMAN (Doc ID 371556.1)
Mais informações →

sexta-feira, 20 de outubro de 2017

Quando iniciou e terminou a coleta de estatísticas?

Na DBA_OPTSTAT_OPERATIONS é mantido um histórico de todas as operações executadas utilizando a DBMS_STATS, logo, é possível identificar o inicio e fim de varias operações como: 


  • gather_table_stats;
  • lock_schema_stats;
  • gather_fixed_objects_stats;
  • gather_system_stats;
  • gather_schema_stats;
  • gather_dictionary_stats;
  • set_system_stats;
  • delete_table_stats;
  • entre outros.

select operation,
       target,
       to_char(start_time, 'dd/mm/yyyy hh24:mi:ss') start_time,
       to_char(end_time, 'dd/mm/yyyy hh24:mi:ss') end_time
  from DBA_OPTSTAT_OPERATIONS
 where operation = 'gather_system_stats';

OPERATION                      TARGET                         START_TIME          END_TIME
------------------------------ ------------------------------ ------------------- -------------------
gather_system_stats                                           16/10/2017 14:17:21 16/10/2017 14:17:21
gather_system_stats                                           16/10/2017 14:24:13 16/10/2017 14:24:14

select operation,
       target,
       to_char(start_time, 'dd/mm/yyyy hh24:mi:ss') start_time,
       to_char(end_time, 'dd/mm/yyyy hh24:mi:ss') end_time
  from DBA_OPTSTAT_OPERATIONS
 where operation = 'gather_schema_stats';

OPERATION                      TARGET                         START_TIME          END_TIME
------------------------------ ------------------------------ ------------------- -------------------
gather_schema_stats            SCHEMA1                        19/10/2017 00:02:05 19/10/2017 00:22:28
gather_schema_stats            SCHEMA2                        19/10/2017 00:22:28 19/10/2017 00:22:28
gather_schema_stats            SCHEMA3                        19/10/2017 00:22:28 19/10/2017 00:22:28
gather_schema_stats            SCHEMA4                        19/10/2017 00:22:28 19/10/2017 00:22:28
gather_schema_stats            SCHEMA5                        19/10/2017 00:22:34 19/10/2017 00:23:02

select operation,
       target,
       to_char(start_time, 'dd/mm/yyyy hh24:mi:ss') start_time,
       to_char(end_time, 'dd/mm/yyyy hh24:mi:ss') end_time
  from DBA_OPTSTAT_OPERATIONS
 where operation = 'gather_table_stats' and target like '%TABLE1%';

OPERATION                      TARGET                         START_TIME          END_TIME
------------------------------ ------------------------------ ------------------- -------------------
gather_table_stats             SCHEMA1.TABLE1                 24/09/2017 07:36:07 24/09/2017 08:13:19
gather_table_stats             SCHEMA1.TABLE1                 01/10/2017 06:53:58 01/10/2017 07:28:15
gather_table_stats             SCHEMA1.TABLE1                 08/10/2017 07:06:55 08/10/2017 07:41:41

--Identificando o tempo de retenção (em dias):

select dbms_stats.get_stats_history_retention from dual;

GET_STATS_HISTORY_RETENTION
---------------------------
                         31

--Alterando a retenção para para mais ou menos dias:

exec dbms_stats.alter_stats_history_retention(10);

PL/SQL procedure successfully completed.

select dbms_stats.get_stats_history_retention from dual;

GET_STATS_HISTORY_RETENTION
---------------------------
                         10
Mais informações →

quinta-feira, 19 de outubro de 2017

Quando a role foi criada?

Na dba_roles não temos nenhuma coluna informando a data de criação da role, contudo podemos obter a data através da sys.user$

.......................................................................................................................................................................................................................................................................................................................................

SQL> desc dba_roles;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 ROLE                                      NOT NULL VARCHAR2(30)
 PASSWORD_REQUIRED                                  VARCHAR2(8)
 AUTHENTICATION_TYPE                                VARCHAR2(11)


SQL> select to_char(ctime,'dd/mm/yyyy hh24:mi:ss') created from sys.user$ where name='RESOURCE';

CREATED
-------------------
16/10/2017 11:15:38
Mais informações →

Resizing a Non-root LVM Partition - Exadata

Após um deploy do Exadata é normal termos o ponto de montagem /u01 com aproximadamente 99G, entretando este tamanho nem sempre consegue comportar tudo o que é preciso especialmente quando é necessário que exista várias versões do Oracle Database instaladas (11.2.0.3, 11.2.0.4, 12.1.0.1, 12.1.0.2, 12.2.01)

O /u01 nada mais é que um Logical Volume Manager (LVM) partition e a Oracle deixou uma "gordurinha" para que possamos expandir ou criar novas partições caso seja necessário.

[root@dm01graf01 ~]# vgs
  VG      #PV #LV #SN Attr   VSize VFree
  VGExaDb   1   4   0 wz--n- 1.63t 1.45t

A partir da versão 11.2.3.2.1 do Exadata Software é possivel expandir o /u01 de forma online. Para verificar a versão do Exadata software basta executar um imageinfo:

[root@m01graf01 ~]# imageinfo

Kernel version: 2.6.39-400.248.3.el6uek.x86_64 #1 SMP Wed Mar 11 18:04:34 PDT 2015 x86_64
Image version: 12.1.2.1.1.150316.2
Image activated: 2015-05-01 16:10:18 -0300
Image status: success
System partition on device: /dev/mapper/VGExaDb-LVDbSys1

Identificando o filesystem:

[root@dm01graf01 ~]# df -h /u01
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VGExaDb-LVDbOra1
                       99G   81G   18G  82% /u01

Onde:

VG (Volume Group) = VGExaDb
LV (Logical Volume) = LVDbOra1

Utilizando o comando vgdisplay -s é possível obter mais detalhes da configuração atual do do filesystem


[root@dm01graf01 ~]# lvs -o lv_name,lv_path,vg_name,lv_size
  LV        Path                   VG      LSize
  LVDbOra1  /dev/VGExaDb/LVDbOra1  VGExaDb 100.00g
  LVDbSwap1 /dev/VGExaDb/LVDbSwap1 VGExaDb  24.00g
  LVDbSys1  /dev/VGExaDb/LVDbSys1  VGExaDb  30.00g
  LVDbSys2  /dev/VGExaDb/LVDbSys2  VGExaDb  30.00g

A option que permite o resize online é "resize_inode", logo, confirme se a mesma é listada:

[root@dm01graf01 ~]# tune2fs -l /dev/mapper/VGExaDb-LVDbOra1 | grep resize_inode
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype needs_recovery extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize

 Verificando a área livre (free):

[root@dm01graf01 ~]# vgdisplay -s
  "VGExaDb" 1.63 TiB  [184.00 GiB used / 1.45 TiB free]

Realizando o extend do LV em +100G:

[root@dm01graf01 ~]# lvextend -L +100G /dev/mapper/VGExaDb-LVDbOra1
  Size of logical volume VGExaDb/LVDbOra1 changed from 100.00 GiB (25600 extents) to 200.00 GiB (51200 extents).
  Logical volume LVDbOra1 successfully resized

Realizando o resize do filesystem:

[root@dm01graf01 ~]# resize2fs  /dev/mapper/VGExaDb-LVDbOra1
resize2fs 1.43-WIP (20-Jun-2013)
Filesystem at /dev/mapper/VGExaDb-LVDbOra1 is mounted on /u01; on-line resizing required
old_desc_blocks = 7, new_desc_blocks = 13
Performing an on-line resize of /dev/mapper/VGExaDb-LVDbOra1 to 52428800 (4k) blocks.
The filesystem on /dev/mapper/VGExaDb-LVDbOra1 is now 52428800 blocks long.

Verificando o novo tamanho do /u01:

[root@dm01graf01 ~]# df -h /u01
Filesystem            Size  Used Avail Use% Mounted on
/dev/mapper/VGExaDb-LVDbOra1
                      197G   81G  117G  41% /u01

As root LVM Partition também podem ser estedidas no Exadata utilizand os passos acima, da mesma forma em ODA-BM

Para versões do Exadata Software inferiores a 11.2.3.2.1 verifique os procedimentos conforme nota nas referências.


Referências:

http://docs.oracle.com/cd/E80920_01/DBMMN/maintaining-exadata-database-servers.htm#DBMMN21590
Mais informações →

sexta-feira, 29 de setembro de 2017

ORA-16188: LOG_ARCHIVE_CONFIG settings inconsistent

Após o desligamento de alguns servidores DR (Disaster Recovery) o parâmetro  LOG_ARCHIVE_CONFIG foi ajustado para '' (null) em ambas as instances do database pois não existiria mais nenhum Data Guard (ODG) configurado.




alter system set log_archive_config='';
Em função de outra manutenção uma das intancias precisou ser reiniciada, resultando então no erro ORA-16188 durante o startup:


WARNING: The 'LOG_ARCHIVE_CONFIG' init.ora parameter settings
are inconsistent with another started instance.  This may be
caused by the 'DB_UNIQUE_NAME' init.ora parameter being specified
differently on one or more of the other RAC instances; the
DB_UNIQUE_NAME parameter value MUST be identical for all
instances of the database.
Errors in file /u01/app/oracle/diag/rdbms/orcl/orcl2/trace/orcl2_lgwr_72945.trc:
ORA-16188: LOG_ARCHIVE_CONFIG settings inconsistent with previously started instance
LGWR (ospid: 72945): terminating the instance due to error 16188

 Apesar do erro informar que o parâmetro estava inconsistente entre as instances ele não estava:

SQL> select name, value from v$spparameter where name='log_archive_config';

NAME                      VALUE
------------------------- -------------------------
log_archive_config

Conforme reportado na Doc ID 1580482.1, isto ocorre em função de alguns problemas na atualização da v$dataguard_config entre as instances:





Para resolver o problema basta reajustar o parâmetro conforme abaixo em uma das instances que ainda está ativa:



alter system set log_archive_config=NODG_CONFIG  scope=both sid='*';


Realize um novo startup para que a instance suba sem apresentar a divergência supracitada.

Referência:

Standby Instance Crash or Failed to Startup with ORA-16188 (Doc ID 1580482.1)
Mais informações →

terça-feira, 29 de agosto de 2017

Row Locks (TX) - Como identificar a linha bloqueada

Em um banco de dados multiusuários como o Oracle database, é necessário que exista algum tipo de bloqueio de dados para que possam ser resolvidos os problemas associados à simultaneidade, consistência e integridade de dados. Estes bloqueios são mecanismos que impedem a interação destrutiva entre as transações que acessam o mesmo recurso.

Um dos tipos de bloqueios existentes é o bloqueio (lock) de linha identificado pelo evento de espera (wait event) "enq: TX - row lock contention".

Um lock do tipo linha ocorre naturalmente sobre a linha de uma tabela, ou seja, enquanto uma linha (registro) está "alocado", nenhuma outra sessão conseguirá alterá-lo até que a transação que originou o lock chegue ao seu fim, seja por commit ou rollback.


A identificação de um lock transacional (TX) pode ser realizada de diferentes formas, aqui utilizaremos o script utllockt.sql distribuído pela própria Oracle e encontrado abaixo do $ORACLE_HOME/rdbms/admin

Montando o cenário:

SESSÃO 1:


SQL> select distinct sid from v$mystat;

       SID
----------
        58

SQL> create table teste (id number);

Table created.

SQL> insert into teste values (1);

1 row created.

SQL> insert into teste values (2);

1 row created.

SQL> insert into teste values (3);

1 row created.

SQL> insert into teste values (4);

1 row created.

SQL> commit;

Commit complete.

SQL> update teste set id=5 where id=1;

1 row updated.

Observe que ao final do UPDATE não foi executado commit ou rollback;

SESSÃO 2:


SQL> select distinct sid from v$mystat;

       SID
----------
        51

SQL> update teste set id=6 where id=2;

1 row updated.

SQL> update teste set id=5 where id=1;


A sessão 2 (sid=51) ao tentar realizar a alteração da mesma linha da sessão 1 (sid=58) ficou "travada" pois a linha id=1 está bloqueada até que a sessão 1 realize um commit ou rollback do registro.


SESSÃO 3:


SQL> select distinct sid from v$mystat;

       SID
----------
        56

SQL> update teste set id=6 where id=2;

A sessão 3 (sid=56) ao tentar alterar a mesma linha que a sessão 2 (sid=51) também ficou presa, pois a sessão 2 ainda não concluiu sua transação, desta forma existe a sessão 2 aguardando a sessão 1 e a sessão 3 aguardando a sessão 2 conforme árvore de bloqueio abaixo:

SESSÃO 4:



SQL> set lines 200
SQL> @?/rdbms/admin/utllockt.sql
drop table lock_holders
           *
ERROR at line 1:
ORA-00942: table or view does not exist



Table created.

drop   table dba_locks_temp
             *
ERROR at line 1:
ORA-00942: table or view does not exist



Table created.


2 rows created.


Commit complete.


Table dropped.


1 row created.


Commit complete.


WAITING_SESSION   LOCK_TYPE         MODE_REQUESTED MODE_HELD      LOCK_ID1          LOCK_ID2
----------------- ----------------- -------------- -------------- ----------------- -----------------
58                None
   51             Transaction       Exclusive      Exclusive      196619            958
      56          Transaction       Exclusive      Exclusive      327712            947


Table dropped.

Cenário de bloqueio:



Identificando as linhas bloqueadas:

Sempre que uma sessão fica aguardando um lock transacional (row lock – TX), algumas informações adicionais são pobuladas na v$session:




Utilizando-se destes dados é possível identificar o ROWID da linha bloqueada.

O ROWID é uma pseudocolumn que representa o endereço de cada linha de uma tabela. Os valores desta pseudocoluna são strings que podem conter os caracteres A-Z, a-z, 0-9 e o sinal de mais (+) e a barra (/).

Os rowids são formados pelas seguintes informações:

  •          Data block: Bloco de dados que contém a linha;
  •          Row: Linha no bloco de dados;
  •          Database file: Arquivo de dados que a linha;
  •         Data object number: Número de identificação do objeto.


Agora basta utilizar o pacote DBMS_ROWID para interpretar os conteúdos de rowid. As funções do pacote extraem e fornecem informações sobre os quatro elementos rowid listados acima.

Como as colunas ROW_WAIT_* da v$session são populadas apenas quando uma sessão está aguardando alguma transação, podemos identificar a rowid (endereço da linha) que as sessões 2 (sid=51) e 3 (sid=56) estão aguardando.


Linha bloqueada da sessão 2:


SQL> set lines 200
SQL> col object_name for a30
SQL> select o.object_name,
  2  s.row_wait_obj#,
  3  s.row_wait_file#,
  4  s.row_wait_block#,
  5  s.row_wait_row#,
  6  dbms_rowid.rowid_create ( 1, s.ROW_WAIT_OBJ#, s.ROW_WAIT_FILE#, s.ROW_WAIT_BLOCK#, s.ROW_WAIT_ROW# ) as "ROWID"
  7  from v$session s, dba_objects o
  8  where s.sid=51
  9  and s.ROW_WAIT_OBJ# = o.OBJECT_ID;


OBJECT_NAME                    ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW# ROWID
------------------------------ ------------- -------------- --------------- ------------- ------------------
TESTE                                  57927              1           83065             0 AAAOJHAABAAAUR5AAA


SQL> select * from teste where rowid='AAAOJHAABAAAUR5AAA';

        ID
----------
         1

 Linha bloqueada da sessão 3:



SQL> select o.object_name,
  2  s.row_wait_obj#,
  3  s.row_wait_file#,
  4  s.row_wait_block#,
  5  s.row_wait_row#,
  6  dbms_rowid.rowid_create ( 1, s.ROW_WAIT_OBJ#, s.ROW_WAIT_FILE#, s.ROW_WAIT_BLOCK#, s.ROW_WAIT_ROW# ) as "ROWID"
  7  from v$session s, dba_objects o
  8  where s.sid=56
  9  and s.ROW_WAIT_OBJ# = o.OBJECT_ID;


OBJECT_NAME                    ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW# ROWID
------------------------------ ------------- -------------- --------------- ------------- ------------------
TESTE                                  57927              1           83065             1 AAAOJHAABAAAUR5AAB


SQL> select * from teste where rowid='AAAOJHAABAAAUR5AAB';

        ID
----------
         2

Neste exemplo (cenário), como não foi utilizado bind variables nas operações DML é possível identificar também o valor bloqueado pelo próprio texto sql da instrução:



SQL> select sql_id from v$session where sid=51;

SQL_ID
-------------
g7tsgdb2thq5t

SQL> select sql_fulltext from v$sql where sql_id='g7tsgdb2thq5t';

SQL_FULLTEXT
--------------------------------------------------------------------------------
update teste set id=5 where id=1

SQL> select sql_id from v$session where sid=56;

SQL_ID
-------------
7r7ugkhm1bnaz

SQL> select sql_fulltext from v$sql where sql_id='7r7ugkhm1bnaz';

SQL_FULLTEXT
--------------------------------------------------------------------------------
update teste set id=6 where id=2


Com a utilização de bind variables a instrução retornada seria similar a:



update teste set id=:b2 where id=:b1


A identificação da instrução também é importante para saber quais colunas estão sofrendo alterações, pois a linha retornada pelo rowid pode conter várias colunas diferentemente do exemplo onde a tabela possuía apenas uma coluna.


Referências:

https://docs.oracle.com/database/122/CNCPT/data-concurrency-and-consistency.htm#CNCPT1313
https://docs.oracle.com/database/122/REFRN/V-SESSION.htm#REFRN30223

https://docs.oracle.com/database/122/SQLRF/Data-Types.htm#SQLRF50998
Mais informações →

sábado, 5 de agosto de 2017

Oracle RAC 10g sobre GRID 11g

Executando o DBCA (database configuration assistant) para criar uma nova base de dados RAC 10g (10.2.0.5) sobre um grid 11g (11.2.0.4) notei que na tela de "boas-vindas" não haviam as opções de tipo de database para seleção (RAC ou Single), logo, se a criação fosse prosseguida teria-se ao final uma base de dados single instance.



Conforme notas:


  • Pre 11.2 Database Issues in 11gR2 Grid Infrastructure Environment (Doc ID 948456.1)
  • RAC: Frequently Asked Questions (RAC FAQ) (Doc ID 220970.1)

Para se criar um database inferior a versão 11gR2 sobre um grid infrastructure 11gR2 é necessário que os nodes sejam pinados (fixados) no CRS.

Como root:


[root@srvtst01 ~]# olsnodes -t -n
srvtst01      1       Unpinned
srvtst02      2       Unpinned
[root@srvtst01 ~]# crsctl pin css -n srvtst01 srvtst02
CRS-4664: Node srvtst01 successfully pinned.
CRS-4664: Node srvtst02 successfully pinned.
[root@srvtst01 ~]# olsnodes -t -n
srvtst01      1       Pinned
srvtst02      2       Pinned
[root@srvtst01 ~]#

Feito o ajuste bastou abrir novamente o DBCA que as opções já estavam disponíveis.




Outro detalhe em relação a criação de um banco pré 11gR2 sobre um grid 11gR2 destacado nas mesmas notas supracitadas é a existência do bug 8288940 que foi corrigido na versão 10.2.0.5 porém requer que um patch <patch 8288940> seja aplicado nas demais versões 10.2.0.3, 10.2.0.4, 11.1.0.6 e 11.1.0.7



Mais informações →
Postagens mais antigas Página inicial

Translate

#Oracle

#Oracle
Disclaimer: The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.

#Blog reconhecido

Marcadores

Postagens populares