Recuperando Repositório GIT Corrompido: error: bad packed object CRC for

Ontem me deparei com um problema de corrupção em um repositório git, e depois de apanhar um pouco, consegui resolver o problema. Estou documentando o passo a passo para referencia futura.

A seguinte mensagem de erro aparecia ao tentar clonar um repositório bare (com outros comandos também ocorria, como ”git gc”):

Counting objects: 119213, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (22370/22370), done.
error: bad packed object CRC for ca94d22d6c8cee73c2901b396183f5c8cebdb37a
error: bad packed object CRC for ca94d22d6c8cee73c2901b396183f5c8cebdb37a
error: failed to read object ca94d22d6c8cee73c2901b396183f5c8cebdb37a at offset 116202510 from /repositorio/objects/pack/pack-87aa0cf7ddb97fe5482cbd8173d1ee07e403729f.pack
fatal: object ca94d22d6c8cee73c2901b396183f5c8cebdb37a is corrupted
error: failed to run repack

A interpretação final foi que o objeto com SHA1 ca94d22d6c8ce…, que neste repositório já havia sido empacotado no arquivo pack-87aa0cf7ddb97fe5482cb…, estava corrompido. (Este empacotamento é feito por um ”git gc”, ”git repack”, ou automaticamente durante o merge, se habilitado, para melhorar o desempenho do repositório)

Algo muito bom num repositório distribuído é que cada clone funciona como um backup. Cada cópia de trabalho contem todo o histórico e todos os objetos existentes no repositório clonado desde a última atualização (fetch). De forma que, se este mesmo objeto (blob) existe em algum repositório clonado e não está corrompido, pode ser utilizado para substituir o arquivo corrompido no repositório com problema.

O objeto pode ser encontrado e extraído em algum repositório cópia com o seguinte comando:

git show -p ca94d22d6c8cee73c2901b396183f5c8cebdb37a > blob.bin

Este comando gera o arquivo blob.bin, que contém o conteúdo do objeto ca94d22d6c8ce. O mesmo deve ser copiado (ssh, scp) para o computador/repositório corrompido, ex:

scp blob.bin gitadmin@ip.com:~/

No repositório corrompido, executar:

git hash-object -w ~/blob.bin

Isso irá re-escrever o blob no repositório e um ”git gc” deve mostrar que o problema foi solucionado.

Pode ser necessário um passo adicional no repositório corrompido: desempacotar o pack onde o blob está contido e removê-lo da pasta packs. O nome e caminho do arquivo foi exibido na mensagem original pack-87aa0cf7ddb97fe5482cbd8173d1ee07e403729f.pack:

git unpack-objects /repositorio/objects/pack/pack-87aa0cf7ddb97fe5482cbd8173d1ee07e403729f.pack
mv /repositorio/objects/pack/pack-87aa0cf7ddb97fe5482cbd8173d1ee07e403729f.* ~/
git hash-object -w ~/blob.bin

Esta solução pode ainda ser aplicada para blob”s faltantes, mensagens exibidas por ”git fsck” similares a:

error: ca94d22d6c8cee73c2901b396183f5c8cebdb37a: object corrupt or missing
missing blob ca94d22d6c8cee73c2901b396183f5c8cebdb37a

Afinal, para que serve Desvio Padrão?

Recentemente nós (eu e mais 3389 pessoas, aproximadamente devido aos faltantes) fizemos a prova do POSCOMP 2011. Hoje foi o dia da divulgação do resultado oficial para cada participante no site da COPS.

A média de acerto foi de 24 questões das 69 possíveis (apenas 34,78%), com desvio padrão de 7,1 (uma questão foi anulada e dois gabaritos foram alterados: 18 e 35). Com certeza uma prova super difícil se comparada com muitas outras.

Talvez você nem notou, mas “peraí”! Tem um 7,1 no parágrafo anterior, chamado de desvio padrão. Afinal de contas, você sabe para que este número pode ser utilizado? Até poucas horas eu nunca havia ficado curioso o suficiente para entendê-lo. Sabia que a partir dele é possível saber quantas pessoas acertaram o mesmo número de questões que você? Continue lendo!

A definição do desvio padrão conforme Wikipedia, na minha opnião, não ajuda muito. Definição bem formal, texto pra quem gosta de matemática mesmo, desde a infância! Mas o artigo: O que é Desvio Padrão, seção Na prática, o que isso significa?, do site Investpedia, veio bem a calhar para meu entendimento prático.

