Pular para o conteúdo

Quando o RAC atrapalha

Quando o RAC atrapalha

Nota: um leitor do Blog deixou um comentário em um Post, mas sem querer eu marquei como Spam, e comentário foi recusado.
Como eu recebo cerca de 200 Spams no Blog por dia, vou eliminando eles muito rapidamente, e quando percebi que era um comentário válido, já era tarde demais.
Peço desculpas ao leitor que colocou o comentário (acho que era algo sobre um script de inserção de nomes, mas como eu cliquei muito rápido, não deu tempo de ler), e se for possível, que ele coloque o comentário novamente, que eu responderei com toda a atenção !
E passarei a eliminar os Spams com mais calma daqui em diante…

Bom, vamos ao Post.

Estive em um grande cliente que tinha um sério problema de escalibilidade em sua aplicação. O problema foi detectado durante um Stress Test, o que é louvável, pois geralmente fazem a migração primeiro, e chamam o DBA depois.
Antes de sermos chamados para diagnosticar o gargalo da arquitetura (de 4 camadas, muito complexa), muitas opções foram tentadas pelo cliente, inclusive, como sempre, adicionar mais hardware, e alterar parâmetros do Oracle que poderiam ter alguma relação com o problema.

Como sempre vejo, estas tentativas são apenas isso: tentativas.

Na primeira reunião sobre o Stress Test, me perguntaram que parâmetros eu gostaria de alterar para realizar o teste. Eu expliquei que esta forma de trabalho não nos trará sucesso, não posso dar remédio sem saber a doença. E a melhor forma de diagnosticar um gargalo deles, é acompanhar o teste, e medir onde o tempo é gasto. Onde estiver o tempo, é onde estará o problema.

Oracle Performance Diagnostics & Tuning não é um exercício de tentativa e erro. Não há necessidade disto. O método de diagnóstico de desempenho baseado em tempo é sempre objetivo, claro, infalível. Algumas vezes não é possível corrigir o problema (pode estar em uma aplicação com código fechado), mas sempre é possível diagnosticar.

Durante o Stress Test, medi detalhadamente as WAITs dos SIDs. Assim que o teste iniciou, não tive dúvidas: a aplicação não foi construída para escalar em RAC.

Dezenas de SIDs executavam o bloco PL/SQL abaixo, no mesmo momento, apresentando a mesma Wait.

19:12:15 SQL> SELECT W.SID, W.EVENT, W.WAIT_CLASS, W.SECONDS_IN_WAIT, SQL.SQL_TEXT FROM V$SESSION_WAIT W, V$SESSION S, V$PROCESS P, V$SQLTEXT SQL WHERE W.WAIT_CLASS NOT IN ('Idle', 'Other') AND W.SID = S.SID AND S.PADDR = P.ADDR AND SQL.ADDRESS = S.SQL_ADDRESS AND SQL.HASH_VALUE = S.SQL_HASH_VALUE ORDER BY W.SECONDS_IN_WAIT DESC, W.SID, SQL.PIECE;

SID EVENT WAIT_CLASS SECONDS_IN_WAIT SQL_TEXT
----- -------------------------------------------------- -------------------- --------------- ----------------------------------------------------------------------------------------------------
...
974 gc current request Cluster 1 BEGIN TRANSACTION.INSERT_VALIDATE_TRANSACTION(:1,:2,:3,:4,:5,:6,
974 gc current request Cluster 1 :7,:8,:9,:10,:11,:12,:13,:14,:15,:16,:17,:18,:19,:20,:21,:22,:23
974 gc current request Cluster 1 ,:24,:25,:26,:27,:28,:29,:30,:31,:32,:33,:34,:35,:36,:37,:38,:39
974 gc current request Cluster 1 ,:40,:41) ; END;
...

Um segundo para “gc current request” é muita coisa. Os dois nós do RAC, cada um com várias sessões (provenientes do Application Server), tentavam inserir dados na mesma tabela, criando páginas no mesmo índice, em síntese, tentando usar o mesmo bloco do banco de dados.

Como um bloco só pode pertencer a um nó do RAC de cada vez (de outra forma teríamos corrupção de dados), os nós estavam brigando entre si sobre a propriedade dos mesmos blocos.

Sugeri ao cliente direcionar o Application Server para utilizar apenas um dos nós (utilizando na string de conexão FAILOVER=ON e LOAD_BALANCE=OFF). Claro que todos estranharam essa sugestão: como menos poderia nos dar mais?

O teste com um apenas nó foi feito, e gargalo foi então automagicamente superado. O Application Server passará a utilizar apenas um nó para esta parte da aplicação. O RAC servirá por enquanto apenas como um Data Guard de luxo. Apareceram outros gargalos menores depois, mas este é outro Post…

Quão útil foi este post ?

Clique em uma estrela para classificar o post

nota média 5 / 5. Contagem de votos: 6

Sem votos ! Seja o primeiro a classificar !

9 comentários em “Quando o RAC atrapalha”

  1. Avatar de Fardim

    Bom dia!

    Parabéns pelos artigos!!!!!

    Portilho,
    Qual a melhor forma que a aplição deveria submeter o INSERT com LOAD_BALANCE=ON e não ocorrer o problema de disputa de bloco?

    Obrigado!

  2. Avatar de Ricardo Portilho Proni

    Oi Fardim.
    Este problema poderia ser minimizado com a reconstrução da tabela sem ASSM e com múltiplas FREELISTs, manualmente. ´Quando ao índice, poderia ser criado um índice reverso que também ajudaria. Mas pelo tamanho do ambiente, não sei até que ponto estas sugestões ajudariam, e certamente teriam efeitos colaterais.
    O melhor é particionar a aplicação mesmo (este nó faz INSERT nesta tabela, este faz UPDATE naquelas outras tabelas).

    Abraço !

  3. Avatar de Humberto

    No ambiente que administro, temos 3 tipos de aplicações. 1 Desktop que atende por volta de 1000 sessões; Uma versão web que atende umas 500 sessões e um aplicativo de OLAP que demanda perto de 10 em época de fechamento. Porém este último representa 30% de processamento e a aplicação web também representa pelo menos 20% de processamento. As duas primeiras são OLTP que executam a todo instante procedures CRUD’s e tenho observado bastante waits events referente a “gc current request” e outros gc***.

    Meu ambiente esta configurado com 2 nós na versão 10.2.0.4 em hpux itanium.

    É válido eu apontar as aplicações com funções OLTP para um nó? Teria efeito a aplicaçã com função OLAP não participar do load balance também, embora não demande tantas DML’s?

    Obrigado,

    Humberto.

  4. Avatar de Ricardo Portilho Proni

    Oi Humberto.

    O mais importante não é balancear a aplicação por tipo, mas sim pelos objetos que ela usa, as tabelas e índices mesmo. Não adiantaria colocar um nó para OLTP e outro para OLAP, sendo que faz UPDATE em um tabela, e outro uma leitura massiva.
    E especificamente quanto ao perfil OLTP / OLAP / BATCH, pode ser configurado via DBMS_SERVICES, você pode “avisar” o Service que ele deve tratar o balanceamento entre os nós como o de uma aplicação OLTP, por exemplo.

    Abraço !

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

plugins premium WordPress