Oracle RAC

Vamos aproveitar esse post para escrever de um tema bem atual: Oracle RAC. O objetivo aqui é tratar alguns novos conceitos e analisarmos algumas diferenças entre uma single instance.

Arquitetura:

Arquitetura Oracle Rac

Novos componentes:
Oracle Clusteware: realiza serviços básicos no nível do sistema operacional que permitem que software Oracle rode em modo de clustering, componente essencial para a instalação do Oracle Rac
Voting Disk: é uma partição de disco compartilhada entre os nós do RAC onde pode ser verificar os membros da estrutura e seu status
OCR: registro das informações dos membros: Vip Address, service, database, asm, entre outros

Instância:

Instance

Novos componentes:

Cache Fusion: mecanismo que garante a coerência entre os caches, realiza a transferência dos blocos da holding instance para request instance
Cluster Private High Speed Network: Interconnect
Global enqueue service: coordena o acesso aos blocos de dados dos nós garantindo a coerência
Global cache service: processo que implementa o Cache Fusion
LMD: gerenciam a requisições de acesso aos blocos e deadlocks
LMON: gerenciam a queda das instância e recuperação no caso de falha
LMSx: gerenciam a quantidade de mensagens remotas
 
Contenção de DMLs, Querys e Serialização
 
DMLs e Querys intensivas num pequeno conjunto de blocos
 

GC Buffer Busy

Conseqüência

Re-masterização de blocos via interconnect entre os nós ocasionando lentidão
 

Solução

Módulos que utilizem tabelas diferentes podem ser configurados para entrada em apenas uma das instâncias (configuração de failover no listener) / configuração de serviços

Sequences

CACHE or NO CACHE

Quando no cache é utilizado o dicionário de dados tem que ser atualizado com a requisição NEXTVAL. Isso significa que o row cache gerar um lock com essa requisição. Múltiplas sessões requisitando um nextval gera o wait event “row cache lock”.

Quando cache + ordering são utilizados e o parâmetro cluster_database = true,  a sessão requer um NEXTVAL é necessário conseguir um lock exclusivo na shared pool para obter o valor. Quando múltiplas requisitam o mesmo valor o wait event gerado é ‘DFS lock Handle’ também uma contenção, que pode ser resolvida por exemplo aumentando o valor de cache.

 

A configuração que gera menor impacto em termos de performance é:

 

CACHE e NOORDER (default)

Essa configuração tem menor impacto de performance no RAC, cada instance armazena um número diferente no cache e não serão globalmente ordenadas, gerando gaps

 

Gaps em seqüences sempre são possíveis, quando ocorre falha e/ou rollback de transações!

Best Practises

Algumas boas práticas, porém de qualquer forma recomendo a leitura das notes elencadas ao final do artigo pois há muito mais que isso:

Designer

Eliminar qualquer ponto de falha na arquitetura

Exemplo: Incluir Cluster Interconnect Redundancy (NIC bonding), múltiplos paths no storage, utilizando 2 HBAs, Disk mirroring / Raid

ASM fortemente recomendado para a versão 10g e obrigatório na versão 11g

 

Network

Switch (ou redundante switches) são necessários e altamente recomendados para private network (crossover cables não são suportados). Se utilizarem uma VLAN deverá ser configurada 1:1 para evitar congestionamentos. (Vlan Settings: 9761210).
Vips e Scan Vips (Recomendável a partir de 11gR2) devem ser o mesmo na sub-rede e na interface pública
As interfaces de rede devem ter o mesmo nome em todos os nós (eth1 -> eth1 suporta o Vip e eth2 -> suporte a interface privada)

 

Storage

Utilizar múltiplas HBAs
Assegurar a utilização de discos NFS juntamente com ASM
No mínimo 4 LUNs de mesmo tamanho em tamanho e desempenho (Cada LUN em um Raid Grupo separado)
Apenas 2 diskgroups são necessários (ASM) um para flash recovery area e o outro para área de dados
Criar uma retundância externa
 

Cluster e Grid Infra-estrutura

Recomenda-se utilização de RAW ou Block Devices na área dos voting disks
Se a versão do BD é 11.2.0.2 pode se utilizar NIC retundancy para o interconnect

Note: 1210883.1

 

Instalação

Verificar os pré-requisitos do Cluster com o utilitário cluvfy
Instalar o ASM em paths diferentes do Oracle Home, garantindo disponibilidade e facilidade para realização de upgrades

 

 Notes Interessantes:

RAC and Oracle Clusterware Best Practices and Starter Kit (Platform Independent) [ID 810394.1]
Where Should the CRS Home be Placed? [ID 549196.1]
When Starting the Database with Srvctl [ID 749515.1]
Transactional Sequences in Applications in a RAC environment [ID 561414.1]
RAC and Sequences [ID 853652.1]

 

Anúncios
Publicado em Oracle | Publicar um comentário

Oracle índices

Oracle – Entendendo um pouco mais sobre índices

Os índices certamente não resolverão todos os seus problemas de desempenho, mas se bem utilizados são de grande ajuda para a busca de dados de forma eficiente. Aliás criar índices para variadas colunas, sem visualizar a Clausula WHERE e a Seletividade não é uma boa tática, mas isso é tema para outros posts. Vamos tentar quebrar alguns paradigmas sobre índices, são eles:

a)      Com o tempo, índices se tornam desbalanceados e, com isso, requerem uma reconstrução (rebuild) para um bom desempenho

b)      Índices com valores sempre crescente ou monôtonico (nunca diminuem ex.: Sequences) tendem a piorar sua performance com o passar do tempo, pois precisam de “re-balanceamento”

