Como executar tarefas recorrentes no Postgresql sem uma ferramenta externa do tipo cron?

41

Gostaria de chamar um procedimento armazenado regularmente. No Oracle, eu criaria um trabalho para isso. Eu descobri que o Postgresql pode simular isso usando uma ferramenta externa (cron etc) e o PgAgent.

Você conhece uma alternativa "interna" que não envolva a ferramenta externa?

  • Quero evitar preocupações de segurança com a senha armazenada na linha de comando do pgAgent.
  • Quero evitar qualquer configuração adicional do sistema para ocultar a senha ( ~/.pgpass).

Postgresql 8.3
Linux RedHat 64bit

Stephan
fonte
Você pode adicionar por que não pode usar o pgAgent ou o crontab? especificamente o que recursos estão faltando ..
WrinkleFree
@Rohan Eu atualizei a minha pergunta
Stephan
Pós parece ter sido copiado e colado para stackoverflow.com/q/16958625/398670
Craig Ringer

Respostas:

30

Mesmo se você estivesse executando o PostgreSQL 10 em breve a ser lançado (no momento da redação) ou o PostgreSQL 9.6 atual, não uma versão antiga como a 8.3, ainda não existe um agendador de tarefas embutido.

Algo como trabalhos PgAgent ou cron externos é necessário, não há solução conveniente.

Espera-se que o recurso de trabalhadores em segundo plano introduzido na 9.3 permita que uma ferramenta como o PgAgent seja movida para o núcleo do PostgreSQL em uma versão posterior, mas ainda não foi feita. Mesmo na versão 9.3, você ainda precisa executar o cron ou o pgagent.

Algumas pessoas estão trabalhando em agendadores baseados em trabalhadores em segundo plano, e há alguns patches chegando que devem fornecer recursos para ajudá-lo. Mas, a partir do PostgreSQL 10, ainda não há boa qualidade, agendador amplamente adotado e a maioria das pessoas usa o agendador de tarefas cron / ms / etc.

Por favor, dê uma olhada na política de versão também; você está executando uma versão obsoleta e sem suporte.

Craig Ringer
fonte
Please take a look at the version policy, atualizar o Postgresql não é uma opção.
Stephan
2
@ Alex Você terá que atualizar em algum momento, e isso só vai ficar mais difícil. O lançamento de 8,3 pontos, a propósito? Quantas correções significativas estão faltando? Ou você está pelo menos em 8.3.23? Dito isso, como expliquei, o recurso que você deseja nem existe no próximo lançamento da versão 9.3, embora algumas das bases para permitir sua adição tenham sido adicionadas.
Craig Ringer
Eu vou ter uma conversa com meu chefe :)
Stephan
1
@Alex Boa ideia :-). Na atualização mínima para 8.3.23 com urgência, comece a trabalhar nos planos de atualização para uma versão mais recente. Ele não vai resolver esta questão, mas é uma muito boa idéia para salvar a dor futuro. O número de clientes que eu apoio que estão enfrentando problemas que nunca teriam se continuassem atualizados é incrível. Não lançamos novas versões apenas por diversão ;-). Leia as notas de versão de cada versão .0 para obter orientação sobre as coisas com as quais você pode precisar lidar e leia o manual sobre atualização. Seus únicos pontos de dor prováveis ​​são standard_conforming_stringse bytea_output.
Craig Ringer
Craig, o que você acha do pg_cron?
Me #
21

No PostgreSQL 9.5, você pode usar a extensão pg_cron , que é carregada como uma biblioteca compartilhada no PostgreSQL.

Após a configuração, a criação de um trabalho é bastante simples:

SELECT cron.schedule('30 3 * * 6', $$DELETE FROM events WHERE event_time < now() - interval '1 week'$$);

Isso executará o comando delete de acordo com a programação cron especificada. Você também pode usar @rebootpara agendar um trabalho quando o servidor reiniciar, e o pg_cron começará automaticamente a execução dos trabalhos se você promover uma espera em espera.

Em vez de usar .pgpass, você pode fornecer acesso ao host local para o usuário cron em pg_hba.conf.

Marco Slot
fonte
-1

Você realmente, realmente não quer fazer isso. O Postgres não é um sistema operacional, é um servidor de banco de dados. Mesmo que o banco de dados suporte a execução de tarefas agendadas, não é uma boa ideia abusar do banco de dados dessa maneira.

Se sua preocupação é que você não deseja configurar a senha e os materiais, isso é fácil de resolver. Configure uma conexão de soquete Unix local usando a autenticação trust ou ident ; execute seu cronjob como esse usuário.

Em sua configuração pronta para uso, geralmente o postgres configura o usuário do sistema postgrespara executar o servidor db, e esse usuário do sistema já está pré-configurado para poder se conectar ao servidor local usando autenticação confiável ao se conectar via soquete unix local. Você pode executar seu cronjob como usuário do sistema postgres, conectar-se ao soquete local e, em seguida, alternar a função se não desejar que seu procedimento armazenado seja executado com privilégio de superusuário.

Na configuração padrão, você pode fazer isso:

$ sudo -u postgres crontab -e

No editor, adicione à entrada crontab da seguinte maneira:

0    0    *     *    * bash /path/to/run_stored_procedure.sh

e no seu arquivo /path/to/run_stored_procedure.sh, basta usar o psql para chamar o procedimento de armazenamento

#!/usr/bin/env bash
psql my_db_name <<END
    SET ROLE limited_user;
    SELECT my_stored_proc();
    SELECT 1 FROM my_stored_proc();
END
Lie Ryan
fonte
1
'não é realmente uma boa ideia abusar do banco de dados assim' Por que você acha que é abuso? Os diferentes RDBMSs convencionais tendem a ter abordagens semelhantes, e não acho tão terrível. Além disso, se você não tiver acesso ao sistema operacional, ficará sem o crontab.
dezso 10/01