quinta-feira, 4 de dezembro de 2014

MySQL - SQL thread is not running?



Imagine o seguinte cenário, você tem um MySQL master e um slave configurado com replicação assíncrona. Por alguma razão você descobre através da consulta de status do slave que o SQL thread parou de funcionar, mas o IO thread continua em execução buscando logs do master. 

COMO IDENTIFICAR A CAUSA DO PROBLEMA? 

        - Verifique o log de erro do MySQL, lá constará o código de erro gerado durante o processo de replicação, seja ela por row ou statement, e este código já lhe ajudará a buscar soluções na documentação. 

        - No mesmo log você poderá verificar qual a posição e binlog do master em que ocorreu o erro, isso será muito útil no futuro. 

        Consideraremos aqui neste exemplo que o erro foi causado por um SQL que violou uma CONSTRAINT de PK ou FK.

        O ERRO É DE VIOLAÇÃO E AGORA? 

 1 - Primeiramente utilizando o mysqlbinlog acesse o log binário do master indicado no erro do MySQL do slave e com o -j informe a posição;
2 - Ao identificar o STATEMENT ou ROW que foi executado/alterada você poderá acessar o MySQL master e comparar os dados da tabela alvo com a do slave;
3 - Aqui é certo que você identificará diferenças de integridade entre as tabelas, pois lembre que o slave está atrasado com relação ao master;
4 - Pule uma posição no log do master no slave: 

CHANGE MASTER TO MASTER_LOG_FILE = '$master_log_name' MASTER_LOG_POS = $master_log_pos+1; 

Viu agora o porquê da importância da posição do log lido no master? Onde $master_log_name e $master_log_pos podem ser obtidos ao consultar o status do slave

 5 - Feito isto ative o slave novamente:
     
START SLAVE;

Se nenhum outro erro ocorreu após o slave se atualizar em relação ao master(veja no status do slave) então é hora de verificar como ficaram os dados da tabela que apresentou o erro. COMO? 

        Se seu slave não tem delay setado e o fluxo de alterações e inserções da tabela não é constante podes realizar a validação por MD5SUM. COMO? 
mysql > \P md5sum 
mysql > select * from tabela_alvo; (não faça isso em tabelas gigantes!)
O resultado no master e slave devem ser o mesmo valor de md5. Para normalizar o client basta executar \P. 

Bom, se ainda assim tem diferenças na tabela alvo, considere ajustar os dados dela via dump com a function slave parada, ou ressincronizar o slave. 







quarta-feira, 13 de agosto de 2014

PostgreSQL - Acompanhando SQL via log

Ei você! Sim, você que precisa acompanhar DML/DDL/DCL via log, mas não sabe como, ai vai uma dica para acompanhar o mesmo via log em tempo real(depois que já executou, evidente): 


1 - logado por SSH no banco alvo execute :

watch -n 10 'tail -n 1500 /var/log/pgsql.log | grep -i -A 1 "MEU SQL"'

Em resumo de 10 em 10 segundos você ficará visualizando os SQLs, e caso seja um UPDATE/DELETE que os parâmetros sejam vistos somente na próxima linha será apresentado. 

Requisitos: 

1 - Cluster PGSQL com log configurado para o syslog/rsyslog;
2 - Log ser o pgsql.log no '/var/log';
3 - Ser Linux; 
4 - Log configurado para logar tudo ou pelo menos SQL por duration. 

quinta-feira, 8 de maio de 2014

Oracle - ORA-01017 usando JDBC

ERRO:

root@appserver:/opt/resources/oracletest/jdbctool-1.0/bin# CLASSPATH=/opt/resources/oracletest/ojdbc5.jar ./jdbctool -u teste -p meuteste jdbc:oracle:thin:@10.0.1.16:1521/DB_MYAPP

Unable to connect to database: java.sql.SQLException: ORA-01017: invalid username/password; logon denied


SINTOMA: Ao integrar uma aplicação em um servidor de aplicação Java onde a comunicação seja estabelecida via JDBC ainda que usuário e senha estejam corretos e você consiga conectar através do SQLPlus o erro gerado no servidor de aplicação será o item mencionado no ERRO.


SOLUÇÃO: Existem duas formas de solucionar este erro, uma é atualizar seu JDBC para o ojdbc mais atual, outra é executar o comando abaixo como sys ou system na base alvo:

ALTER SYSTEM SET SEC_CASE_SENSITIVE_LOGON = FALSE; 


JUSTIFICATIVA: Por padrão o  Oracle11g ou superior vem configurado para senhas case_sensitive e o  ojdbc5(baseado em client 10g) ou inferior enviam as senhas em maiúsculo, logo o erro e a solução de ou atualizar o ojdbc6(baseado em client 11g) ou a desativação do recurso.