Um pouco da estrutura de um índice B*Tree:

  • Leaf Nodes: contêm entradas que se referem diretamente as linhas das tabelas;
  • Branch Nodes: contêm entradas que se referem a “Leaf Nodes”; e
  • Um único Root Node: que é um “Ramo” , o topo da estrutura da árvore

O número de entradas em um “Branch Block” é determinado em parte pelo DB_BLOCK_SIZE, bem como o comprimento dos valores dos dados. Cada entrada em um “Leaf Block” consiste em linhas com 2 colunas. A primeira coluna é o valor do dado propriamente dito e a segunda coluna é o ROWID.

O ROWID (“endereço” físico do dado) que é uma pseudo-coluna de cada tabela de seu database e contêm as seguintes informações:

Partes do ROWID Significado
AAADVH (até 6º caracter) Segmento
AAE (3 caracteres seqüentes) Datafile@tablespace
AAAADk (6 caracteres sequentes)  Block@datafile
AAA (3 últimos caracteres) Número de linhas no bloco

 Há diversos tipos de índices: Bitmap, Reverse Keys, Function Based Index, Index Descending … . Cada um desses tem características diferentes e cada um deles apresenta ganhos de desempenho com um tipo de acesso aos dados. Já perceberam que para fazer um post completo sobre índices seria uma leitura muito, muito, muito extensa e provavelmente ainda faltaria muitas coisas. Mas vamos continuar com os pontos mais importantes:

O Blevel é considerado por alguns DBAs como um balizador para um Index Rebuild! O Blevel é o número de níveis que o índice tem gerado. Mesmo para índices muito grande, ele dificilmente será superior a 4. Cada Blevel representa um I/O adicional que deve ser realizado na árvore do índice!

Voltando ao assunto sobre o Rebuild relacionado ao Blevel, se você tem um índice com crescimento monotônico (uma chave que é uma sequência que só aumenta e nunca diminui), e as entradas são deletadas, porém nunca são re-utilizadas, um rebuild PODE SER útil e o Blevel aqui poderia ser um indicador, mas a análise não pode basear-se apenas nesse número. Tomas Kytes tem grandes discussões sobre esse tema, uma delas, pode ser acompanhada por: http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2913600659112#43555424746793.

A perda de performance, não ocorre porque o índice fica “desbalanceado”, pois o balanceamento é realizado conforme a inserção de dados. A perda de performance, pode ocorrer porque o índice se torna mais espaçado, com mais blocos livres. Na maioria das vezes esse problema ocorre devido a exclusões de linhas o que resulta em entradas de índices não re-utilizadas.

Algumas notas da própria Oracle com o objetivo de encontrarmos quais indices devem ser rebuildados(Script: Lists All Indexes that Benefit from a Rebuild [ID 122008.1] ), ( Index Rebuild, the Need vs the Implications [ID 989093.1] ) e ( Script to investigate a b-tree index structure [ID 989186.1] ).

A solução após as devidas análises e caso chegue-se a conclusão de que a performance (diminuição de blocos lidos em SQLs) ou o ganho em termos de espaço em disco irão compensar a janela de manutenção para o rebuild …. mãos a obra!!!!

Bom artigos sobre rebuild podem ser encontrados em www.dbazine.com e procurem artigos de performance sobre o assunto de autoria de Jonathan Lewis, alguns deles: Unbalaced Indexes? ( www.dbazine.com/jlewis13.shtml ) e When should you rebuild an index? ( www.dbazine.com/jlewis14.shtml ).

Índice é um assunto muito interessante e muito vasto! Por isso e para falarmos de outras métricas interessantes que influenciam o otimizador a utilizar ou não um determinado índice, precisaremos de muitos e muitos posts. Ao longo do post, espero ter quebrado os dois mitos citado no início desse. 

Abraços espero ter ajudado a entenderem um pouco sobre índices. 

By José Eduardo Fiamengui Júnior

Publicado em Oracle | Publicar um comentário

Performance DashBoard

Performance DashBoard

Para realização de Tuning em uma base SQLServer a partir da versão 2005 e Service Pack 2  podemos utilizar a Ferramenta Performance DashBoard. Essa ferramenta possibilita visualizar vários dados do database inclusive algumas métricas como CPU utilizada pelo database, eventos e TopSqls ( comparando com o Oracle, seria um AWR ou Statspack bem menos robusto, em ambiente gráfico ), porém essa ferramenta peca em não armazenar os dados em um repositório. Dessa forma, todas as informações coletadas são em tempo real.

A ferramenta coleta Snapshots do ambiente em tempo real e essas statistics podem ser “impressas” em PDF ou CSV.

O download da ferramenta pode ser feito em: http://www.microsoft.com/download/en/details.aspx?id=22602

A instalação é bem simples e padrão Microsoft Next-Next-Finish.
Como fazer para gerar os relatórios:
a)      Entre no Sql Management Studio
b)      Botão direito > Reports > Custom Reports
c)       Escolha o relatório principal: performance_dashboard_main.rdl

Tela Principal

Por padrão, a ferramenta deixa seus relatórios no diretório:
c:\program files\microsoft sql server\90\tools\performancedashboard\

 A partir daí é só clicar nas métricas que te interessam para análise, por exemplo podemos ver a tela de Waits:

 TopSQLs por consumo de CPU:

  Para não extender muito o artigo não coloquei aqui os TopSQLs, mas juntamente com o gráfico é possível visualizar os SQLs que estão em execução pelas métricas escolhidas.

Bom a partir daí, a análise fica mais interessante, podendo partir para:

a)      Coleta de statistics ( Por exemplo, utilizando “exec sp_updatestats” )
b)      Otimização dos SQLs ( Partindo para criação de índices )
c)       Colocando discos mais rápidos ( SSDs)

Muitas outras possibilidades, …..

 Forte abraço.
