Hide
Die Auftragshistorie soll mit der Job-Historie in der Weise verknüpft sein, dass per SQL eine Auskunft über den Fehlerzustand bzw. das Nicht-Erreichen des Endzustands eines Auftrags möglich ist. Die nachstehenden Beispiele gelten für Oracle:
1. Erweiterung des Datenmodells
a) Tabelle SCHEDULER_HISTORY
CREATE TABLE SCHEDULER_HISTORY ADD (
"PID" NUMBER(10) DEFAULT 0 NOT NULL /* operating system process id */
);
b) Tabelle SCHEDULER_NODE_HISTORY
CREATE TABLE SCHEDULER_NODE_HISTORY (
"HISTORY_ID" NUMBER(10) DEFAULT 0 NOT NULL, /* references order in scheduler_order_history.history_id */
"ORDERING" NUMBER(10) DEFAULT 0 NOT NULL, /* ordering of entries per order */
"TASK_ID" NUMBER(10) DEFAULT 0 NOT NULL, /* references task in scheduler_history.id */
"STATE" VARCHAR2(100) NOT NULL, /* order state for current node */
"NEXT_STATE" VARCHAR2(100) NOT NULL, /* order state for next node */
"END_STATE" NUMBER(1) DEFAULT 0 NOT NULL, /* end state reached 0=no, 1=yes */
"START_TIME" DATE NOT NULL, /* timestamp when entering this node */
"END_TIME" DATE NOT NULL, /* timestamp when leaving this node */
"ERROR" NUMBER(1) DEFAULT 0 NOT NULL, /* error state 0=ok, 1=error */
"ERROR_CODE" VARCHAR2(50), /* Job Scheduler error message no. */
"ERROR_TEXT" VARCHAR2(250), /* error message */
PRIMARY KEY ( "HISTORY_ID", "ORDERING" )
);
2. Versorgung durch den Job Scheduler
a) SCHEDULER_HISTORY
PID wird beim Anlegen des Satzes versorgt
b) SCHEDULER_ORDER_HISTORY
- Satz wird beim Start des Auftrags geschrieben
* history_id, job_chain, order_id, spooler_id, title, state, start_time werden versorgt
* end_time wird mit '0000-00-00 00:00:00' versorgt
- Satz wird beim Ende des Auftrags aktualisiert
* end_time wird mit aktuellem Zeitstempel versorgt
c) SCHEDULER_NODE_HISTORY
- Ein Auftrag kann wg. Wiederholung mehrfach dieselbe Task-ID durchlaufen
- Satz wird jeweils beim Wechsel des Auftragszustands geschrieben:
* Anlegen bei Start der Ausführung durch die Task:
INSERT INTO SCHEDULER_NODE_HISTORY ("HISTORY_ID", "ORDERING", "TASK_ID", "STATE", "NEXT_STATE", "START_TIME", "END_TIME")
VALUES (4711, 1, 0815, 'start', 'next', '2007-09-30 12:22:14', '0000-00-00 00:00:00');
* Aktualisieren beim Ende der Ausführung durch die Task
UPDATE SCHEDULER_NODE_HISTORY SET "ERROR"=0, "ERROR_CODE"='SCHEDULER-1234', "ERROR_TEXT"='....',
NEXT_STATE='error', "END_STATE"=1
WHERE "HISTORY_ID"=4711 AND "ORDERING"=1;
Das Modell steht erst mal zur Diskussion.
- Pro:
* die Verknüpfung ist erstmal pro Auftragsstatus sichtbar
* es kann abgefragt werden,
** ob ein Auftrag abschließend mit Fehler beendet wurde
** ob ein Auftrag zwischendurch auf Fehler lief, aber ggf. abschließend ohne Fehler beendet wurde
- Con:
* das Modell ist redundant, die Node-History wiederholt im Grunde die Attribute der Order-History
* der Platzbedarf ist hoch
Show
Die Auftragshistorie soll mit der Job-Historie in der Weise verknüpft sein, dass per SQL eine Auskunft über den Fehlerzustand bzw. das Nicht-Erreichen des Endzustands eines Auftrags möglich ist. Die nachstehenden Beispiele gelten für Oracle:
1. Erweiterung des Datenmodells
a) Tabelle SCHEDULER_HISTORY
CREATE TABLE SCHEDULER_HISTORY ADD (
"PID" NUMBER(10) DEFAULT 0 NOT NULL /* operating system process id */
);
b) Tabelle SCHEDULER_NODE_HISTORY
CREATE TABLE SCHEDULER_NODE_HISTORY (
"HISTORY_ID" NUMBER(10) DEFAULT 0 NOT NULL, /* references order in scheduler_order_history.history_id */
"ORDERING" NUMBER(10) DEFAULT 0 NOT NULL, /* ordering of entries per order */
"TASK_ID" NUMBER(10) DEFAULT 0 NOT NULL, /* references task in scheduler_history.id */
"STATE" VARCHAR2(100) NOT NULL, /* order state for current node */
"NEXT_STATE" VARCHAR2(100) NOT NULL, /* order state for next node */
"END_STATE" NUMBER(1) DEFAULT 0 NOT NULL, /* end state reached 0=no, 1=yes */
"START_TIME" DATE NOT NULL, /* timestamp when entering this node */
"END_TIME" DATE NOT NULL, /* timestamp when leaving this node */
"ERROR" NUMBER(1) DEFAULT 0 NOT NULL, /* error state 0=ok, 1=error */
"ERROR_CODE" VARCHAR2(50), /* Job Scheduler error message no. */
"ERROR_TEXT" VARCHAR2(250), /* error message */
PRIMARY KEY ( "HISTORY_ID", "ORDERING" )
);
2. Versorgung durch den Job Scheduler
a) SCHEDULER_HISTORY
PID wird beim Anlegen des Satzes versorgt
b) SCHEDULER_ORDER_HISTORY
- Satz wird beim Start des Auftrags geschrieben
* history_id, job_chain, order_id, spooler_id, title, state, start_time werden versorgt
* end_time wird mit '0000-00-00 00:00:00' versorgt
- Satz wird beim Ende des Auftrags aktualisiert
* end_time wird mit aktuellem Zeitstempel versorgt
c) SCHEDULER_NODE_HISTORY
- Ein Auftrag kann wg. Wiederholung mehrfach dieselbe Task-ID durchlaufen
- Satz wird jeweils beim Wechsel des Auftragszustands geschrieben:
* Anlegen bei Start der Ausführung durch die Task:
INSERT INTO SCHEDULER_NODE_HISTORY ("HISTORY_ID", "ORDERING", "TASK_ID", "STATE", "NEXT_STATE", "START_TIME", "END_TIME")
VALUES (4711, 1, 0815, 'start', 'next', '2007-09-30 12:22:14', '0000-00-00 00:00:00');
* Aktualisieren beim Ende der Ausführung durch die Task
UPDATE SCHEDULER_NODE_HISTORY SET "ERROR"=0, "ERROR_CODE"='SCHEDULER-1234', "ERROR_TEXT"='....',
NEXT_STATE='error', "END_STATE"=1
WHERE "HISTORY_ID"=4711 AND "ORDERING"=1;
Das Modell steht erst mal zur Diskussion.
- Pro:
* die Verknüpfung ist erstmal pro Auftragsstatus sichtbar
* es kann abgefragt werden,
** ob ein Auftrag abschließend mit Fehler beendet wurde
** ob ein Auftrag zwischendurch auf Fehler lief, aber ggf. abschließend ohne Fehler beendet wurde
- Con:
* das Modell ist redundant, die Node-History wiederholt im Grunde die Attribute der Order-History
* der Platzbedarf ist hoch
Vielleicht muss der Satz etwas später als bisher geschrieben werden, bis der Scheduler die Pid hat.
Als Default würde ich NULL nehmen.
b) Neue Tabelle scheduler_node_history
Anscheinend ist es nicht eine Geschichte der Knoten, sondern der Auftragsschritte. Die Tabelle könnte dann scheduler_order_step_history heißen.
Als Defaults würde ich für alle Spalten NULL nehmen.
Die Tabelle scheduler_order_history muss schon beim Start des Auftrags beschrieben werden. Dazu wird eine neue history_id (jetzt eigentlich eine Laufkennung, order_run_id) erzeugt und im Auftrag vermerkt. Beschreiben der Tabellen scheduler_order_history und scheduler_orders müssen in einer Transaktion zusammenfasst werden.
Die Spalte ordering ist eigentlich die Schrittnummer. Sie wird für jeden erreichten Jobkettenknoten hochgezählt und in der Tabelle scheduler_orders oder scheduler_order_history gehalten. Zu jedem Insert in die Tabelle scheduler_order_step_history kommt also noch ein Update in die Tabelle scheduler_order_history.
Die Spalte next_state geht konstant aus der Jobkette oder dem folgenden Eintrag hervor, sie enthält keine neue Information.
Error_code und error_text sind redundant mit den Spalten in scheduler_history. Sie werden aber nicht in derselben Transaktion geschrieben, für einen sehr kurzen Moment fallen sie also auseinander. Möglicherweise können beide Transaktionen zusammengefasst werden.
Die Spalte end_state (oder end_state_reached) könnte in scheduler_order_history gehalten werden.
Die Tabelle hätte dann diese 6 Spalten:
- Laufkennung
- Schrittnummer
- Zustand
- Task-Kennung
- Startzeit
- Endezeit
Man könnte Order.state_text dazunehmen.
Der Platzbedarf fällt im Vergleich mit der Speicherung des Auftragsprotokolls vielleicht nicht so ins Gewicht.
Die Geschwindigkeit wird sich verringern, fast so langsam wie verteilte Aufträge.
Man könnte noch überlegen, wie man die Schritthistorie mit den verteilten Aufträgen effizient zusammenbekommt.