segunda-feira, 4 de novembro de 2013

PostgreSQL - pg_repack



    Olá amigo sofredor que mantêm um PostgreSQL 8.x, sim, falemos besteiras, pois afinal não são muitos os que as leem mesmo. 

    Por que tu sofres? Pelo VACUUM FULL inviável? Por índices maltratados e ou inchados? Aqui não falaremos dos inexistentes, pois como cantavam(tempo passado, pois hoje a formação da banda não é mais a mesma) Os Mirins(http://pt.wikipedia.org/wiki/Os_Mirins): "Dos covardes não se fala". 

    Bem, este é o mesmo sofrimento que eu passo. Então há alguns dias o Fabrízio Mello(http://fabriziomello.blogspot.com/) me apresentou o pg_repack(https://github.com/reorg/pg_repack).

    Primeiro, por que ele é importante? 

    Porque o VACUUM ou AUTOVACUUM somente marcam para reuso as túpulas mortas. VACUUM FULL é impraticável no 8.x, é mais rápido exportar e importar um dump do que rodá-lo. CLUSTER gera exclusive lock na tabela, o que é impossível também em uma base 24x7. 

    REINDEX em tabelas grandes não é viável também, ou se você vai para uma recriação de índice concorrente te falta o maldito índice da PK.  

    O que, sua base não é 24x7? Pare de ler este post, isto não serve pra ti. Continua com CLUSTER sem problemas. 

    Como funciona o pg_repack: Na prática ele recria a tabela e seus índices com o mínimo de lock possível. Durante o processo ele cria uma tabela temporária e armazena os dados da tabela atual nela(sim, você precisa de pelo menos 120% do espaço da tabela livre em espaço em disco), recria seus índices e durante este processo armazena os logs das alterações(via trigger) sofridas em uma outra tabela para aplicar posteriormente ao finalizar o processo. Feito isto remove a tabela antiga e renomeia a nova.

    Qual o comando para isso:

/usr/pgsql-8.4/bin/pg_repack --order-by=identificador_unico --table=public.teste‏ --echo -U postgres -d producao 

    O que significam os parâmetros? 

--order-by=identificador_unico : Para recriar a tabela ordenando-a pela PK
--table=public.teste‏ : A tabela em si
--echo : Para que você veja a coisa acontecer 
-U postgres : Sério mesmo que tu não sabe? 
-d producao : database alvo

   Quais cuidados devo ter?  

    O único ponto onde não testei o rollback é quando o mesmo está enviando as transações durante o processo para um local temporário via trigger, então tenha bastante cuidado ao automatizar uma rotina desta, pois a falha da rotina PODE(talvez, pois não foi testado) continuar enviando as DMLs para o limbo e não para a tabela em si.