
| View Eine View ist eine Sicht auf den Inhalt einer oder mehrerer Tabellen. Hinter einer View verbirgt sich datenbankintern eine SELECT-Anweisung. |
| Materialized View Materialized Views sind spezielle Sichten auf Tabellen, deren Inhalt temporär physikalisch gespeichert wird, um den Aufwand zur Berechnung zu minimieren. |
| Crontab Die Crontab bzw. der Cron-Dienst dient der zeitlichen Steuerung von wiederkehrenden Aufgaben. In der Crontab werden diese Aufgaben in einer Tabellen-ähnlichen Struktur terminiert. |
| DDL Data Definition Language. Mit DDL-Kommandos werden Datenstrukturen gepflegt (z. B. Tabellen anlegen oder löschen). |
Sowohl Datenbankanwender als auch -administratoren sind oftmals mit wiederkehrenden Aufgaben beschäftigt. Sei es das regelmäßige Erstellen von Materialized Views mit den Umsatzzahlen des letzten Monats oder Jahres, das Prüfen von Tabellen oder Indexen, das nächtliche Laden von Daten oder das periodische Aufräumen von Datenbanken und/oder Tabellen.
Bislang wurden solche Aufgaben durch das Schreiben von SQL-Skripten gelöst, die dann über Betriebssystemmittel (Crontab oder geplante Tasks) von außerhalb der Datenbank gesteuert wurden. Hierzu war es notwendig, das Passwort des ausführenden Users im Klartext beim Aufruf zu hinterlegen. Alternativ hatte man natürlich die Möglichkeit, vollständig auf eine Authentifizierung zu verzichten. Beide Varianten waren in der Praxis eher unbefriedigend.
Die Steuerung von Jobs kann von nun an datenbankintern über einen eigenen Prozess erfolgen. Dieser Job-Prozess ist beim Start der MySQL Datenbank in der neuen Version zwar aktiviert, führt zunächst jedoch keine Aufträge aus. Er befindet sich in einer Art Standby-Modus. Um die Jobsteuerung zu aktivieren, muss der globale Konfigurationsparameter event_scheduler umgesetzt werden:
| 0 | Scheduler ist deaktiviert |
| 1 | Scheduler ist aktiviert und führt Jobs aus |
| 2 | Scheduler ist aktiviert, führt aber keine Jobs aus (Default-Einstellung) |
Die Aktivierung des Schedulers kann wahlweise zur Laufzeit über set-Anweisungen (siehe Abbildung 1) oder aber dauerhaft über die Konfigurationsdatei (my.ini bzw. my.cnf) vorgenommen werden.
mysql> show variables like '%event%'; +-----------------+-------+ | Variable_name | Value | +-----------------+-------+ | event_scheduler | 2 | +-----------------+-------+ 1 row in set (0.00 sec) mysql> set global event_scheduler = 1; Query OK, 0 rows affected (0.00 sec) |
| Abb. 1: Ermitteln und Aktivieren der Jobsteuerung. |
Um Aufträge erstellen zu dürfen, benötigt der Datenbank-User das "EVENT"-Privileg. Das Anlegen von Jobs erfolgt dann über eine wohlbekannte DDL-ähnliche Syntax (siehe Abbildung 2). Besondere Beachtung verdient hier die schedule-Klausel. Über diese Syntax können beliebig komplexe Zeitpläne erzeugt werden.
CREATE EVENT [IF NOT EXISTS] event_name
ON SCHEDULE schedule
[ON COMPLETION [NOT] PRESERVE]
[ENABLE | DISABLE]
[COMMENT 'comment']
DO sql_statement;
schedule:
AT timestamp [+ INTERVAL interval]
| EVERY interval [STARTS timestamp] [ENDS timestamp]
interval:
quantity {YEAR | QUARTER | MONTH | DAY | HOUR | MINUTE |
WEEK | SECOND | YEAR_MONTH | DAY_HOUR | DAY_MINUTE |
DAY_SECOND | HOUR_MINUTE | HOUR_SECOND | MINUTE_SECOND} |
| Abb. 2: Die Syntax zur Erstellung eines Jobs. |
Prinzipiell können zwei Arten von Ausführungsplänen unterschieden werden:
Zusätzlich können Zeitpläne mit Bedingungen, ähnlich den IF-Anweisungen aus Programmiersprachen, kombiniert werden, z. B. "Führe den Auftrag alle fünf Minuten aus, wenn der User XYZ eingeloggt ist". Einige exemplarische Zeitpläne und Jobs können der aktuellen MySQL-Dokumentation [1] entnommen werden.
Die vollständige Qualifikation von Datenbankobjekten (<DB_NAME>.<OBJECT_NAME>) ist prinzipiell immer eine gute Sache. Gerade beim Umgang mit Events sollte man aber besonders achtsam sein. Events (Jobs) sind wie alle anderen Objekte datenbankspezifisch. In unserem Beispiel (siehe Abbildung 3) liegt das Event in der Datenbank events. Der voll qualifizierte Name dieses Objektes lautet also: events.log_user. Das Event sucht damit alle anderen, nicht voll qualifizierten Objekte, wie z. B. Tabellen, in genau diesem Kontext.
Darüber hinaus werden Aufträge immer mit den Rechten des Besitzers, also des Users, der den Job angelegt hat, ausgeführt. Hat dieser nicht ausreichende Berechtigungen für den Zugriff auf die benötigten Tabellen, schlägt der Job fehl.
mysql> use events; mysql> create table test.current_user ( id bigint, user varchar(16), host varchar(16), command varchar(16) ); mysql> create event test.log_user on schedule every 30 second do insert into events.current_user select id, user, host, command from information_schema.processlist; |
| Abb. 3: Beispiel für einen einfachen Job, welcher die User-Aktivität überwacht. |
Dem Administrator stehen, wie bei MySQL üblich, mehrere Wege offen, um Informationen über seine Events einzuholen. Zum einen stehen die zwei Systemtabellen mysql.event und information_schema.events zur Verfügung, in denen u. a. auch die letzten Ausführungszeiten der Events protokolliert werden. Zum anderen präsentiert das neue Kommando SHOW [FULL] EVENTS Auszüge aus den Systemtabellen. Darüber hinaus kann, ähnlich wie bei Tabellen, das Kommando SHOW CREATE EVENT event_name genutzt werden, um Informationen über den Aufbau des Events zu bekommen. Das Kommando ALTER EVENT event_name ENABLE/DISABLE; aktiviert bzw. deaktiviert nachträglich bestehende Aufträge.
Automatismen können die Arbeit eines Datenbankadministrators erleichtern. Dennoch sollte man sich nicht 100%ig auf diese Mechanismen verlassen. Getreu dem Motto: "Vertrauen ist gut, Kontrolle ist besser".
Eine Möglichkeit, sich über die Ausführungen eines Events zu informieren, ist das allgemeine Error Log des Servers (siehe Abbildung 4).
Version: '5.1.11-beta' socket: '' port: 3306 MySQL Community Server (GPL) 060720 10:30:31 [Note] SCHEDULER: Manager thread booting 060720 10:30:31 [Note] SCHEDULER: Loaded 0 events 060720 10:30:31 [Note] SCHEDULER: Manager thread started with id 1 060720 10:33:12 [Note] SCHEDULER: [events.log_user of root@localhost] executing in thread 5 060720 10:33:12 [Note] SCHEDULER: [events.log_user of root@localhost] executed. RetCode=0 060720 10:33:17 [Note] SCHEDULER: [events.log_user of root@localhost] executing in thread 6 060720 10:33:17 [Note] SCHEDULER: [events.log_user of root@localhost] executed. RetCode=0 |
| Abb. 4: Auszug aus der allgemeinen Error-Log des Servers. |
Besonderes Augenmerk sollte hierbei auf den Eintrag Manager thread started with id 1 gelegt werden. Dieser Eintrag gibt darüber Auskunft, ob der Scheduler überhaupt beim Serverstart aktiviert wurde.
Die nachfolgenden Zeilen zeigen uns den Verlauf unseres Auftrages log_user (siehe Abbildung 3), der alle 30 Sekunden erneut ausgeführt wird. Wünschenswert ist hier, dass die Jobs mit einem RetCode=0 (Return Code) beendet werden. Dies zeigt an, dass der Job ohne Fehler beendet wurde.
Eine weitere Möglichkeit, sich den Status des Schedulers anzeigen zu lassen, bietet die Prozessliste: select id, user, host, command, state, info from processlist where user = 'event_scheduler';
Weitaus eleganter und sicherer ist jedoch die Nutzung von BEGIN/END-Blöcken im Event selber, da diese Blöcke mit einem ERROR-Handler verknüpft werden können (siehe Abbildung 5). Ein ERROR-Handler kann beispielsweise genutzt werden, um aufgetretene Probleme direkt in eine Tabelle zu protokollieren. Während der Blick in die Prozessliste nur darüber Aufschluss gibt, ob das Scheduling generell gestartet wurde, können die ERROR-Handler jobspezifisch gestaltet werden.
In unserem Beispiel werden in einem Fehlerprotokoll der Ausführungszeitpunkt und der Name des entsprechenden Jobs in der Tabelle events.event_errors geloggt. Natürlich können in so einem ERROR-Handler auch andere Maßnahmen getroffen werden, wie z. B. das Erzeugen von nicht vorhandenen Tabellen usw.
drop table if exists event_error;
create table event_errors
(
nr int primary key auto_increment,
job varchar(20),
jobdate timestamp
);
drop event if exists log_user;
delimiter //
create event log_user on schedule every 5 second
do
begin
declare exit handler for sqlexception
insert into event_errors (job) values ('log_user');
insert into events.monitor select * from nowhere;
end
// |
| Abb. 5: Event zum Protokollieren auftretender Fehler in der Tabelle event_errors. |
Die MySQL-Events sind eine weitere sinnvolle Funktion, welche jeden Administrator und Entwickler erfreuen dürfte. Im Zusammenhang mit den erst kürzlich eingeführten Triggern und Prozeduren (siehe ORDIX News Artikel "MySQL 5 - The Next Generation") ergeben sich sowohl für den Anwender als auch für den Administrator vielfältige Möglichkeiten, um lästige, wiederkehrende Aufgaben zu automatisieren, ohne auf datenbankexterne Mechanismen zurückgreifen zu müssen. In der nächsten Ausgabe stellen wir Ihnen dann die neu geschaffene Möglichkeit der Partitionierung vor.
Matthias Jung (info@ordix.de).