Premium

Geplante Events

In echten Anwendungen taucht oft die Anforderung auf, bestimmte Aktionen automatisch und nach Zeitplan auszuführen: alte Einträge bereinigen, Statistiken aktualisieren, Reports erzeugen. Dafür bietet SQL den Mechanismus der geplanten Events.

Ein Event ist eine Aufgabe, die die Datenbank selbst nach Zeitplan startet. Du konfigurierst sie einmal — sie läuft danach automatisch.

Events in MySQL funktionieren ähnlich wie der Task Scheduler eines Betriebssystems: Du legst die Aufgabe einmal an, und die Datenbank führt sie automatisch nach Zeitplan aus.

In PostgreSQL wird für die automatische Ausführung von Aufgaben die Extension pg_cron verwendet. Damit kannst du SQL-Befehle mit der cron-Syntax planen (wie unter Unix).

Wann brauchst du das?

Geplante Events helfen bei der Automatisierung von Aufgaben wie:

  • Datenbereinigung: Löschen veralteter Log-Einträge oder temporärer Daten
  • Statistik-Update: Neuberechnung aggregierter Daten für Analytics
  • Report-Erstellung: Automatisches Erzeugen periodischer Reports
  • Backups: Erstellen von Kopien wichtiger Daten

Scheduler aktivieren

Bevor du Events anlegen kannst, solltest du sicherstellen, dass der Event Scheduler eingeschaltet ist:

MySQL 8.1
SHOW VARIABLES LIKE 'event_scheduler';

Falls er ausgeschaltet ist, schalte ihn ein:

MySQL 8.1
SET GLOBAL event_scheduler = ON;

Um geplante Aufgaben in PostgreSQL zu nutzen, musst du die Extension pg_cron installieren:

MySQL 8.1
CREATE EXTENSION IF NOT EXISTS pg_cron;

Wichtig: Die Extension pg_cron kann Superuser-Rechte und eine zusätzliche PostgreSQL-Konfiguration erfordern. In Cloud-Diensten (AWS RDS, Azure) ist sie möglicherweise schon vorinstalliert.

Einmaliges Event anlegen

Beginnen wir mit dem Einfachsten — einem Event, das einmalig zu einem bestimmten Zeitpunkt läuft:

MySQL 8.1
CREATE EVENT cleanup_old_logs
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 DAY
DO
    DELETE FROM logs WHERE created_at < NOW() - INTERVAL 30 DAY;

Dieses Event löscht 24 Stunden nach seiner Erstellung Log-Einträge, die älter als 30 Tage sind.

Die Syntax im Detail:

  • CREATE EVENT cleanup_old_logs — wir legen ein Event mit dem Namen cleanup_old_logs an
  • ON SCHEDULE AT — wir geben an, wann das Event ausgeführt werden soll
  • CURRENT_TIMESTAMP + INTERVAL 1 DAY — Ausführungszeitpunkt (in 1 Tag)
  • DO — der auszuführende Code (jede beliebige SQL-Anweisung)
MySQL 8.1
SELECT cron.schedule(
    'cleanup_old_logs',
    '0 3 * * *',
    'DELETE FROM logs WHERE created_at < NOW() - INTERVAL ''30 days'''
);

Dieses Event läuft jeden Tag um 3:00 Uhr morgens und löscht Log-Einträge, die älter als 30 Tage sind.

Die Syntax im Detail:

  • cron.schedule() — Funktion zum Anlegen einer geplanten Aufgabe
  • 'cleanup_old_logs' — Name der Aufgabe
  • '0 3 * * *' — Zeitplan im cron-Format (Minute Stunde Tag Monat Wochentag)
  • Letzter Parameter — der auszuführende SQL-Befehl

cron-Zeitplan-Format:

cron-Zeitplan-Format

Wiederkehrendes Event anlegen

Häufiger sollen Events regelmäßig laufen — jeden Tag, jede Stunde oder jede Minute:

MySQL 8.1
CREATE EVENT update_statistics
ON SCHEDULE EVERY 1 HOUR
DO
BEGIN
    UPDATE product_stats SET
        total_sales = (SELECT SUM(amount) FROM orders WHERE product_id = product_stats.product_id),
        last_updated = NOW();
END;

Dieses Event aktualisiert die Verkaufsstatistik jede Stunde.

Die Syntax im Detail:

  • ON SCHEDULE EVERY 1 HOUR — stündlich ausführen
  • BEGIN ... END — Block aus mehreren SQL-Anweisungen

Mögliche Intervalle:

  • EVERY 1 MINUTE — jede Minute
  • EVERY 1 HOUR — jede Stunde
  • EVERY 1 DAY — jeden Tag
  • EVERY 1 WEEK — jede Woche
  • EVERY 1 MONTH — jeden Monat
  • EVERY 30 SECOND — alle 30 Sekunden
MySQL 8.1
SELECT cron.schedule(
    'update_statistics_hourly',
    '0 * * * *',
    $$
    UPDATE product_stats SET
        total_sales = (SELECT SUM(amount) FROM orders WHERE product_id = product_stats.product_id),
        last_updated = NOW()
    $$
);

Dieses Event aktualisiert die Verkaufsstatistik jede Stunde (zur vollen Stunde).