Aprendi (acho! se estiver errado me corrija por favor) que apenas com a média e desvio padrão, considerando uma distribuição normal, é possível encontrar algumas probabilidades bem interessantes, como:

  • Qual a probabilidade de alguém ter acertado apenas 01 (uma) questão na prova?
  • Qual a probabilidade de alguém ter acertado todas as 69 questões da prova?
  • Quantas pessoas acertaram 30 questões?

Mãos a obra. Só tenho três informações: Quantidade de candidatos (3390), Média de acertos (24) e Desvio padrão (7,1).

Usando a função =NORMDIST() do Open Office/Excel posso encontrar a probabilidade de acerto para cada quantidade de questões. Veja só:

Acertos Fórmula Resultado Pessoas (Resultado x 3390)
10 =NORMDIST(ACERTOS;MÉDIA;DESVIO;0) 0,80419% 27,26
20 =NORMDIST(ACERTOS;MÉDIA;DESVIO;0) 4,79435% 162,53

Probabilidade de Acertos
O gráfico ao lado foi construído a partir desta tabela completa. Perceba que a maior parte dos acertos estão próximos da média. Na verdade, entre (media – desvio padrão: 16,9) e (média + desvio padrão: 31,1). Para ser exato, de acordo com a regra 68-95-98, ou regra dos três sigmas 68,26% ou 2314 pessoas (parte vermelha).

Ainda de acordo com esta regra, 921 pessoas acertaram menos que 16,9 ou mais que 31,1 (Parte azul no gráfico.).

E vai afunilando: 145 pessoas menos que 9,8 ou mais que 38,2 (Parte verde no gráfico.).

E o espanto do POSCOMP 2011: Somente 09 pessoas acertaram menos que 2,7 ou mais que 45,3 questões! 45 questões são somente 65% da prova, ou seja, menos de 9 pessoas acima de 6,5!

Agora quero entender melhor como aplicar isso na análise de relatórios de sistemas ERP’s (vendas, financeiro, contabilidade, etc) e o que se enquadra na distribuição normal. Alguém tem algum exemplo prático de alguma análise? Agradeço muito se deixar um comentário abaixo!

POSCOMP 2011 – Erros nas questões?

