TL;DR: O postmaster imparável e inutilizável está sendo gerado quando o Postgres é iniciado logo após a restauração de seu diretório de dados de um backup básico do WAL. Por quê?
Contexto:
Rodamos o postgresql 8.4, no CentOS 6, usando os pacotes PGDG. Temos um script para uso em ambientes de teste do desenvolvedor que restaura um backup noturno do diretório de dados do nosso servidor de produção (criado entre chamadas para pg_start_backup
e pg_stop_backup
). O script descompacta o arquivo e usa restore_command
para reaplicar quaisquer WALs que foram gerados durante o tempo em que o backup foi feito na produção.
Geralmente funciona bem e restaura centenas de vezes mais rápido do que uma restauração baseada em SQL de um arquivopg_dump
'ed.
Problema:
Às vezes, depois de descompactar o diretório de dados, o script inicia o postgres executando /etc/init.d/postgresql start
(que é um link simbólico para /etc/init.d/postgresql-8.4
. Isso o torna um script init previsível para quando eventualmente atualizarmos para 9.*). Ele relata "OK", como em: iniciou corretamente. Então os WALs não são restaurados; ele trava indefinidamente esperando um recovery.done
arquivo aparecer.
O que eu tentei:
Quando corri /etc/init.d/postgresql status
durante o travamento indefinido, o script init relata dead but pid file exists
.
Então eu corri ps -ef | grep post
. Estranhamente, o processo postmaster e os arquivadores, etc., estavam em execução. Todos os parâmetros de invocação estavam corretos (datadir correto etc etc).
Quando executei psql
, ele detectou um postmaster em execução e um banco de dados inicializado postgres
, mas não detectou o banco de dados principal - aquele que queremos restaurar por meio do script WAL.
Em seguida, verifiquei as permissões no diretório de dados e tudo parecia OK.
A execução /etc/init.d/postgresql stop
relatou "OK" e matou os processos do arquivador/observador, mas o postmaster continuou em execução.
A mesma coisa aconteceu quando tentei killall -r '*.postmaster*.'
.
A única coisa que funcionou para retomar a restauração WAL travada foi um killall -s 3 -r '.*postmaster.*'
(Sinal 3 é SIGQUIT) e, em seguida, um arquivo /etc/init.d/postgresql start
.
Eu verifiquei pg_startup.log
e os arquivos diários pg_log
durante o estado incontrolável, e tudo parecia bem. pg_startup.log
registrou um início bem-sucedido como a última entrada.
Causas Possíveis:
Algumas coisas (acho que menores) não são padrão em nossa configuração.
Nosso script init é vinculado simbolicamente, como eu disse antes, a um script independente de versão em
/etc/init.d/postgresql
. Isso aponta para onde queremos. Atualmente aponta para/etc/init.d/postgresql-8.4
.Nosso
postgresql.conf
arquivo reside/etc/
(com um proprietário e grupo do usuário postmaster) e possui um link simbólico para o diretório de dados. Nosso script de restauração do WAL garante que o link simbólico seja recriado antes de tentar iniciar o postgres.Recentemente, atualizamos nossa infraestrutura do Postgresql 8.4.11 para 8.4.12. Estamos testando a nova versão para estabilidade. Nossos servidores de produção estão executando 8.4.11. No entanto, estamos extraindo dados deles por meio de
pg_dump
, depurando-os e, em seguida, 'empacotando-os' para restauração WAL em outro lugar (em 8.4.12), portanto, não estamos restaurando WALs em versões incompatíveis do Postgres.
Pergunta:
Por que está fazendo isso? Uma das possíveis causas listadas abaixo é possivelmente a culpada?
Em geral, se você estiver tendo problemas desse tipo, pode ser melhor incluí-los na lista de bugs do pgsql. As pessoas lá podem ajudar a descobrir quais informações coletar para ajudar a determinar qual é o escopo desse comportamento inadequado e ajudar a corrigi-lo para você.
Também 8.4.11 a 8.4.12 wal restore deve funcionar bem.
Se isso está acontecendo apenas ocasionalmente, não acho que suas explicações cheguem lá. Parece algo que realmente poderia usar a solução de problemas adicional por pessoas que podem determinar se uma correção de código é necessária.