Wie führe ich wiederkehrende Aufgaben unter Postgresql ohne ein externes Cron-ähnliches Tool aus?

41

Ich möchte regelmäßig eine gespeicherte Prozedur aufrufen. Auf Oracle würde ich dafür einen Job anlegen. Ich habe festgestellt, dass Postgresql dies gut imitieren kann, indem es ein externes Tool (cron usw.) und PgAgent verwendet.

Kennen Sie eine "interne" Alternative, bei der das externe Tool nicht zum Einsatz kommt?

  • Ich möchte Sicherheitsbedenken in Bezug auf das in der Befehlszeile des pgAgent gespeicherte Kennwort vermeiden.
  • Ich möchte jegliche zusätzliche Systemkonfiguration zum Ausblenden des Passworts vermeiden ( ~/.pgpass).

Postgresql 8.3
Linux RedHat 64bit

Stephan
quelle
Können Sie hinzufügen, warum Sie pgAgent oder crontab nicht verwenden können? speziell, welche Funktionen fehlen ..
WrinkleFree
@ Rohan Ich habe meine Frage aktualisiert
Stephan
Der Beitrag wurde anscheinend kopiert und in stackoverflow.com/q/16958625/398670
Craig Ringer,

Antworten:

30

Selbst wenn Sie die (zum Zeitpunkt des Schreibens) bevorstehende Veröffentlichung von PostgreSQL 10 oder die aktuelle Veröffentlichung von PostgreSQL 9.6 ausgeführt haben, die keine frühere Veröffentlichung wie 8.3 ist, gibt es noch keinen integrierten Aufgabenplaner.

So etwas wie PgAgent oder externe Cron-Jobs sind erforderlich. Es gibt keine praktische Umgehung.

Die in 9.3 eingeführte Hintergrund-Worker-Funktion sollte hoffentlich ermöglichen, dass ein Tool wie PgAgent in einer späteren Version in den PostgreSQL-Kern verschoben wird, dies ist jedoch noch nicht geschehen. Sogar auf 9.3 müssen Sie noch cron oder pgagent ausführen.

Ein paar Leute arbeiten an Schedulern, die auf Hintergrundarbeitern basieren, und es gibt einige Patches, die Funktionen bereitstellen sollten, die dabei helfen. Ab PostgreSQL 10 gibt es jedoch immer noch keine gute, weit verbreitete Scheduler-Qualität, und die meisten Leute verwenden cron / ms task scheduler / etc.

Bitte beachten Sie auch die Versionsrichtlinien . Sie führen eine veraltete und nicht unterstützte Version aus.

Craig Ringer
quelle
Please take a look at the version policy, ein Upgrade von Postgresql ist keine Option.
Stephan
2
@Alex Irgendwann muss ein Upgrade durchgeführt werden, und es wird nur noch schwieriger. Was für eine 8,3-Punkte-Veröffentlichung übrigens? Wie viele wichtige Fehlerkorrekturen fehlen Ihnen? Oder bist du zumindest am 8.3.23? Wie ich bereits erklärt habe, gibt es die von Ihnen gewünschte Funktion auch in der kommenden Version 9.3 nicht, obwohl einige Grundlagen für die Hinzufügung hinzugefügt wurden.
Craig Ringer
Ich werde mit meinem Chef sprechen :)
Stephan
1
@ Alex Gute Idee :-). Beginnen Sie bei einem dringenden Update auf mindestens 8.3.23 mit der Arbeit an Upgradeplänen für eine neuere Version. Es wird diese Frage nicht lösen, aber es ist eine sehr gute Idee, zukünftige Schmerzen zu retten. Die Anzahl der Kunden, die ich unterstütze und die Probleme haben, die sie niemals gehabt hätten, wenn sie nur auf dem Laufenden geblieben wären, ist erstaunlich. Wir veröffentlichen keine neuen Versionen nur für Kicks ;-). Lesen Sie die Versionshinweise für jede .0-Version, um Anleitungen zu erhalten, wie Sie eventuell vorgehen müssen, und lesen Sie das Handbuch zum Aktualisieren. Ihre einzigen wahrscheinlichen Schmerzpunkte sind standard_conforming_stringsund bytea_output.
Craig Ringer
Craig, was denkst du über pg_cron?
Mehmet
21

Ab PostgreSQL 9.5 können Sie die Erweiterung pg_cron verwenden , die als gemeinsam genutzte Bibliothek in PostgreSQL geladen wird.

Nach dem Einrichten ist das Erstellen eines Jobs ziemlich einfach:

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

Dadurch wird der Löschbefehl gemäß dem angegebenen Cron-Zeitplan ausgeführt. Sie können mit auch @rebooteinen Job planen, wenn der Server neu gestartet wird, und pg_cron startet automatisch die Ausführung von Jobs, wenn Sie einen Hot-Standby-Modus aktivieren.

Anstatt .pgpass zu verwenden, können Sie in pg_hba.conf localhost-Zugriff für den cron-Benutzer bereitstellen.

Marco Slot
quelle
-1

Das willst du wirklich, wirklich nicht. Postgres ist kein Betriebssystem, sondern ein Datenbankserver. Selbst wenn die Datenbank das Ausführen von geplanten Aufgaben unterstützt, ist es keine gute Idee, die Datenbank auf diese Weise zu missbrauchen.

Wenn Sie kein Passwort und keine weiteren Informationen einrichten möchten, ist dies leicht zu beheben. Richten Sie stattdessen eine lokale Unix-Socket-Verbindung mit Trust- oder Ident-Authentifizierung ein und führen Sie Ihren Cronjob als dieser Benutzer aus.

In der Standardkonfiguration richtet postgres den Systembenutzer normalerweise so ein, dass er den Datenbankserver ausführt. postgresDieser Systembenutzer ist normalerweise bereits vorkonfiguriert, sodass er bei der Verbindung über einen lokalen Unix-Socket eine Verbindung zum lokalen Server mithilfe der Vertrauensauthentifizierung herstellen kann. Sie können Ihren Cronjob als Postgres-Systembenutzer ausführen, eine Verbindung zum lokalen Socket herstellen und dann die Rolle wechseln, wenn Ihre gespeicherte Prozedur nicht mit Superuser-Berechtigungen ausgeführt werden soll.

In der Standardeinstellung können Sie dies einfach tun:

$ sudo -u postgres crontab -e

Fügen Sie im Editor den Eintrag crontab wie folgt hinzu:

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

und in deiner /path/to/run_stored_procedure.sh Datei benutzt du einfach psql um deine store Prozedur aufzurufen

#!/usr/bin/env bash
psql my_db_name <<END
    SET ROLE limited_user;
    SELECT my_stored_proc();
    SELECT 1 FROM my_stored_proc();
END
Lüge Ryan
quelle
1
'Es ist nicht wirklich eine gute Idee, die Datenbank so zu missbrauchen' Warum denkst du, ist es Missbrauch? Die verschiedenen Mainstream-RDBMS haben in der Regel ähnliche Ansätze, und ich finde das nicht so schrecklich. Wenn Sie keinen Zugriff auf das Betriebssystem haben, fehlt Ihnen Crontab.
10.