Ontem fiz a prova do POSCOMP à tarde. Pelos comentários do twitter, dá para perceber o nível da danada (http://twitter.com/#!/search/poscomp). Fiz outro POSCOMP em 2007 e continuei desde então na academia, fiz meu mestrado e, mesmo assim, desta vez, achei ainda mais difícil a prova. Principalmente as questões de matemática e as de processamento de imagem (que não é muito minha praia).

Mas conferindo o gabarito ontem, me deparei com algumas questões que aparentemente estão incorretas, e estou colocando recurso no site:

Link da Prova
Link do Gabarito

  • GrafoQuestão 18: Caixeiro Viajante. No grafo dado, um vendedor pode sim, sair de uma cidade par (4), passar em todas as cidades e voltar a seu destino (caixeiro viajante), atingindo seu objetivo. Exemplo: saindo de 4, 3, 2, 1, 5, 6, 9, 7, 8, 10, 4. É também possível encontrar caminho saindo de cidade ímpar (3), exemplo: 3, 2, 1, 5, 4, 10, 7, 8, 6, 9, 3. Portanto, isso invalida as afirmativas III e IV que dizem que o vendedor não cumprirá seu propósito com êxito se sair de uma cidade par/impar. O gabarito aponta resposta correta na letra C, que por sua vez afirma que III e IV estão corretas, o que de acordo com os caminhos possíveis demonstrados acima está incorreto.
  • Questão 35, sobre tipos de linguagens de programação. Prolog não é uma linguagem funcional: “Prolog, was is after all a simple and logical language.” conforme em http://pauillac.inria.fr/deransar/prolog/overview.html. Pascal é uma linguagem imperativa/procedural e não Lógica conforme apontado pelo gabarito (Questão 35, Letra A). A resposta adequada da questão parece ser letra D.
  • Questão 43: O programa exibido na prova, questão 43, não é um programa válido. Ele apresenta as palavras end while após o fechamento de uma chave, palavras inválidas para a posição. Uma tentativa de compilar o programa através do compilador gnu g++ falha com o seguinte erro:
    teste.cpp: In function ‘int main’:
    teste.cpp:23: error: ‘end’ was not declared in this scope
    teste.cpp:23: error: expected before ‘while’
    

    O fato de não ser um programa válido impossibilita o entendimento do código e, na minha opnião, uma possível escolha de resposta.

    Há também um “peguinha” na questão. Observe que depois do primeiro for, apesar de não existir uma chave, indicando que todo o if e else é um bloco comum, este é o comportamento padrão. O bloco if/else que vem depois do for é considerado como apenas uma linha e portanto, executa várias vezes gerando uma lista encadeada.

    ...
    N *A, *B, *C;
    int n;
    cin >> n;
    for (int i=0; i<n; i++)
    { // aqui
    	if (!i) {
    		...
    	}
    	else {
    		...
    	}
    } // aqui
    A = C;
    while (A) {
    	cout << A->A << "/" << A->B << " ";
    	A = A->L;
    }
    
  • Questão 61: Veja comentário abaixo, @Carlos Raoni

Encontrou algum erro nas considerações acima? Ou em outra questão? Deixe seu comentário!

Links about High Availability and NoSQL

I’m reading many links about High Availability, Elastic Systems and NoSQL alternatives. It’s all about alternatives for scaling a system where a RDBMS can’t fill it needs.

We are putting them below, with some messages and images:

NoSQL storage
NoSQL storage

NOSQL Patterns – How we can build a distributed database

This article describes the principal NoSQL alternatives and how to split a table/dataset by key an put them into many servers. It also present how map reduce occurs in the cluster nodes with detailed diagrams.

RoadMap to SaaS
RoadMap to SaaS

RoadMap to SaaS

How to convert a standard web application in to a SaaS with Facade class and RESTFul services, moving processes to different JVM’s, cache tiers and much more…

Observers: Making ZooKeeper Scale Even Further
Observers: Making ZooKeeper Scale Even Further

Observers: Making ZooKeeper Scale Even Further

Maybe you don’t know about Zookeeper: yet. But you can be interested in what you can do to scale servers that depends on distributed communication and synchronization. That is a big trouble: How much more computers you put in the cluster, more messages need to be send to coordinate the distributed lock between the computers. The throughput obviously decreases. That is not true for this guy’s using followers and observers!

Ativando DRI no OpenChrome para P4M900

Muitas placas compartilham os mesmos recursos ou são evoluções de outras mantendo o conjunto de recursos da anterior ou ainda o modo de compatibilidade. A placa gráfica VIA P4M900 é um caso destes. Ela é encontrada em computadores mais baratos, principalmente alguns modelos de notebooks da Itautec.

O driver AGP/DRM do kernel não reconhece esta placa, por um mero detalhe: ele não tem o pci_id da mesma na listagem de placas suportadas e por isso o DRI não é ativado por padrão.

Consegui ativar o DRI seguindo os passos abaixo e então resolvi compartilhar. Isso não ativa o modo 3D da placa, já que o próprio OpenChrome ainda não tem suporte a 3D. Apenas o DRI é ativado.

O kernel que estou utilizando é o 2.6.29. O driver openchrome instalado no X foi obtido diretamente do repositório do projeto e compilado. Mas acredito que funcione com versões já existentes nas distribuições.

A placa que tenho é listada pelo comando lspci da seguinte forma:

# lspci|grep VGA
01:00.0 VGA compatible controller: VIA Technologies, Inc. CN896/VN896/P4M900 [Chrome 9 HC] (rev 01)

Para conseguir ativar o DRI é necessário um Kernel com os fontes, possivelmente já compilado. É necessário alterar o arquivo /usr/src/linux/include/drm/drm_pciids.h, incluindo no mesmo o id 0x1106, 0x3371. Localize o texto da primeira e terçeira linhas abaixo. A segunda linha deve ser inserida.

        {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, 
        {0x1106, 0x3371, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, 
        {0, 0, 0}

Entre na configuração do kernel (make menuconfig) e ative os módulos listados a seguir:

Device Drivers  --->
 Graphics support  --->
    <M> /dev/agpgart (AGP Support)  --->
      <M> VIA chipset support
    <M> Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)
      <M> Via unichrome video cards

Compile e instale o kernel e os módulos. Após reiniciar o sistema você verá os seguintes módulos na lista de lsmod. Aparecerá também o arquivo /dev/dri/cards0.

# lsmod
Module                  Size  Used by
...
via                    40160  1
drm                   139712  2 via
via_agp                 7868  1
agpgart                29196  2 drm,via_agp
...

Executando o X e rodando glxinfo, pode-se confirmar que o DRI foi ativado:

$ glxinfo |grep direct
direct rendering: Yes

Não é a maior maravilha para uma placa gráfica, mas melhorou muito a exibição de vídeos. Antes de ativar o DRI o glxgears exibia apenas 80-90 FPS e depois:

$ glxgears
774 frames in 5.0 seconds = 154.666 FPS
797 frames in 5.0 seconds = 159.263 FPS
795 frames in 5.0 seconds = 158.824 FPS
786 frames in 5.0 seconds = 157.173 FPS

DBX4 – Resultados Parciais de Otimização com Paralelismo

Hoje em dia é super comum e barato comprar computadores com dois/quatro núcleos. Cada dia que passa estão mais acessíveis. Mas as aplicações desenvolvidas para estes processadores continuam sendo feitas sequencialmente (“mono-thread”).

Já olhou o Gerenciador de Tarefas e viu sua aplicação patinando nos 50% em uma máquina com dois núcleos? Isso só muda quando duas aplicações estão usando processador ao mesmo tempo, ou ainda, quando uma aplicação possui várias threads simultâneas para resolver um algoritmo.

Pensando nisso, a um bom tempo venho trabalhando em algumas idéias de otimização no driver DBX4. Apesar de o Delphi 2010 agora já vir com driver para Firebird, pretendo colocar esta otimização também nos demais drivers que fiz e disponibilizar para meus clientes de Postgres e Oracle.

A primeira idéia consiste em ter um buffer circular, mais ou menos uma espécie de pipelining. Uma thread busca os dados do banco e a outra repassa estes dados para o framework DBX. Desta forma, enquanto o framework DBX aloca memória e copia os valores dos campos, o driver vai requisitando a frente os dados do banco de dados.

A segunda idéia é um cache de statements. O Firebird ainda não tem um cache de statements preparados como os demais bancos (Oracle por exemplo). E o framework DBX não aproveita os statements criados. A cada registro de inserção/update, um novo statement é preparado e executado.

Os resultados parciais desta segunda idéia são animadores. Veja só o gráfico que compara o driver para Firebird e o TBODBXFB. No eixo y está o tempo em milisegundos e no eixo x a quantidade de registros inseridos em cada teste.

Gráfico Comparativo driver FIREBIRD X TBODBXFB

O teste consiste em inserir 1000, 5000, 10000, 50000 e 100000 registros numa tabela do banco. Para isolar qualquer interferência entre um e outro driver, o banco é criado no momento do início de cada teste. Também é utilizado o servidor classic do Firebird, para evitar qualquer tipo de cache entre as conexões. Os testes foram executados em uma máquina local. Firebird e Aplicação juntos.

Os tempos em milisegundos estão na tabela abaixo:

Registros inseridos TBODBXFB FIREBIRD D2010
1000 1279 2028
5000 6586 11158
10000 12212 20068
50000 64095 102144
100000 127065 202174

Caso deseje fazer um teste, o instalador do driver está no link abaixo. Por enquanto só pode ser instalado no Delphi 2010:

Driver TboDbxFb para Delphi 2010

Em breve darei mais detalhes e o código do teste. Também efetuarei testes com o banco em outro computador, já que este é o ambiente mais comum de utilização. Também exibirei outros testes a respeito do pipeline de registros em um artigo. Aguarde!

A Cabeça de Steve Jobs, de Quem Não Vive no Mundo Mac

Acabo de ler o livro A Cabeça de Steve Jobs e para não perder os mais interessantes achados no livro estou aqui registrando-os. Primeiro, o que não gostei.

Não gostei muito da organização do livro. A tentativa do autor, Leander Kahney, de dividir em capítulos por tema resultou em uma certa bagunça. Sabe aquele tipo de escrita que tem muito: “Daqui a pouco falaremos mais disso”? Quase que o único capítulo que segue seu título é o último, o oitavo: “Controle Total – A obra toda”. Aliás, o melhor dos capítulos na minha opnião. O mais esclarecedor do porquê das decisões do Steve.

Ilustrações! Faltou. Durante a leitura senti extrema falta de figuras. É como se o livro fosse escrito somente para quem acompanhou toda a trajetória dos Macs. Pra quem sabe que o Mac tinha o botão de desligar na parte de trás. Para quem acompanhou todas as propagandas “Pense Diferente (Think Different)”. Às vezes tive que recorrer ao YouTube e a figuras na web.

E por falar das propagandas, não parecem tão boas assim. Claro, tem muito a ver com a cultura em que estou inserido. Mas na minha opnião existem propagandas infinitamente melhores aqui no Brasil. Essa parte foi a que mais achei fanatismo dos “Mac-maníacos” juntamente com o ovacionismo nas Macworld”s quando Steve diz: “E tem mais…”.

Inventividade? Nada! Steve, de acordo com o livro, é um “escolhedor”. O que ele faz de melhor é escolher e rejeitar as melhores e piores idéias dos seus colaboradores, para logo depois achá-las uma ótima idéia, com a mínima ou sequer nenhuma alteração. O grande detalhe está no processo de simplificação. Steve rejeitou o nome iPod antes de aceitá-lo.

Steve também “rouba” idéias, como foi o caso da GUI que copiou da Xerox. Não estou condenando. O livro te aconselha a fazer o mesmo! A Xerox não saberia o que fazer com aquilo na época. Ela vendia máquinas de copiar.

Além de escolhedor, é um caçador de talentos. Sempre contrata e mantém os melhores a sua volta. Essa é uma cultura que grande parte dos brasileiros empreendedores não possuem. Talvez seja essa história do jeitinho brasileiro, sempre tentando tapar buraco. Não é possível ser o melhor sem os melhores, nisso eu acredito.

Para manter estes talentos na Apple ele distribui opções de compra de ações, por valores baixos. Quando o funcionário resolve comprar ou vender as ações elas valem mais do que eles pagaram por elas. Isso mantém qualquer um motivado, e inventivo. Não tenho notícias dessa cultura na área de TI aqui no Brasil, mesmo que seja na forma de PLR.

Steve também é um aficcionado por perfeição. Não há como negar que iPod e iPhone são perfeitos demais para a maioria dos usuários. O acabamento é muito bem feito. Duvida? Então vejamos. Responda a seguinte pergunta: “Quantas vezes comprou um produto e abriu a caixa observando cada efeito desde a luminosidade, efeitos, o porquê das fontes na embalagem, dobras das abas até, enfim, visualizar o produto?” É, isso mesmo, até a embalagem do equipamento é pensada neste nível de detalhes. Veja a cerimônia desta “unboxing” neste vídeo (como é chamado a abertura da embalagem). O mais interessante é que ao chegar ao iPhone, ele coloca-o de lado. Algum brasileiro faz isso?

Aliás, tudo que roda o mundo Mac parece ter uma certa diferença. Só de curiosidade, passe em uma banca de revista e veja a capa da Mac+ número 38. Acredite, esta foto aqui ao lado não tem nada a ver com olhá-la em suas mãos.

Confesso que discordei de grande parte do livro até ler o último capítulo. Nele, muita coisa fez sentido para um usuário de Linux e Windows. Há uma explicação interessante dos modelos vertical e horizontal de distribuição de equipamentos. Steve, desde que fundou a Apple, segue o modelo vertical.

No modelo vertical a distribuição contempla o conjunto: hardware, software e serviços, ou seja, a solução completa. O iPod por exemplo não é somente o aparelho. É o conjunto: aparelho, software e loja iTunes. E isso vai contra o que aconteceu nos últimos 30 anos. Buscou-se uma comoditização/generalização do hardware, e algumas empresas focaram em hardware (Intel, AMD), outras em software (Microsoft) e outros ainda em serviços para as plataformas.

Ser o dono de tudo facilita muito a distribuição e reduz drasticamente a quantidade de erros de integração. A Microsoft demorou mais copiou isso, com o Zune e o XBox. E aparentemente o mundo está girando a favor da Apple neste sentido. O autor se refere a isso como se Steve estivesse à frente do seu tempo, cerca de trinta anos. Não estou certo disso.

Mas isto está virando resumo do livro! Vou deixar a idéia solta, para sobrar vontade de ler o livro! Há muito mais do que o escrito aqui! Hummm, nem falei da obsessão pelo segredo até o lançamento, o formato das lojas de varejo, …