Eu tive o mesmo desejo de configurar o pg desta maneira. Para mim, eu queria vários clusters, cada um com seu próprio agendador independente (pgagent). Quando eu desligar um cluster individual, o pgagent irá parar automaticamente, mas quando eu iniciar um cluster, eu quero que o pgagent inicie automaticamente para esse cluster também. Se eu esquecer de iniciar o agendador quando eu iniciar um cluster, estou com problemas.
Eu pesquisei o Google, mas nunca encontrei uma boa solução para executar o PostgreSQL no Upstart. A maioria das soluções iniciou o postmaster explicitamente em vez de usar os comandos pg_wrapper. Com o modo como o Upstart funciona, isso parece perigoso e pode resultar em perda de dados em raras situações.
Assim, eu segui em frente e tentei criar meus próprios scripts Upstart que fariam o trabalho. Descobri que era muito difícil capturar o PID correto do cluster e de sua instância pgagent. Eventualmente, no entanto, percebi que com o PostgreSQL, você não se importa realmente com os PIDs. Você se preocupa com versões e clusters. Depois que percebi, tudo se encaixou e criei os três scripts a seguir:
O primeiro eu chamo pg_versions.conf.
description "PostgreSQL Version Controller"
author "Brian Myers"
start on runlevel [2345]
stop on runlevel [016]
env DEFAULT_VERSIONS="9.3"
pre-start script
if [ -z $VERSIONS ]; then
VERSIONS=$DEFAULT_VERSIONS
fi
for version in $VERSIONS
do
for cluster in $(pg_lsclusters -h | grep $version | cut -d" " -f 2)
do
if [ 'tail -1 /etc/postgresql/$version/$cluster/start.conf' = "auto" ]; then
start pg_cluster version=$version cluster=$cluster
fi
done
done
end script
post-stop script
if [ -z $VERSIONS ]; then
VERSIONS=$DEFAULT_VERSIONS
fi
for version in $VERSIONS
do
for cluster in $(pg_lsclusters -h | grep $version | cut -d" " -f 2)
do
stop pg_cluster version=$version cluster=$cluster
done
done
end script
A seguir está o pg_cluster.conf.
description "PostgreSQL Cluster Controller"
author "Brian Myers"
instance $version-$cluster
pre-start script
if [ 'pg_lsclusters -h | grep $version | grep $cluster | cut -d" " -f 4' = "down" ]; then
pg_ctlcluster $version $cluster start || :
start pg_agent version=$version cluster=$cluster || :
fi
end script
post-stop script
if [ -e "/var/run/postgresql/pgagent-$version-$cluster.pid" ]; then
stop pg_agent version=$version cluster=$cluster
fi
if [ 'pg_lsclusters -h | grep $version | grep $cluster | cut -d" " -f 4' = "online" ]; then
pg_ctlcluster $version $cluster stop
fi
end script
E finalmente pg_agent.conf.
description "PgAgent Controller"
author "Brian Myers"
instance ${version}-${cluster}
setuid postgres
pre-start script
PORT='pg_lsclusters -h | grep $version | grep $cluster | cut -d" " -f 3'
if [ -z 'psql -c "select schema_name FROM information_schema.schemata WHERE schema_name = 'pgagent';" -d postgres -p $PORT | grep pgagent' ]; then
stop ; exit 0
fi
PGAGENTDIR='which pgagent'
PGAGENTOPTIONS="host=/var/run/postgresql dbname=postgres user=postgres port=$PORT"
start-stop-daemon --start --oknodo --name "pga$version$cluster" --exec $PGAGENTDIR -- $PGAGENTOPTIONS
pgrep -f "$PGAGENTDIR.+$PORT" > /var/run/postgresql/pgagent-$version-$cluster.pid
end script
post-stop script
start-stop-daemon --stop --oknodo --pidfile /var/run/postgresql/pgagent-$version-$cluster.pid
if [ -w /var/run/postgresql/pgagent-$version-$cluster.pid ]; then
rm -f /var/run/postgresql/pgagent-$version-$cluster.pid
fi
end script
Se você quiser mais do que apenas a versão 9.3, basta adicionar as versões à linha env DEFAULT_VERSIONS="9.3"
, separadas por espaços.
Com estes, posso:
Inicie todos os clusters que ainda não estão em execução:
sudo initctl start pg_versions
Inicie todos os clusters para uma versão específica que ainda não esteja em execução:
sudo initctl start pg_versions version=9.3
Inicie um cluster específico, pgagent de inicialização automática para esse cluster, mas somente se o cluster estiver pgagent ativado:
sudo initctl start pg_cluster version=9.3 cluster=main
Inicie o pgagent de um cluster se o cluster estiver pgagent ativado:
sudo initctl start pg_agent version=9.3 cluster=main
Altere o início para parar para obter o comportamento inverso. É claro que tudo começa na inicialização e desliga ao parar por meio de pg_ctlcluster
, portanto, não há perda de dados. Eu tive que desabilitar os scripts init.d via bum.
Tenho certeza de que isso pode ser feito de forma ainda melhor. O script pg_agent por exemplo - eu nunca consegui descobrir por que usar script ou exec não poderia capturar o PID correto. Eventualmente eu desisti e gerenciei o arquivo pid, mas ainda é um mistério. Provavelmente foi minhas habilidades de script de shell muito suaves.
Observe também que, se você desligar manualmente os clusters com pg_ctlcluster
, esses trabalhos do Upstart continuarão sendo exibidos, mesmo que as versões / clusters associados não estejam. Não é um grande problema, porque você pode apenas reiniciá-los com pg_ctlcluster
ou initctl
, mas por esse motivo eu sugiro usar initctl
para controlar seus clusters se você implantar esses trabalhos.
De qualquer forma, isso funciona muito bem para mim.