José Eduardo Fiamengui Júnior

Publicado em SQL Server | 1 Comentário

TM Locks

Locks são mecanismos necessários para a proteção de dados, pois com início dos sistemas computacionais multi-usuários, torna-se necessário a criação de formas que impeçam um usuário de atualizar ou apagar um determinado registro ao mesmo tempo.

Nesse post vamos tratar especificamente sobre Locks de TM: Locks

São usados principalmente para fazer concorrência com operação simultâneas DDL, como a prevenção de uma tabela que não pode ser apagada no meio de uma operação DML (Insert, Delete, Update, … ) e Querys. Quando há uma instrução DDL incidindo sobre uma tabela, um bloqueio é adquirido.

Uma transação adquire bloqueio de tabela quando a tabela é modificada nas seguintes declarações DML (Insert, Delete, Update e Select for Update), essas operações necessitam de bloqueios para 2 propósitos:
  a) Reservar o acesso DML para a tabela em nome de uma transação
  b) Evitar operações DDL que entrariam em conflito com a transação

Segundo o Tuning Guide: http://download.oracle.com/docs/cd/B19306_01/server.102/b14211/instance_tune.htm

A causa mais comum para TM Locks é a falta de índices em colunas que são chaves estrangeiras (Foreign Keys Constraints).

Nesse ponto, temos que pensar em como descobrir as chaves estrangeiras (não indexadas), mais informações sobre esse tipo de constraint pode ser encontrado no post Modelagem, Integridade e Normalização.

A note: ID 16428.1 do metalink nos mostra como:
a) Criar a tabela:
CREATE TABLE foreign_key_exceptions
(owner VARCHAR2(30),
constraint_name VARCHAR2(30),
status VARCHAR2(8),
table_name VARCHAR2(30),
foreign_key VARCHAR2(2000));

b) Esse script popula a tabela criada no passo (a):
Declare
pl_cons_column VARCHAR2(30);
pl_foreign_key VARCHAR2(2000);
pl_ind_column VARCHAR2(30);
pl_ind_name VARCHAR2(30);
pl_ind_owner VARCHAR2(30);
pl_index VARCHAR2(2000);
CURSOR c1 IS SELECT constraint_name,owner,table_name,status
FROM dba_constraints
WHERE constraint_type=’R’;
CURSOR c2(cons_name VARCHAR2,cons_owner VARCHAR2) IS SELECT column_name
FROM dba_cons_columns
WHERE constraint_name=cons_name
AND owner=cons_owner
ORDER BY dba_cons_columns.position;
CURSOR c3(ind_table varchar2,tab_owner varchar2) IS
SELECT index_name, owner
FROM dba_indexes
WHERE table_name=ind_table
AND table_owner=tab_owner;
CURSOR c4(ind_name varchar2,ind_owner varchar2) IS
SELECT column_name
FROM dba_ind_columns
WHERE INDEX_NAME=ind_name
AND INDEX_OWNER=ind_owner
ORDER BY dba_ind_columns.column_position;
BEGIN
FOR c1_rec in c1 LOOP
pl_cons_column := NULL;
pl_foreign_key := NULL;
pl_ind_column := NULL;
pl_ind_name := NULL;
pl_ind_owner := NULL;
pl_index := NULL;
OPEN c2(c1_rec.constraint_name,c1_rec.owner);
FETCH c2 INTO pl_cons_column;
pl_foreign_key := pl_cons_column;
LOOP
FETCH c2 into pl_cons_column;
EXIT WHEN c2%NOTFOUND;
pl_foreign_key := pl_foreign_key||’,’||pl_cons_column;
END LOOP constraint_names;
CLOSE c2;
OPEN c3(c1_rec.table_name,c1_rec.owner);
LOOP
FETCH c3 INTO pl_ind_name,pl_ind_owner;
EXIT WHEN c3%NOTFOUND;
OPEN c4(pl_ind_name,pl_ind_owner);
FETCH c4 INTO pl_ind_column;
pl_index := pl_ind_column;
IF pl_index=pl_foreign_key THEN
CLOSE c4;
EXIT index_name;
END IF;
IF pl_index = SUBSTR(pl_foreign_key,1,LENGTH(pl_index)) THEN
LOOP
FETCH c4 INTO pl_ind_column;
EXIT WHEN c4%NOTFOUND;
pl_index:= pl_index||’,’||pl_ind_column;
IF pl_index=pl_foreign_key
THEN
CLOSE c4;
EXIT index_name;
END IF;
IF pl_index != SUBSTR(pl_foreign_key,1,LENGTH(pl_index))
THEN
EXIT index_columns;
END IF;
END LOOP index_columns;
END IF;
CLOSE c4;
END LOOP index_name;
CLOSE c3;
IF pl_index != pl_foreign_key OR pl_index IS NULL THEN

INSERT INTO foreign_key_exceptions VALUES
(c1_rec.owner,c1_rec.constraint_name,c1_rec.status,
c1_rec.table_name,pl_foreign_key);
COMMIT;
END IF;
END LOOP;
END;
/

c) Executar o SQL abaixo para verificar as FKs não-indexadas:

A partir daí é só indexá-las e terminamos com mais esse pequeno problema que pode afetar muitas aplicações, causando famosos problemas de desempenho.

Mais sobre os tipos de locks odem ser encontrados em: http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#sthref2066

Good Bye.

José Eduardo Fiamengui Júnior

Publicado em Oracle | Publicar um comentário

Hash Group By X Sort Group By

Para evitarmos problemas já conhecidos de usuários reclamando de lentidão é uma boa prática testarmos as funcionalidades mais importantes da aplicação e com isso, evitamos futuras dores de cabeça, pois afinal nunca ouvimos a frase abaixo:

 a)  Após a migração estamos com lentidão nas querys: X, Y e Z ;
