Mostrando postagens com marcador Oracle. Mostrar todas as postagens
Mostrando postagens com marcador Oracle. Mostrar todas as postagens

segunda-feira, 26 de abril de 2010

Algumas Diferenças entre o Oracle e o MySQL

Nas últimas semanas venho trabalhando com um banco de dados MySQL que possui algumas tabelas com um volume considerável de dados para a realidade do MySQL, na minha opinião.

São três tabelas que juntas hoje correspondem a aproximadamente 50GB de dados (somando a elas seus respectivos índices) e são acessadas de uma única vez a partir de uma junção. Além disso essa junção é feita a partir das chaves primárias das tabelas e a tabela principal da consulta também é filtrada por um índice, ou seja, podemos assumir quepelo menos alguns cuidados foram tomados na construção da consulta.

Tudo corria bem nesse ambiente até que a quantidade de linhas dessas tabelas chegou na ordem de dezenas e centenas de milhões e foi ai que após alguns ajustes de parâmetros de memória para o storage engine em questão (MyISAM, key_buffer_cache, net_buffer_length, max_allowed_packet, myisam_use_mmap, etc.), muitos explains e muitos show profiles comecei a notar que diferentemente do que eu estava acostumado com o modo do Oracle trabalhar (hash joins, full table scans, etc. para esse perfil de consultas) o MySQL optava pelo velho "nested loop", mas por que?

Consultas e mais consultas em foruns me mostravam que existia um certo "dito popular" que esse seria o limite do MySQL, apesar de ficar claro para mim que não passava de um mito, mais um deles alias, serviu de constatação que realmente o MySQL era mais "recomendado" para o perfil de transações de aplicações web, ou seja, curtas e rápidas.

Além dessa última constatação usei esse fato para motivar um teste comparativo de performance entre os SGBDs que estou mais acostumado a trabalhar, Oracle e MySQL. A idéia foi bem simples, vamos fazer o MySQL imitar o Oracle e o Oracle imitar o MySQL e o resultado mais fatídico ainda: Uma lástima!

Inicialmente apostei que o Oracle trabalharia com Full Table Scans e realizaria o Join utilizando o algoritmo de Hash, com base nessa aposta e a utilização de hints tentei forçar esse comportamento no MySQL resultado: O MySQL não possui algoritmo de Join baseado em Hash na tentativa de forçar outros algoritmos que trabalhassem melhor com o acesso Full da tabela não obtive nenhum resultado satisfatório, na verdade os resultados foram bem piores do que otimizador tinha obtido com seu plano de acesso original.

Chegou a hora então de importarmos os dados no Oracle e ver se a aposta foi certa. Utilizando alguns recursos triviais do MySQL como o Storage Engine CSV e o SQL*Loader do Oracle rapidamente consegui importar os dados do MySQL/MyISAM para o Oracle.

Inicialmente notei que cerca de 25% a mais de espaço foi necessário para comportar a mesma quantidade de dados (ou seja, perspectiva de mais I/O e de mais uso de memória). Uma vez carregado gerei o plano de acesso da consulta e pela primeira vez não obtive surpresa, Full Table Scans e Hash Join, resultado melhor performance que o MySQL, porém nada muito significativo em um primeiro momento, ou seja, não justificava o custo da migração. Os testes com o Oracle utilizando os algoritmos propostos pelo MySQL também não foram interessantes em termos de resultado.

Resultados a parte e considerando que não tive muito a preocupação de isolar as variáveis nesse "benchmark" (hardwares diferentes e o fato de posteriormente nos testes com a utilização de particionamento consegui equilibrar bastante essa diferença de performance) o principal aprendizado que ficou foi o seguinte: Cada SGBD conhece bem seus limites, seja em relação a algoritmos ou em relação a adaptatividade ao hardware disponível e tentar fazer com que um SGBD se comporte como se estivesse influenciado pelo otimizador de outro SGBD não é certeza de sucesso, mesmo que no outro SGBD os resultados sejam tentadores.

Cada SGBD possui seu perfil de aplicação que se comporta melhor com eles, cada um deles também possui um custo (ou nenhum custo) de licenciamento ou suporte, e cada um deles irá exigir mais ou menos trabalho de um DBA para se adaptar as necessidades das aplicações, mas em termos de performance de consultas individuais, seja envolvendo grande volume de dados ou poucas linhas, ainda não encontrei nenhuma bala de prata!





domingo, 22 de março de 2009

Eliminando Enqueue no Oracle

Modelo de dados construidos por desenvolvedores, aplicações que não foram devidamente testadas, bancos que cresceram fora do planejado e uma série de outras causas podem resultar no famoso pedido de socorro (nada técnico) "O banco está travado"!

