Quão difícil pode ser isso?

Por bastante tempo eu pensei que os erros de estimativa de desenvolvimento de software fossem um sintoma de inexperiência. Eu não conseguia acertar nenhuma, mas achava sinceramente que estudando meus erros eu fosse ter estimativas cada vez melhores...

Hoje eu já cometi vários erros de estimativa e bem, já posso concluir que eu estava errado. Por exemplo, durante meu mestrado, pouco depois de sair da faculdade, eu desenvolvi uma biblioteca de correspondência estéreo de imagens. Lá pela terceira semana de desenvolvimento, eu fui falar com meu orientador, que me sugeriu reescrever a biblioteca em C++ (ela estava escrita em C). Eu saí de lá pronto a ignorar essa sugestão, afinal, eu já estava escrevendo em C a mais de duas semanas, quanto tempo eu ia gastar para passar tudo para C++? Bom, por causa desta sugestão me ocorreu que eu poderia usar o namespace extra que eu ganharia colocando meu código dentro de uma classe para fazer com que ele seja recursivo e muito mais fácil de entender. Eu certamente ia perder um pouco de performance, mas com este namespace extra eu podia minimizar esta perda e ainda ter um código organizado. Isso iria economizar mais do que algumas semanas de tempo no futuro, então comecei a traduzir o programa. Tempo total para a tradução? Em torno de 1 hora e meia! Depois foram mais umas 4 horas medindo a performance do novo programa, que diminuiu em 8%, mas o computador fez essa parte sozinho. Pouco depois eu encontrei um bug na função mais central do programa... Ela era uma função pequena, menos de 30 linhas, representava uma função matemática bem conhecida; não pode ser que eu demorasse muito para corrigir. Demorei uma semana.

Bom, isso foi naquela época. Eu não tinha muita experiência. Agora, é claro, as coisas são bem diferentes. Por exemplo, estou fazendo este site, o comemcasa, onde eu quero relacionar restaurantes que entregam em domicílio por local de entrega. É simples, não tenha dúvida, mas quão simples? Quando decidi fazer o site, eu comecei a olhar formas de colocar ele no ar, mas sem muita pressa. Afinal não pretendia passar uma parcela grande do meu tempo fazendo ele, então ia demorar até ter alguma coisa pronta. Mais ainda porque resolvi fazer o site em uma linguagem em que nunca tinha feito nada grande (Python), com um framework de web que eu nem sabia que existia (Django). Esperava demorar uns três meses antes de colocar qualquer coisa no ar. Realmente, demorei... três dias. Finalmente, eu comecei a criar a toda a estrutura necessária para cadastrar restaurantes. Comecei em um dia em que eu tinha um compromisso em que teria que passar duas horas sem fazer nada; então levei o laptop. Não pretendia fazer tudo nestas duas horas, mas esperava fazer a maior parte do trabalho. Isso foi em outubro, estou escrevendo este post porque agora, em fevereiro, eu acabei! Ainda não está no ar, estou fazendo QA ainda :)

Mas então a experiência é inútil? Não, claro que não. A experiência não faz com que os erros desapareçam, mas reduz eles tendendo a um certo mínimo que aparentemente é maior do que zero. Mas esse não parece ser o seu efeito mais importante; se você além do tempo tentar também estimar a confiabilidade da estimativa de tempo, esta segunda estimativa melhora muito mais rápido do que a primeira com a experiência. Bom, essa frase ficou um pouco complicada, então vamos aos exemplos:

Nos dois primeiros erros acima (de quando eu estava no mestrado), eu nem pensei no caso quando fiz minhas estimativas, mas se alguém ouvisse estas estimativas e me perguntasse "Você tem certeza deste tempo?" eu provavelmente diria que sim, eu tinha certeza. Ou seja, eu estimava que o tempo que eu encontrei fosse confiável, quando ele não era. Minha estimativa da confiabilidade estava errada. Nos dois últimos erros (do comemcasa) se alguém me fizesse a mesma pergunta (e neste caso eu me fiz esta pergunta) as respostas seriam respectivamente "Eu não faço a menor idéia" e "Não estou muito confiante". Ou seja, eu estimava que o tempo pudesse estar errado, e estava mesmo.