Ou ainda e nesse caso:
 b)  A ordem das linhas retornadas não são mais as mesmas ???? !!!!

Então vamos as vias de fato, falando sobre um alteração ocorrida após a versão 10gR2.

Na versão Oracle9i e Oracle10gR1 temos como comportamento default para SQLs com a clausula GROUP BY a utilização do algoritmo SORT GROUP BY que envolve realizar classificação de dados para as colunas envolvidas e acumular os resultados agregados. O HASH GROUP BY calcula todas as linhas em uma hash table e a joga em memória e só devolve a primeira linha quando todas já foram agregadas. Pode ser necessário a criação de tabelas temporárias (work tables) para a resolução e o acesso a esses dados podem ser paralelizados.

Vamos estudar o caso do simples comando abaixo:

SQL>  SELECT OBJECT_TYPE, COUNT(*) FROM DBA_OBJECTS GROUP BY OBJECT_TYPE ;

Oracle: 10.1.0.3 (Sort Group By)

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Rows     Row Source Operation
——-  —————————————————
     44  SORT GROUP BY (cr=1727 pr=7 pw=0 time=0 us cost=253 size=4059 card=369) 
  72009   VIEW  DBA_OBJECTS (cr=1727 pr=7 pw=0 time=1271203 us cost=252 size=4059 card=369)
  72009    UNION-ALL  (cr=1727 pr=7 pw=0 time=1040215 us)
      0     TABLE ACCESS BY INDEX ROWID SUM$ (cr=2 pr=2 pw=0 time=0 us cost=1 size=11 card=1)
      1      INDEX UNIQUE SCAN I_SUM$_1 (cr=1 pr=1 pw=0 time=0 us cost=0 size=0 card=1)(object id 956)
  72008     FILTER  (cr=1723 pr=4 pw=0 time=548046 us)
  72893      HASH JOIN  (cr=907 pr=0 pw=0 time=1238908 us cost=250 size=79860 card=726)
     92       INDEX FULL SCAN I_USER2 (cr=1 pr=0 pw=0 time=182 us cost=1 size=344 card=86)(object id 47)
  72893       HASH JOIN  (cr=906 pr=0 pw=0 time=690104 us cost=248 size=76956 card=726)
     92        INDEX FULL SCAN I_USER2 (cr=1 pr=0 pw=0 time=182 us cost=1 size=1892 card=86)(object id 47)
  72893        TABLE ACCESS FULL OBJ$ (cr=905 pr=0 pw=0 time=197794 us cost=247 size=60984 card=726)
   3775      TABLE ACCESS BY INDEX ROWID IND$ (cr=816 pr=4 pw=0 time=0 us cost=2 size=8 card=1)
   4648       INDEX UNIQUE SCAN I_IND1 (cr=85 pr=4 pw=0 time=0 us cost=1 size=0 card=1)(object id 41)
      0      NESTED LOOPS  (cr=0 pr=0 pw=0 time=0 us cost=2 size=29 card=1)
      0       INDEX FULL SCAN I_USER2 (cr=0 pr=0 pw=0 time=0 us cost=1 size=20 card=1)(object id 47)
      0       INDEX RANGE SCAN I_OBJ4 (cr=0 pr=0 pw=0 time=0 us cost=1 size=9 card=1)(object id 39)
      1     NESTED LOOPS  (cr=2 pr=1 pw=0 time=0 us cost=2 size=7 card=1)
      1      INDEX FULL SCAN I_LINK1 (cr=1 pr=1 pw=0 time=0 us cost=1 size=3 card=1)(object id 137)
      1      INDEX RANGE SCAN I_USER2 (cr=1 pr=0 pw=0 time=0 us cost=1 size=4 card=1)(object id 47)

 Oracle: 11.2.0.1 (Hash Group By)

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Rows     Row Source Operation
——-  —————————————————
     44  HASH GROUP BY (cr=1727 pr=316 pw=0 time=0 us cost=259 size=745756 card=67796)
  72009   VIEW  DBA_OBJECTS (cr=1727 pr=316 pw=0 time=6712987 us cost=254 size=745756 card=67796)
  72009    UNION-ALL  (cr=1727 pr=316 pw=0 time=6448745 us)
      0     TABLE ACCESS BY INDEX ROWID SUM$ (cr=2 pr=0 pw=0 time=0 us cost=1 size=11 card=1)
      1      INDEX UNIQUE SCAN I_SUM$_1 (cr=1 pr=0 pw=0 time=0 us cost=0 size=0 card=1)(object id 956)
  72008     FILTER  (cr=1723 pr=315 pw=0 time=5933607 us)
  72893      HASH JOIN  (cr=907 pr=0 pw=0 time=1286352 us cost=252 size=7989850 card=72635)
     92       INDEX FULL SCAN I_USER2 (cr=1 pr=0 pw=0 time=182 us cost=1 size=344 card=86)(object id 47)
  72893       HASH JOIN  (cr=906 pr=0 pw=0 time=731097 us cost=250 size=7699310 card=72635)
     92        INDEX FULL SCAN I_USER2 (cr=1 pr=0 pw=0 time=273 us cost=1 size=1892 card=86)(object id 47)
  72893        TABLE ACCESS FULL OBJ$ (cr=905 pr=0 pw=0 time=227259 us cost=248 size=6101340 card=72635)
   3775      TABLE ACCESS BY INDEX ROWID IND$ (cr=816 pr=315 pw=0 time=0 us cost=2 size=8 card=1)
   4648       INDEX UNIQUE SCAN I_IND1 (cr=85 pr=0 pw=0 time=0 us cost=1 size=0 card=1)(object id 41)
      0      NESTED LOOPS  (cr=0 pr=0 pw=0 time=0 us cost=2 size=29 card=1)
      0       INDEX FULL SCAN I_USER2 (cr=0 pr=0 pw=0 time=0 us cost=1 size=20 card=1)(object id 47)
      0       INDEX RANGE SCAN I_OBJ4 (cr=0 pr=0 pw=0 time=0 us cost=1 size=9 card=1)(object id 39)
      1     NESTED LOOPS  (cr=2 pr=1 pw=0 time=0 us cost=2 size=7 card=1)
      1      INDEX FULL SCAN I_LINK1 (cr=1 pr=1 pw=0 time=0 us cost=1 size=3 card=1)(object id 137)
      1      INDEX RANGE SCAN I_USER2 (cr=1 pr=0 pw=0 time=0 us cost=1 size=4 card=1)(object id 47)

