# Überwachung von Datensatzänderungen



## Romanticus (20. Dezember 2007)

Hallo,

ich habe folgende Situation:

eine produktive Datenbank und eine Datenbank, die als Datewarehouse (DW) dient. Beides sind MySql 5.x DBs mit der MyISAM-Engine. Die Daten werden einmal pro woche aus der produktiven Datenbank ins DW exportiert. Es gibt aber Tabellen, die relativ groß sind (> 500.000 Zeilen), bei denen sich aber relativ selten was ändert. Da die Änderungen aber sehr wichtig sind, müssen sie auf jeden Fall schnellstmöglich im DW auftauchen. Folgende Möglichkeiten sehe ich zur Lösung:
1. Die Tabelle wird jedes Mal komplett neu ins DW übertragen. Nachteil - es kann passieren, dass wegen 100 geänderten Datensätzen mehr als 500.000 übertragen werden, was sehr teuer ist.
2. Ich lege in der operativen Datenbank eine zusätzliche Tabelle (update_log), die die Änderungen protokollieren soll. Die Tabelle, die auf Änderungen überwacht werden soll, bekommt einen ONINSERT- und einen ONUPDATE-Trigger, die den Wert updated in der Tabelle update_log für den betroffenen Datensatz auf 1 setzt. Nachdem die Daten ins DW übertragen wurden, rufe ich eine Prozedur, die alle updated-Werte wieder zurücksetzt.
Nachteil dieser Methode ist, dass ich mehr Daten in der operativen Datenbank habe. Zweitens besteht die Gefahr, dass Inkonsistenzen entstehen, da der Extraktions-Prozess zu lange dauert um die betroffenen Tabellen für diese Zeit zu locken. 
Was denkt Ihr, wie man dieses Problem am elegantesten lösen könnte?

Gruß,
Romanticus


----------



## ristone (20. Dezember 2007)

Kannst Dir ein Trigger schreiben der nach dem Insert/Update deine 2te Datenbank updated. 
Weiss leidern nicht genau ob das Serverübergreifend funktioniert.

http://dev.mysql.com/doc/refman/5.0/en/create-trigger.html


Andere Möglichkeit wäre du Speicherst bei jedem Datensatz das Änderungsdatum und Updates dann aller x Minuten die in den letzten x Minuten geändert wurden.


----------



## Michael Engel (20. Dezember 2007)

Wenn du Shell-Zugriffsrechte hast kannst du das ganze auch sehr viel schneller kopieren als die Inserts. Indem du die frm und anderen Dateien von dem einen Verzeichniss in das andere kopierst. Vorher MySQL stoppen, kopieren, neu laden. Wenn die Files im Hunderte MB Bereich liegen ist das eine Sache von 2 Sekunden.

Nebenbei kann man die alten Datenbanken gleich noch archivieren und hat im notfall ältere backups ,)


----------



## Romanticus (20. Dezember 2007)

Michael Engel hat gesagt.:


> Wenn du Shell-Zugriffsrechte hast kannst du das ganze auch sehr viel schneller kopieren als die Inserts. Indem du die frm und anderen Dateien von dem einen Verzeichniss in das andere kopierst. Vorher MySQL stoppen, kopieren, neu laden. Wenn die Files im Hunderte MB Bereich liegen ist das eine Sache von 2 Sekunden.
> 
> Nebenbei kann man die alten Datenbanken gleich noch archivieren und hat im notfall ältere backups ,)



Ich kann die DB-Files nicht einfach ins DW kopieren, da die DB-Schemas nicht identisch sind. Jedoch habe ich an eine Art Staging Area gedacht, die das gleiche Schema hat, wie die operative DB.


----------



## olqs (20. Dezember 2007)

Erstell für jede Tabelle, die du überwachen willst eine temporäre Tabelle mit gleichm Layout.
Danach jeweils einen AFTER UPDATE und nen AFTER INSERT Trigger pro tabelle schreiben, die die Einträge nicht nur in die originale Tabelle sondern auch in die temporären schreiben. Aus den temporären kannst dann die Veränderungen schön ablesen.

Das kann aber unter Umständen sehr stark auf die Performance gehen. Also würd ichs die Tabellen für die ich das einrichte doch stark selektieren.

Gruss
olqs


----------