Postgresql pg_xlog muito grande!

Parece que todo mundo já postou perguntas em todos os lugares sobre este problema, mas ninguém tem uma resposta que valha a pena.

O caso é o seguinte o Postgres guarda o write ahead log (WAL) em um diretório chamado pg_xlog. Normalmente ele guarda um arquivo de log até pouco tempo depois de gravar as mudanças que estão nele no banco de dados, e renomeia ele para usar depois. Tudo funciona muito bem, e o diretório fica com um tamanho constante e razoavelmente pequeno.

Daí, como você gosta de segurança, você cria uma rotina de backup. A melhor forma de fazer backups do Postgres é arquivando os WALs e copiando de tempos em tempos o conteúdo do banco de dados. Então você muda o arquivo postgres.config para arquivar os wals, e cria um script que faz o arquivamento, além deste você cria um script que copia /var/lib/postgres para um lugar seguro. Por exemplo, neste servidor sempre que o Postgres acaba de usar um WAL ele roda um script que copia o arquivo para um computador na minha casa, e todas as noites o cron roda um script que sincroniza o banco de dados.

Tudo funciona muito bem, e o pg_xlog continua com um tamanho estável. Daí o marceneiro me liga e diz que a mesa o os armários do quarto onde ficam os computadores ficaram prontos, e ele está vindo montar. Meus computadores passam uma semana desligados, e o pg_xlog explode! Como o Postgres não consegue arquivar os WALs, ele não apaga nenhum. (Para ajudar, eu estava rodando uns updates beeem grandes nesta semana...) O espaço em disco acaba, e o administrador do banco fica desesperado...

Como na internet não tem muita coisa que funcione, vai aqui como resolver o problema. Se o seu servidor ainda estiver rodando, tente primeiro fazer o arquivamento voltar a funcionar. Assim que ele voltar o tamanho do diretório vai começar a diminuir. Se você não puder fazer o arquivamento funcionar (seu marceneiro é mais enrolado do que o meu, por exemplo), você pode "trapacear"; coloque /bin/true como o script de arquivamento. Você vai perder os WALs, mais não vai perder o servidor.

Agora, se o servidor não estiver mais funcionando você vai ter que fazer umas coisas bem "feias". No diretório pg_xlog tem um diretório chamado archive_status. Lá dentro tem uns arquivos com o nome dos WALs, acabando em ".ready". Se existir o arquivo XXXX.ready, isso significa que você pode apagar o arquivo XXXX no pg_xlog, então:

for i in $(ls archive_status); do echo "$i" | sed -e 's/.ready$//' | xargs rm; done

Pronto, você já tem espaço para rodar o Postgres de novo. Mude o script de arquivamento para /bin/true e ative o Postgres por algum tempo. Quando ele achar que arquivou todos os WALs, mude o script para o seu script normal, e reinicie o Postgres. Verifique se o arquivamento está funcionando normalmente.

Se o arquivamento não se comportar direito, faça um dump completo do seu banco de dados, porque a coisa vai ser feia mesmo. Encerre o Postgres pelo pg_ctl (verifique se ele encerrou sem erro, NÃO USE SIGINT ou SIGKILL), mova todos os arquivos do pg_xlog e archive_status para outro lugar, e rode pg_resetxlog. Inicie o Postgres, ele deve funcionar normalmente. Se não funcionar, bem você agora tem um backup...

Ei, um blog.

Parece que eu não vou conseguir escrever práticamente nada nesse site se as idéias não sairem de um blog. Pois então, estou mudando a estrutura do site, ele começa no meu blog e, se tiver mais conteúdos longos, vou linkar para ele de posts. Hoje só tem Free Software and Code Reuse.
Inscreva-se em marcosdumay.com RSS