Há alguns bugs documentados no metalink com a utilização desse novo algoritmo, alguns notes (6471770, 6818207 e 7716219). Esses erros estão relacionados desde trazer resultados errados até altíssima utilização de tablespace temporária, entre outros.

Normalmente a solução de contorno está em alterar o parâmetro _gby_hash_aggregation_enabled = false, no entanto acredito que essa seja uma solução muito ofensiva já que desabilita essa nova funcionalidade para toda base de dados e uma outra possibilidade seria fazer o mesmo  apenas para um comando via hint /*+ OPT_PARAM(‘_gby_hash_aggregation_enabled’ ‘false’).

Não se deve confiar em uma ordenação de resultados sem utilizar a clausula ORDER BY, como tratado por Tomas Kyte no artigo http://tkyte.blogspot.com/2005/08/order-in-court.html, no entanto antes da versão 10.2 você pode não ter se preocupado com essa ordenação já que os resultados eram ordenados pelo algoritmo de SORT ORDER BY. No entanto a partir dessa versão você pode ter grandes surpresas na ordem de retorno das linhas.

Normalmente, o algoritmo HASH GROUP BY é mais eficiente do que o algoritmo de SORT GROUP BY. No caso do SQL que fizemos acima temos:

call     count       cpu    elapsed       disk      query    current        rows
——- ——  ——– ———- ———- ———- ———-  ———-
Parse        1      0.03       0.27          0          4          0           0
Execute      1      0.00       0.01          0          0          0           0
Fetch        4      0.65       0.81          7       1727          0          44
——- ——  ——– ———- ———- ———- ———-  ———-
total        6      0.68       1.09          7       1727          0          44

Oracle: 10.1.0.3 (Sort Group By)

call     count       cpu    elapsed       disk      query    current        rows
——- ——  ——– ———- ———- ———- ———-  ———-
Parse        1      0.14       0.08          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        4      0.53       0.61          7       1727          0          44
——- ——  ——– ———- ———- ———- ———-  ———-
total        6      0.67       0.69          7       1727          0          44

Oracle: 11.2.0.1 (Hash Group By)

Os testes foram executadas nas mesmas condições de temperatura e pressão e tivemos cerca de 35 %  a menos no tempo de resposta.

Vamos a mais um caso:

Oracle: 10.1.0.3 (Sort Group By)

SELECT OBJECT_TYPE, STATUS, COUNT(*) FROM DBA_OBJECTS
GROUP BY OBJECT_TYPE, STATUS
ORDER BY OBJECT_TYPE, STATUS

call     count       cpu    elapsed       disk      query    current        rows
——- ——  ——– ———- ———- ———- ———-  ———-
Parse        1      0.06       0.05          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        5      0.51       0.59          7       1727          0          49
——- ——  ——– ———- ———- ———- ———-  ———-
total        7      0.57       0.64          7       1727          0          49

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Rows     Row Source Operation
——-  —————————————————
     49  SORT ORDER BY (cr=1727 pr=7 pw=0 time=0 us cost=254 size=5904 card=369)
     49   SORT GROUP BY (cr=1727 pr=7 pw=0 time=144 us cost=254 size=5904 card=369)
  72048    VIEW  DBA_OBJECTS (cr=1727 pr=7 pw=0 time=1296206 us cost=252 size=5904 card=369)
  72048     UNION-ALL  (cr=1727 pr=7 pw=0 time=1065476 us)
      0      TABLE ACCESS BY INDEX ROWID SUM$ (cr=2 pr=2 pw=0 time=0 us cost=1 size=11 card=1)
      1       INDEX UNIQUE SCAN I_SUM$_1 (cr=1 pr=1 pw=0 time=0 us cost=0 size=0 card=1)(object id 956)
  72047      FILTER  (cr=1723 pr=4 pw=0 time=553717 us)
  72925       HASH JOIN  (cr=907 pr=0 pw=0 time=1217958 us cost=250 size=79860 card=726)
     92        INDEX FULL SCAN I_USER2 (cr=1 pr=0 pw=0 time=182 us cost=1 size=368 card=92)(object id 47)
  72925        HASH JOIN  (cr=906 pr=0 pw=0 time=681051 us cost=248 size=76956 card=726)
     92         INDEX FULL SCAN I_USER2 (cr=1 pr=0 pw=0 time=182 us cost=1 size=2024 card=92)(object id 47)     72925         TABLE ACCESS FULL OBJ$ (cr=905 pr=0 pw=0 time=199675 us cost=247 size=60984 card=726)
   3775       TABLE ACCESS BY INDEX ROWID IND$ (cr=816 pr=4 pw=0 time=0 us cost=2 size=8 card=1)
   4648        INDEX UNIQUE SCAN I_IND1 (cr=85 pr=4 pw=0 time=0 us cost=1 size=0 card=1)(object id 41)
      0       NESTED LOOPS  (cr=0 pr=0 pw=0 time=0 us cost=2 size=29 card=1)
      0        INDEX FULL SCAN I_USER2 (cr=0 pr=0 pw=0 time=0 us cost=1 size=20 card=1)(object id 47)
      0        INDEX RANGE SCAN I_OBJ4 (cr=0 pr=0 pw=0 time=0 us cost=1 size=9 card=1)(object id 39)
      1      NESTED LOOPS  (cr=2 pr=1 pw=0 time=0 us cost=2 size=7 card=1)
      1       INDEX FULL SCAN I_LINK1 (cr=1 pr=1 pw=0 time=0 us cost=1 size=3 card=1)(object id 137)
      1       INDEX RANGE SCAN I_USER2 (cr=1 pr=0 pw=0 time=0 us cost=1 size=4 card=1)(object id 47)

 Oracle: 11.2.0.1 (Hash Group By)

SELECT OBJECT_TYPE, STATUS, COUNT(*) FROM DBA_OBJECTS
GROUP BY OBJECT_TYPE, STATUS
ORDER BY OBJECT_TYPE, STATUS

call     count       cpu    elapsed       disk      query    current        rows
——- ——  ——– ———- ———- ———- ———-  ———-
Parse        1      0.07       0.09          0          0          0           0
Execute      1      0.00       0.00          0          0          0           0
Fetch        5      0.56       0.60          7       1727          0          49
——- ——  ——– ———- ———- ———- ———-  ———-
total        7      0.63       0.70          7       1727          0          49

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: SYS

Rows     Row Source Operation
——-  —————————————————
     49  SORT ORDER BY (cr=1727 pr=7 pw=0 time=0 us cost=263 size=1084736 card=67796)
     49   HASH GROUP BY (cr=1727 pr=7 pw=0 time=96 us cost=263 size=1084736 card=67796)
  72048    VIEW  DBA_OBJECTS (cr=1727 pr=7 pw=0 time=1286480 us cost=254 size=1084736 card=67796)
  72048     UNION-ALL  (cr=1727 pr=7 pw=0 time=1052935 us)
      0      TABLE ACCESS BY INDEX ROWID SUM$ (cr=2 pr=2 pw=0 time=0 us cost=1 size=11 card=1)
      1       INDEX UNIQUE SCAN I_SUM$_1 (cr=1 pr=1 pw=0 time=0 us cost=0 size=0 card=1)(object id 956)
  72047      FILTER  (cr=1723 pr=4 pw=0 time=547063 us)
  72925       HASH JOIN  (cr=907 pr=0 pw=0 time=1221029 us cost=252 size=7989850 card=72635)
     92        INDEX FULL SCAN I_USER2 (cr=1 pr=0 pw=0 time=182 us cost=1 size=368 card=92)(object id 47)
  72925        HASH JOIN  (cr=906 pr=0 pw=0 time=682076 us cost=250 size=7699310 card=72635)
     92         INDEX FULL SCAN I_USER2 (cr=1 pr=0 pw=0 time=273 us cost=1 size=2024 card=92)(object id 47)  72925         TABLE ACCESS FULL OBJ$ (cr=905 pr=0 pw=0 time=194549 us cost=248 size=6101340 card=72635)
   3775       TABLE ACCESS BY INDEX ROWID IND$ (cr=816 pr=4 pw=0 time=0 us cost=2 size=8 card=1)
   4648        INDEX UNIQUE SCAN I_IND1 (cr=85 pr=4 pw=0 time=0 us cost=1 size=0 card=1)(object id 41)
      0       NESTED LOOPS  (cr=0 pr=0 pw=0 time=0 us cost=2 size=29 card=1)
      0        INDEX FULL SCAN I_USER2 (cr=0 pr=0 pw=0 time=0 us cost=1 size=20 card=1)(object id 47)
      0        INDEX RANGE SCAN I_OBJ4 (cr=0 pr=0 pw=0 time=0 us cost=1 size=9 card=1)(object id 39)
      1      NESTED LOOPS  (cr=2 pr=1 pw=0 time=0 us cost=2 size=7 card=1)
      1       INDEX FULL SCAN I_LINK1 (cr=1 pr=1 pw=0 time=0 us cost=1 size=3 card=1)(object id 137)
      1       INDEX RANGE SCAN I_USER2 (cr=1 pr=0 pw=0 time=0 us cost=1 size=4 card=1)(object id 47)

Conclusão:

Nesse último caso quando as colunas da clausula GROUP BY e ORDER BY são as mesmas o algoritmo SORT GROUP BY mostrou-se um pouco mais eficiente, lembrando que em nossos testes poucas linhas foram ordenadas e que essa diferença aumentaria no caso de uma ordenação maior.

Antes de qualquer migração: Muitos Testes são necessários!!!

Abraços

By José Eduardo Fiamengui Júnior

Publicado em Oracle | Publicar um comentário

Contadores do Perfmon

By José Eduardo Fiamengui Júnior (oradeep)

Objetivo: Mostrar alguns contadores interessantes do Perfmon e algumas diretrizes para métricas de desempenho:

Perfmon (métricas e diretrizes)

Capacity Planning: Perfmon

1-) Contadores para os servidores
com Sistema Operacional Windows

a) CPU e Memória

Métrica Contador Recomendável Descrição
Processor

% Processor Time

< = 80 %

Percentage
of elapsed time the processorspends executing
non-idle threads.
System

Processor Queue Length

<=4

Number
of threads waiting for CPU cycles,where
< 12 per CPU is good/fair, < 8 is better,< 4 is best.
Memory

Memory Pages / sec

Ver descrição

Often
referenced in older documentation.Useful
only in combination with PagesInput/Sec,
%Usage, %Usage Peak. 
Memory

Available MBytes

100 MB Unused

Unused
physical memory (not page file)
Memory

Paging File

% Usage < 70

Amount
of Page File in use, which indicatesthe
server is substituting disk space formemory. 

b) Discos

Métrica Contador Recomendável Descrição
Physical Disk

% Disk Time

<=
50 %
This
counter is deceptive because it makes no accommodation for multiple spindles.Thus,
the more spindles (i.e. physical hard disks) you have, the higher the
percentilevalues
can go. Conversely, if these spindles are shared across LUNs or other
services, youmay
have high numbers on this counter without any correlation to SQL Server
activity.

In short, there are
better ways to find out SQL Server’s I/O performance.

Physical Disk

Avg. Disk Queue Length

2 por disco. Por exemplo, se falamos de um Array de 5 discos essa
métrica teria como ideal 10
The
way in which Windows measures disk queues, combined with the amount of cachethat
storage vendors provide with hard disk controllers, SANs, and hard disks
themselvesmeans
that Windows might perceive that data is written all the way to disk, when in
factthe data is actually
sitting in a hardware-level cache somewhere.
Physical Disk

Avg. Disk Sec/Read

< 8ms A
key measure of disk latency representingthe
average time, in milliseconds, ofeach
read to disk where > 20 is poor, <20 isgood/fair,
<12 is better, <8 is best
Physical Disk

Avg. Disk Sec/Write

< 8ms (non
cached) e < 1ms (cached)
A
key measure of disk latency representingthe
average time, in milliseconds, of eachwrite
to disk, where non-cached writes(
> 20 poor, <20 fair, <12 better, <8 best)

differ
significantly from cached writes

(>
4 poor, <4 fair, <2 better, <1 best ).

For
OLTP databases, the lower this number

the
better, especially for disks holding the

transaction log.

c) Redes

Métrica Contador Recomendável Descrição
Network Interface Total Bytes / sec
(SEND + RECEIVED)
Ver descrição The
number of bytes sent and receivedover
a specific network adapter, includingframing
characters. Be sure to recordthe
throughput of your SQL Server’s

NIC
card(s). Watch for this value possibly

exceeding
the NIC’s specifications,

especially
when conducting large and/

or
multiple backups or copies to network

drives.
A high-speed network and/or a NIC

dedicated
to admin processes often alleviates

this
bottleneck. This counter is a sum

of
“Network Interface\\Bytes Received/

sec”
and “Network Interface\\Bytes Sent/

sec”.
In some situations, you may wish to

determine
both inbound and outbound

network
traffic separately.This counter is

particularly
useful in iSCSI environments

where
it can help to measure disk I/O

when the NIC is dedicated to storage.

 

2-) Para os servidores com database SQL Server

Métrica Contador Recomendável Descrição
Sql Server: Buffer Manager Buffer Cache Hit Ratio No máximo 90%, o ideal é 99% Long
a stalwart counter used by SQL Server DBAs, this counter is no longer very
useful.It
monitors the percentage of data requests answer from the buffer cache since
the lastreboot.
However, other counters are much better for showing current memory pressurethat
this one because it blows the curve. For example, PLE (page life expectancy)
might

suddenly
drop from 2000 to 70, while buffer cache hit ration moves only from 98.2 to

98.1.
Only be concerned by this counter if it’s value is regularly below 90 (for
OLTP) or 80

(for very
large OLAP).

Sql Server: Buffer Manager Page life Expectancy Inferior a 300 s Tells, on
average, how many seconds SQL Serverexpects a
data page to stay in cache. The targeton an OLTP
system should be at least 300 (5min). When
under 300, this may indicate poor

index design
(leading to increased disk I/O

and less
effective use of memory) or, simply, a

potential shortage of memory.

Sql Server: General Statistics User Connections Ver descrição The number of
users currently connectedto the SQL
Server. This counter shouldroughly track
with “Batch Requests/Sec”.They should
generally rise and fall together.

For example,
blocking problems could

be revealed
by rising user connections,

lock waits
and lock wait time coupled

with
declining batch requests/sec.

Sql Server: Database BatchRequests/Secv Ver descrição Number of
batch requests received per second,and is a good
general indicator for the activitylevel of the
SQL Server. This counter is highlydependent on
the hardware and quality of code

running on
the server. The more powerful the

hardware, the
higher this number can be, even

on poorly
coded applications. A value of 1000

batch
requests/sec is easily attainable though a

typical
100Mbs NIC can only handle about 3000

batch
requests/sec.Many other counter thresholds

depend upon
batch requests/sec while, in

some cases, a
low (or high) number does not

point to poor
processing power. You should

frequently
use this counter in combination with

other
counters, such as processor utilization or

user
connections.In version 2000, “Transactions/

sec” was the
counter most often used to measure

overall
activity, while versions 2005 and later use

“Batch
Requests/sec”. Versions 2005 prior to SP2,

measure this
counter differently and may lead to

some
misunderstandings. Read the footnote for

more details.

Sql Server: Database Data File (s) size
Kb
Ver descrição Cumulative
size (KB) of all the data files in thedatabase
including any automatic growth.Monitoring
this counter is useful, for example,for
determining the correct size of tempdb.
Sql Server: Database Percent Log Used < 80% Percentage of
space in the log that is in use.Since all
work in an OLTP database stops untilwrites can
occur to the transaction log, it’s avery good
idea to ensure that the log never fills

completely. Hence, the recommendation
to

keep the log
under 80% full.

Publicado em Uncategorized | Publicar um comentário

Flashback Database

Esse recurso permite recuperar o banco, fazendo que o mesmo
possa ser voltado num ponto específico do tempo. Esse recurso pode ser útil
para situações de corrupção de dados lógicas ou perda de dados feita por algum
usuário. Meio rápido para recuperação de dados.

A estrutura do Flashback Database envolve alguns novos
recursos componentes: Logs de FlashBack Database e RVWR (Processo de segundo
plano).

a)  Logs de Fashback Database: é um arquivo de log com a imagem anterior dos blocos do banco de dados Oracle. Esses logs devem ser criados na área de recuperação de flashback, ou seja, essa área deve ser configurada para esse armazenamento;

b)  RVWR: quando o Flashback Database está ativado, o processo de segundo plano RVWR é iniciado sendo responsável por gravar nos logs os dados do Flashback Database.

OBS: Para utilizar o Flashback Database o banco deve estar em modo ARCHIVELOG e uma área de recuperação deve ser configurada.

Verificando se o database com o flashback ativado:

SQL> select current_scn, flashback_on from v$database ;

CURRENT_SCN FLASHBACK_ON
———– ——————
846839 NO

Como ativar o Flashback
Database:
1-) Shutdown immediate ;

2-) startup mount exclusive ;

3-) alter system set db_flashback_retention_target=2880 scope=both ;

4-) alter system set db_recvery_file_dest_size=1G scope=both;

5-) alter system set db_recovery_file_dest=’c:\flashback\’  scope=both ;
#diretório deve estar criado em C:\

4-) alter database flashback on ;

5-) alter database open ;

OBS: 2880 minutos equivalem a 2 dias

O parâmetro db_flashback_retention_target é apenas um alvo do intervalo de tempo que as informações devem ser armazenadas. Isso dependerá também do tamanho da área de
disco que armazenará os logs do flashback.

V$database: Coluna Flashback_on, que mostra se o recurso está ativado.
V$flashback_database_log: Permite monitorar o RETENTION_TARGET, isso pode ajudar a estimar a quantidade de espaço necessário exigida na área de recuperação.

Colunas importantes:
a)      Flashback_scn: menor SCN permitido

b)      Flashback_size: especifica o tamanho atual em bytes do dados de flashback

c)       Estimated_flashback_size: usa dados de flashback registrados anteriormente a fim de fornecer uma estimativa do espaço em disco necessário na área de recuperação flash

d)      Oldest_flashback_snc e oldest_flashback_time exibem o menor valor aproximado de SCN e o horário até o qual é possível fazer flashback do banco de dados CURRENT_SCN em V$DATABASE;

Exemplo:
select * from v$flashback_database_log ;

V$flashback_database_stat: Manutenção dos dados de logs.

Estima a quantidade total de espaço para recuperações futuras

Exemplo:
SQL> select Begin_time, end_time, flashback_data, dB_data, redo_data,
estimated_flashback_size from v$flashback_database_stat ;

Desvantagens:
Esse recurso não poderá ser utilizado:
a)      Se o arquivo de controle foi restaurado ou recriado

b)      O objeto que você precisa consultar teve sua tablespace excluída

c)       Ocorreu uma recuperação com o comando RESETLOGS

Vamos a prática: 1º parte

SQL> alter session set nls_date_format=’dd-mm-yyyy hh24:mi:ss’ ;

SQL> select sydate from dual ;

SQL> create table hello_world (id number(4), name varchar2(30)) ;

SQL> insert into hello_world values (1, ‘Katia’) ;

SQL> insert into hello_world values(2, ‘Bianca’);

SQL> insert into hello_world values(3, ‘Suelen’);

SQL> insert into hello_world values(4,’Edilene’) ;

SQL> commit ;

2º parte:

SQL> select sysdate from dual ;             # guardar essa data

SQL> drop table hello_world ;

SQL> flashback table “HELLO_WORLD” to before drop ;

3º parte:

SQL> select sysdate from dual ;

SQL> shutdown immediate ;

SQL> startup mount exclusive ;

SQL> flashback database to timestamp to_timestamp(‘dd-mm-yyyy hh24:mi:ss’,
‘DD-MM-YYYY HH24:MI:SS’) ;

SQL> alter database open resetlogs ;

Verificar se existe a tabela HELLO_WORLD

Habilitando a Lixeira

SQL> show parameter recycle

NAME                                             TYPE        VALUE
———————————— ———– —————————-
recyclebin                                        string      on

Esse parâmetro vem habilitado como default.

A lixeira pode ser utilizada quando:

a)       Você criou uma tabela chamada EMPLOYEES no tablespace
b)      Você eliminou a tabela EMPLOYEES
c)       As extensões ocupadas por EMPLOYEES agora são consideradas espaço livre
d)      EMPLOYEES é renomeada e inserida na lixeira

O comando flashback table <table_name> to before drop ;
O espaço (após DROP) não é liberado na tablespace.

Ignorando a Lixeira:

Drop tablespace
<tablespace_name> including contents ;

Os objetos não são colocados na lixeira. Quando você executa o mesmo comando
sem a cláusula INCLUDING CONTENTS, o tablespace precisa estar vazio para a
execução bem sucedida do comando.

Drop user  <username> cascade ;

# O usuário e todos os objetos pertencentes a ele são eliminados não permitindo
recuperação.

Eliminar a tabela com o comando:

DROP TABLE <table_name> purge ;

OBS: A view DBA_TABLES a coluna DROPPED que é definida como YES no caso de tabelas que foram eliminadas.

Exemplo:

1-)  Criar uma tabela

2-) Dropar uma tabela

3-) select * from <tabela> as of timestamp systimestamp – interval ‘5’ minute;

4-) Insert into <tabela> select * from<tabela> as of timestamp systimestamp
-interval ‘5’ minute;

Para expurgar:

Purge recyclebin ou user_recyclebin  (que são sinônimos). ou
Purge dba_recyclebin ;

Publicado em Oracle | Publicar um comentário