Vamos tentar desmistificar um pouco do que acontece nesses momentos de "tensão" dentro do banco de dados. O principal ponto nesse tema é o mecanismo de "lock" do banco de dados Oracle. Para permitir que múltiplos usuários acessem e manipulem as linhas das tabelas dentro de um esquema o Oracle possui um mecanismo para garantir a integridade e consistência dos dados. o lock. Caso queiram entender melhor os detalhes segue um link da documentação do produto: http://download.oracle.com/docs/cd/B19306_01/server.102/b14220/consist.htm#CNCPT221.

Dependendo do tipo de "lock" que um comando submetido ao banco de dados o Oracle poderá sempre que necessário utilizar um estrutura de memória para garantir o bom funcionamento do banco, essa estrutura de memória é chamada de Enqueue (http://download.oracle.com/docs/cd/B19306_01/server.102/b14237/enqueues.htm).

Reunimos agora todos os ingredientes necessários para chegarmos onde vocês esperam, códigos. Quando o "banco está travado" o primeiro candidato a causa do "problema" é algum objeto estar com um lock que impede que outra sessão utilize o recurso desejado, temos então um enqueue. Para identificar se existe um lock ou um enqueue podemos utilizar a seguinte consulta:

SQL> select a.username ||'@'||a.machine || ' session id = ' ||a.sid || ' esta bloqueando '
|| b.username ||'@'||b.machine || 'session id = '||b.sid
from v$lock c,
v$session a,
v$lock d,
v$session b
where a.sid=c.sid
and b.sid=d.sid
and c.block=1
and d.request > 0
and c.id1 = d.id1
and d.id2 = d.id2;

Existem inúmeras consultas para identificar um lock e possivelmente um enqueue, sinta-se à vontade para utilizar a mais conveniente para você, algumas delas já apontam qual tabela, qual linha e até qual bloco estão envolvidos no lock, mas meu objetivo aqui é como você evita (ou antecipa) um deadlock.

Um deadlock ocorre quando uma dependência ciclica ocorre envolvendo as estruturas de lock e enqueue. Após um determinado tempo o banco de dados elimina uma das sessões para que a outra consiga prosseguir com sua transação e o banco de dados possa retomar ao seu curso normal, porém esse tempo pode não ser interessante para você, ou ainda, você pode querer optar por qual das sessões você quer eliminar (de repente aquela procedure que alguem disparou no momento errado).

Para eliminar a sessão que está causando o enqueue no seu banco, primeiro a identifique, por exemplo, a partir da consulta acima descrita, depois execute os seguintes comandos:

SQL> select sid, serial#
from v$session
where sid = 999;

-- substitua 999 pelo sid que você identificou como responsável pelo enqueue.

Passo 1) Seja sutil

SQL> ALTER SYSTEM KILL SESSION 'sid_number, serial_number';

-- substitua o sid_number e o serial_number pelos valores obtidos na primeira consulta

Caso após essa tentativa a sessão em questão ficar com o status KILLED você pode aguardar o banco fazer a parte dele ou antecipar alguns passos. Resumindo a sessão está "agonizando" e você quer "acabar com o sofrimento dela".

SQL> select sid, status
from v$session
where sid=999;

Verifique se o status da sessão está KILLED, caso esteja prossiga com os próximos passos, caso não existam linhas para o SID em questão, a sessão já passou dessa para uma melhor.

Passo 2) Últimas palavras

Para "acabar com o sofrimento" da sessão identifique qual o processo do sistema operacional é responsável por aquela sessão (cuidado se você utiliza dispatchers):

SQL> select spid
from v$process
where addr=(select paddr from v$session where sid=999);

Uma vez que você identificou o processo do sistema operacional vá para a shell do linux ou unix como root e:

kill -9 99999

Onde 99999 é o valor retornado para o SPID da consulta anterior. (Verifique antes se o processo que você está executando kill é um processo do oracle, com padrão oracleSID, onde SID é o nome da sua instância).

Passo 3) Sumindo com o corpo.

Talvez o kill -9 não seja suficiente para você eliminar de vez essa sessão, para essas sessões que costumo chamar de sessões "Mcloud" você ainda tem um último artificio:

SQL> ALTER SYSTEM DISCONNECT SESSION 'sid_number,serial_number' IMMEDIATE;

Bom amigo se após esse passo sua sessão continua como KILLED, só o tempo ou um shutdown no seu banco para ela ir embora de vez.

Vou ficando por aqui e sei que passei por cima (muito rapidamente) de vários conceitos, portando deixem seus comentários que vou respondendo aos poucos.

Abraços,
Caio Spadafora.

terça-feira, 10 de março de 2009