SUGESTÃO: Atualizar o driver JDBC.

quarta-feira, 26 de fevereiro de 2014

PostgreSQL - Problemas com o pg_repack



   Este post é complemento do post referente ao pg_repack(http://helkmut.blogspot.com.br/2013/11/postgresql-pgrepack.html), onde cito um ponto crítico do repack onde não é viável o rollback. 
   
   Um exemplo é caso sua base tenha um crash durante o repack de uma tabela ou por razão desconhecida você tem a conexão do próprio repack terminada. O que acontece nesta situação com sua tabela? 
   
   A tabela original possuirá uma trigger enviando todos DMLs para uma tabela temporária de log no schema 'repack' da mesma base de dados, a mesma existirá, pois o processo não foi concluído e a tabela antiga de origem não foi excluída. Assim como existirão os dados da tabela antiga(com outro nome) no schema 'repack' quando o repack foi iniciado. 
   
   Então o que fazer? 
   
   O primeiro de tudo é isolar a base de dados, fazer uma análise de dados rápida da tabela do schema de origem e a do schema alvo(repack), caso tenhas diferença entre elas significa que podes somente aplicar a tabela de log(DMLs commitados do início do processo até a falha), remover a trigger da tabela de origem, realizar backup das 3 tabelas envolvidas e liberar a base. 
   
   Não sendo possível isolar a base de dados para a correção deves remover a trigger da tabela de origem deixando que novos DMLs sejam computados na mesma e não mais na tabela de log e avaliar um método de aplicação dos dados da tabela de log  na tabela de origem. 
   
   Para um novo repack deverás remover as duas tabelas do schema repack da base de dados alvo. 
   


sábado, 11 de janeiro de 2014

AWS - Reduzindo custos aumentando performance com S3


   Avançamos um pouco mais no uso das soluções disponíveis pela Amazon. Já tínhamos experiência no uso de AutoScaling, IOPS, entre outros, mas o alvo desta vez foi quebrar paradigmas, então o que melhor do que evoluir na performance reduzindo custos! Parece impossível, mas não é com o S3 + Glacier.

   Trabalhando com volumes EBS conseguimos reduzir custos anteriormente e aumentar performance ao modificar o nível de RAID de 10 para 0 aumentando os IOPS dos discos, mas isso é assunto para um post posterior.

   Na busca por uma melhoria continua, onde priorizamos alta disponibilidade e confiabilidade, backup é um assunto sério. Porem o custo é um fator relevante ao priorizarmos alta disponibilidade e o dimensionamento é vital para uma política efetiva.

   Para tal, avaliando as soluções disponíveis de armazenamento da AWS(Amazon Web Services), realizamos a seguinte análise de custo:

S3 - $0.095 por GB
EBS standard - $0.10 por GB

   Ok, até ai, não temos grande vantagem, mas no S3 existe uma opção de 'lifecycle' dos arquivos/diretórios onde você pode enviá-los após um tempo para o Glacier, o qual é um serviço também de armazenamento, porém assíncrono e de baixo custo($0.010 por GB).

   Agora vamos calcular a vantagem, considerando o preço do dólar comercial a R$2.35, quando utilizamos 1TB de armazenamento durante um ano:

EBS: $0.10 * 1024 = $102.40 * 12 = $1228.80 * 2.35 = R$2.887,68
S3: $0.095 * 1024 = $97,28 * 12 = $1167.36 * 2.35 = R$2.743,30
Glacier: $0.010 * 1024 = $10,24 * 12 = $122,88 *2.35 = R$288,77

   Em resumo, mesmo utilizando o S3 é vantajoso, Glacier mais ainda. É recomendado o uso do S3 para dados estáticos ou até mesmo armazenamento de rotina de backups por necessidade de APIs para comunicar com os buckets. Idem para o Glacier com a seguinte consideração, dados no Glacier não serão disponibilizados em tempo real, pode haver um “delay”, resumindo seu uso se aplica apenas a backups.

   Exemplificando, podemos ter a seguinte política de backup:

   Após 45 dias os dados enviados ao S3 serão movidos para o Glacier e após 90 dias são excluídos sem necessidade de interação, isto graças a configuração de 'lifecycle' utilizada no bucket, ou em um determinado diretório do bucket, pois em um bucket podemos aplicar políticas de distintas de 'lifecycle'.

   Mas onde ganho performance no uso do S3? Ganha-se performance ao reduzir o custo com o S3+Glacier e utilizá-los onde realmente vale a pena.

   Dimensionamento de recurso é tudo.

   Mais informações em: http://aws.amazon.com/pt/s3/

   Agradecimento ao meu colega Guilherme Elias(https://twitter.com/guilhermelias) que me ajudou muito no post e também na implementação da solução.