Postgresql - configurando como problema de trabalho do Upstart

1

Eu preciso que o Postgresql seja configurado para iniciar com o sistema Upstart, porque eu uso os Upstarts para iniciar outro aplicativo, o que depende do pgsql estar rodando. Este é o tutorial / script que usei:

link

Quando eu reiniciar o servidor ( shutdown -r now ), o postgresql não está em execução (não visível como um trabalho via comando 'top'). Em seguida, tentei executar apenas o seguinte comando manualmente:

root@server:~# exec su -c "/usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main -c config_file=/etc/postgresql/9.1/main/postgresql.conf" postgres

E minha sessão ssh simplesmente desconsidera não retornar nada. Se eu reconectar e verificar novamente os trabalhos em execução, o pgsql ainda não está em execução. Então eu tentei executar o comando sem 'exec' e aqui está a resposta:

root@server:~# su -c "/usr/lib/postgresql/9.1/bin/postgres -D /var/lib/postgresql/9.1/main -c config_file=/etc/postgresql/9.1/main/postgresql.conf" postgres

2012-12-03 19:31:36 MSK FATAL:  could not create lock file "/var/run/postgresql/.s.PGSQL.5432.lock": No such file or directory

Eu assumo que o problema está relacionado ao próprio postgresql e não ao sistema de upstart. Suponho que o arquivo mencionado deva existir para que possa ser acessado, mas não por algum motivo. Alguém mais se deparou com isso, ou tem uma solução potencial para isso?

    
por U2ros 03.12.2012 / 17:04

2 respostas

2

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.

    
por Brian.D.Myers 02.02.2014 / 04:44
0

Erro significa que o Postgres não pode criar seu arquivo de bloqueio no diretório /var/run/postgresql . O pré-script deve criá-lo e está definindo a propriedade para postgres. Para mim, parece que este script não foi executado. Portanto, verifique a saída de start postgres (como superusuário), existência e permissões ls -l /var/run/postgresql .

FYI: exec é útil em tarefas do Upstart, portanto, a seção script executando um script de shell não deixa um PID adicional por aí. Em uma sessão de shell, faz o seu shell sair quando o programa executado é encerrado.

    
por Tuminoid 07.12.2012 / 07:38