Oracle Open World - Primeiro Dia - 10/03/2009

Prezados colegas, agora são 23:40 da noite e tentarei em um último esforço de me manter com os olhos abertos contar o que presenciei no primeiro dia de evento do Oracle Open World 2009 - LA. Foram disponibilizadas algumas fotos do pavilhão de exposições e das sessões com palestrantes, que por sinal foram muito boas (assim que conseguir o material apresentado tentarei comentar sobre o que nos foi apresentado).

Para quem já esteve presente em algum dos Oracle Open Worlds (essa é a terceira edição aqui no Brasil) não tivemos nenhuma novidade em relação ao formato do evento, ou seja, demo grounds, stands de expositores, sessões com a alta cúpula da Oracle e seus parceiros e stands mais técnicos com vários palestrantes tanto da Oracle como de outras empresas de TI.

Falando mais especificamente sobre o dia de hoje, começamos ouvindo ninguem mais ninguem menos que Safra Catz, ou melhor dizendo, a presidente mundial da Oracle, que salientou a estratégia da empresa sobre consolidar o fornecimento de software e serviços com uma única empresa. Seguindo a manhã ouvimos mais sobre o posicionamento da Oracle ouvindo o responsável por telecomunicações da Oracle, Shaskar Golti (somente o primeiro de muitos indianos que com certeza conhecerei no evento) que também contou com a participação de João Cox, presidente da Claro, sobre o ainda potencial mercado de telecomunicações no Brasil.

Para finalizar os keynotes do dia contamos com uma palestra do Gerente Geral da América Latina da IBM, Rogério Oliveira, apresentando o novo conceito da IBM (que por sinal achei muito bom) que é o Smarter Planet, apresentando a estratégia e alguns casos de sucesso de onde foram e podem ser aplicados os avanças tecnológicos para melhorar a saúde e bem estar do planeta. Exemplos de sucesso como aproveitamento energético e questões urbanas como o trânsito na cidade foram usados como exemplos já implantados, vale muito a pena ir atrás para quem ainda não viu essa nova proposta da IBM.

Sessões Técnicas)

Desde o final da manhã até o fim do evento praticamente só ouvi as sessões técnicas, especificamente no track de Banco de Dados (para quem não sabe essa era uma pequena parte do evento, a Oracle já faz alguns anos que investe pesado em aquisições e reposicionamento da marca para atender todo o "stack" de soluções corporativas para diferentes mercados). As palestras que assisti foram:
  1. Lidando com a Virtualização: Como o Oracle Enterprise Manager Pode Acabar com Seus Pesadelos sobre Gerenciamento.
  2. Um Guia sobre Atualizações de Banco de Dados.
  3. SQL Performance Analyzer: Eliminação de Conjectura de SQL desempenho.
  4. Anatomia de Roubo de Dados: Como Ocorrem e como Proteger-se Contra eles.
  5. Oracle Advanced Compression: Jogue Fora Metade dos Seus Discos e Execute seu Banco de Dados Mais Rápido.
As palestras foram muito interessantes apesar do cansaço cada uma tinha duração de aproximadamente 45 minutos, e sem desmerecer nenhum palestrante conversei pessoalmente com dois deles que foram de extrema importância para mim: Ashish Ray e Paul Needham, cada um deles na sua área de atuação me esclareceram alguns conceitos interessantes sobre Advanced Compression dentro do Data Guard e sobre dúvidas de implementação do Defence-in-Depth (respectivamente). Tive o privilégio de conseguir o e-mail desses "papas" da Oracle e pretendo em breve encher a caixa-postal deles com dúvidas.

Para quem quiser saber detalhes de todas as sessões que aconteceram e ainda vão acontecer o link é:

Sessões do Oracle Open World LA 2009)

http://www21.cplan.com/cc223/content_catalog.jsp?ilc=223-1&ilg=portuguese&isort_sessions=&isort_demos=&isort_exhibitors=&is=yes&ip=%3C%2Fipresentations%3E&isort_sessions_type=&isort_exhibitors_type=&isort_demos_type=&search_sessions=yes&icriteria1=+&icriteria2=+&icriteria5=+&icriteria8=&icriteria9=+&icriteria6=&icriteria3=+&icriteria7=


Bom vou ficando por aqui, ainda tenho mais 2 dias de eventos e muita novidade deve vir por ai... Não tive nem tempo de comentar sobre os Demo Grounds que eu visitei e sobre os vídeos que fiz, mas prometo que amanhã tento passar mais detalhes de como foi o dia no Oracle Open World. (Visitem o evento, para quem quiser visitar os stands e demo grounds a entrada é R$ 80,00 e vale a pena).

Abraços e até!!!