Beispiele für Zeitpläne:

  • '*/5 * * * *' — alle 5 Minuten
  • '0 * * * *' — jede Stunde (zur vollen Stunde)
  • '0 0 * * *' — jeden Tag um Mitternacht
  • '0 0 * * 0' — jeden Sonntag um Mitternacht
  • '0 9 1 * *' — am 1. jedes Monats um 9:00 Uhr

Event mit begrenzter Laufzeit

Manchmal soll ein Event nur in einem bestimmten Zeitraum aktiv sein:

MySQL 8.1
CREATE EVENT seasonal_discount
ON SCHEDULE EVERY 1 DAY
STARTS '2025-12-01 00:00:00'
ENDS '2025-12-31 23:59:59'
DO
    UPDATE products SET price = price * 0.9 WHERE category = 'seasonal';

Dieses Event vergibt im gesamten Dezember 2025 täglich 10 % Rabatt auf saisonale Produkte.

Neue Elemente:

  • STARTS — Beginn des Gültigkeitszeitraums
  • ENDS — Ende des Gültigkeitszeitraums

Nach dem angegebenen Datum stoppt die Ausführung automatisch.

pg_cron bietet keinen eingebauten Mechanismus zum automatischen Beenden von Aufgaben, aber du kannst die Datumsprüfung direkt in den Befehl einbauen:

MySQL 8.1
SELECT cron.schedule(
    'seasonal_discount',
    '0 0 * * *',
    $$
    UPDATE products
    SET price = price * 0.9
    WHERE category = 'seasonal'
      AND CURRENT_DATE BETWEEN '2025-12-01' AND '2025-12-31'
    $$
);

Alternativ kannst du eine Aufgabe einrichten, die das Event am Ende des Zeitraums entfernt:

MySQL 8.1
SELECT cron.schedule(
    'remove_seasonal_discount',
    '0 0 1 1 *',  -- 1. Januar um Mitternacht
    $$SELECT cron.unschedule('seasonal_discount')$$
);

Vorhandene Events anzeigen

Alle angelegten Events anzeigen:

MySQL 8.1
SHOW EVENTS;

Events einer bestimmten Datenbank ansehen:

MySQL 8.1
SHOW EVENTS FROM your_database_name;

Alle geplanten Aufgaben anzeigen:

MySQL 8.1
SELECT * FROM cron.job;

Das liefert eine Tabelle mit allen Aufgaben samt Zeitplan und Befehl zurück.

Ausführungshistorie ansehen:

MySQL 8.1
SELECT * FROM cron.job_run_details
ORDER BY start_time DESC
LIMIT 10;

Events verwalten

Event vorübergehend deaktivieren:

MySQL 8.1
ALTER EVENT cleanup_old_logs DISABLE;

Event aktivieren:

MySQL 8.1
ALTER EVENT cleanup_old_logs ENABLE;

Zeitplan eines Events ändern:

MySQL 8.1
ALTER EVENT cleanup_old_logs
ON SCHEDULE EVERY 2 HOUR;

Event löschen:

MySQL 8.1
DROP EVENT IF EXISTS cleanup_old_logs;

Geplante Aufgabe löschen:

MySQL 8.1
SELECT cron.unschedule('cleanup_old_logs');

Oder über die Job-ID:

MySQL 8.1
SELECT cron.unschedule(42);  -- wobei 42 die jobid aus der Tabelle cron.job ist

Aufgabe ändern:

In pg_cron kannst du eine bestehende Aufgabe nicht direkt ändern. Du musst die alte löschen und eine neue anlegen:

MySQL 8.1
-- Alte Aufgabe entfernen
SELECT cron.unschedule('cleanup_old_logs');

-- Neue Aufgabe mit aktualisiertem Zeitplan anlegen
SELECT cron.schedule(
    'cleanup_old_logs',
    '0 */2 * * *',  -- alle 2 Stunden
    'DELETE FROM logs WHERE created_at < NOW() - INTERVAL ''30 days'''
);

Wichtige Punkte beim Arbeiten mit Events

  1. Berechtigungen: Zum Erstellen von Events brauchst du das Privileg EVENT.

  2. Zeitzone: Events laufen in der Zeitzone des Datenbankservers.

  3. Performance: Vermeide Events mit zu kurzem Intervall (jede Minute) — das kann sich auf die Performance auswirken.

  1. Berechtigungen: Für pg_cron sind in der Regel Superuser-Rechte oder eine spezielle Konfiguration nötig.

  2. Zeitzone: pg_cron-Aufgaben laufen in der Zeitzone von PostgreSQL (kannst du mit SHOW timezone; prüfen).

  3. Performance: pg_cron prüft den Zeitplan jede Sekunde — die minimale Genauigkeit beträgt aber 1 Minute.

  4. Logging: Alle Ausführungen werden in der Tabelle cron.job_run_details gespeichert, das hilft beim Debugging.

Selbsttest

Welches ist das kleinste Intervall, das du für wiederkehrende Events sinnvoll verwenden kannst?

Geplante Events sind ein mächtiges Werkzeug, um Routineaufgaben in der Datenbank zu automatisieren. Sie sorgen für saubere Daten, aktuelle Statistiken und regelmäßige Wartungsoperationen — ganz ohne Eingreifen von Entwickelnden! 🚀