Mahlzeit,
ich habe DBLog am laufen und soweit ist alles top.
Wenn ich mir nun aber die Plots zu den Temperatur-Daten so anschaue kommen da extrem viele Datenpunkte zusammen die spät. nach einer Woche nicht mehr gebraucht werden, da nur noch für Plots verwendet. Plots mit sovielen Daten schauen spät. im Jahreslog auch nicht wirklich gut aus.
Frage: Wie kann ich z.B. alle Temperaturdaten welche älter als 1 Woche sind auf wenige Werte pro Tag ausdünnen? z.b. 12 Werte/Tag. (Alle 2 Stunden). oder min/max pro Tag etc.
set <dblog> deleteOldDays [n] würde ja alle Werte löschen was ich aber nicht will.
event-min-interval und event-on-change-reading sind bekannt und werden eingesetzt. (min-interval 600 und change-reading 0.2, dennoch sind es recht viele Daten)
Gibt es dazu ein Tool oder einen Lösungsansatz?
Habe das Forum rauf und runter durchsucht aber nicht so wirklich das gefunden was ich suche....
Vielen Dank!
Hallo C0mmanda,
die Idee finde ich Spitze, historische Daten nurnoch in Stundenintervallen aufzubewahren!
Fertig gibts da meiner Kenntnis nach allerdings nichts.
Ich habe mal auf die schnelle das DbLog Modul im Anhang Erweitert damit es diese Funktionalität bereitstellt.
"set <dbLogDevice> reduceLog <days>"
Dadurch sollten alle Einträge älter als <days> auf einen Eintrag pro Stunde (den ersten) je device & reading reduziert werden.
Bitte beachten: Das ganze ist sehr Ressourcenintensiv, sowie wird Fhem nach absetzen des Befehls bis zur Fertigstellung blockiert!
Du kannst es ja mal testen ob es deinen Ansprüchen genügt, und bescheid geben ob alles so funktioniert wie es soll.
Wenn ich mal Zeit habe, oder auch jemand anderst, dann kann das evtl. noch nicht blockierend implementiert werden.
Wenn du sehen möchtest was der Befehl gerade tut (löscht) kannst du die Zeile 1318 auskommentieren, dann taucht es im Log auf.
Gruß
Claudiu
EDIT: Datei entfernt, aktuelle Verison in Post #4
Hallo rapster,
Vielen Dank für die schnelle Reaktion.
Ich habe das ganze jetzt mal ausgeführt, das Ergebnis ist ziemlich genau das was ich gesucht habe!
Ich hatte zu Beginn 337.800 Datensätze in der Datenbank. (aus ca. 7 Wochen!!).
Nach dem ausführen von reduceLogs sind es jetzt nur noch 91.054 Datensätze, in den Plots ist kein Unterschied zu sehen mit der Ausnahme dass diese etwas "glatter" sind und sich noch schneller aufbauen was auch das Ziel war.
Einzig die Jahresplots sind noch recht unleserlich, da hierfür noch immer zu viele Datenpunkte vorhanden sind, aber hier gibt es eventuell eine Lösung in den Plots selbst, anstatt "noch mehr" Daten zu löschen.
Denn mit noch weniger Datenpunkten wären dann die historischen Monats- und Wochenplots eventuell zu ungenau und unleserlich?!
Zu der "technischen" Seite:
- Ich betreibe fhem und auch die mySQL-Datenbank auf einem Intel NUC DN2820, Rechenpower ist also da (Im Vergleich zu FritzBox oder RasPi).
- reduceLogs hat jetzt ziemlich genau 25std. benötigt um 240.000 Datensätze zu löschen. Ich habe die Sache recht genau beobachtet, es werden ca. 2-4 Datensätze pro Sekunde gelöscht.
Damit sollte für andere User in etwa auszurechnen sein wie lange ihr fhem blockiert ist.
Meine Erwartungen sind soweit erfüllt, ich werde reduceLogs nun regelmäßig laufen lassen, dann sollte sich die Zeit in der fhem blockiert ist stark reduzieren.
Sollte es möglich sein reduceLog im Hintergrund laufen zu lassen ohne das fhem blockiert wäre das natürlich eine super Sache, für mich ist es aktuell aber auch in Ordnung. Dauert ja nur einmal so lang, wenn man es regelmäßig macht wird es schneller gehen. Wenn fhem dann Nachts mal eine halbe Stunde blockiert kann man sicher damit leben. Ich zumindest kann es.
Wenn noch Fragen zu dem Test offen sind immer raus damit.
Ich jedenfalls bedanke mich für die schnelle Reaktion und Hilfe. Top!
Zitat von: C0mmanda am 16 September 2015, 09:47:34
Sollte es möglich sein reduceLog im Hintergrund laufen zu lassen ohne das fhem blockiert wäre das natürlich eine super Sache, für mich ist es aktuell aber auch in Ordnung. Dauert ja nur einmal so lang, wenn man es regelmäßig macht wird es schneller gehen. Wenn fhem dann Nachts mal eine halbe Stunde blockiert kann man sicher damit leben. Ich zumindest kann es.
Eine alternative wäre noch das ganze in einem Cronjob unabhängig von FHEM abarbeiten zu lassen.
Dazu müsste die "reduceLog" Funktion in einem Shellskript abgebildet werden.
super, freut mich dass bei dir auch alles geklappt hat! :)
Hab die reduceLog Funktion nochmal etwas überarbeitet,
is zwar noch nicht Non-Blocking, allerdings nun um ein vielfaches schneller!
Es wird jetzt nicht mehr für jeden Datensatz eine eigene Transaktion durchgeführt sondern pro Tag.
Die Commandref wurde desweiteren um diesen Befehl erweitert.
Mit dieser Version werden auf meinem System (sqlite) etwa 1.800 Datensätze pro Minute aus der Datenbank entfernt,
Davon ausgehend, dein System ist genauso schnell wie meins, sollte es bei dieser Datenmenge nicht mehr 25std. sondern nurnoch etwas über 2std. dauern.
Im Anhang die aktuelle Version, sowie ein Patch für tobiasfaust um das ganze ins FHEM-Update einzuchecken.
Gruß
Claudiu
EDIT: Datei entfernt, aktuelle Version in Post #28 => http://forum.fhem.de/index.php/topic,41089.msg334617.html#msg334617
Wow, das geht ja Schlag auf Schlag :D
Großartig!
Bei nun 1800 Datensätze pro Minute sollte der Job, wenn er jede Nacht läuft, ja nur wenige Minuten (wenn überhaupt) benötigen, das reicht mir schon völlig.
Kann dann morgen nochmal berichten wie schnell es aktuell durchläuft wenn die DB schon bereinigt ist und nur 1 Tag bereinigt wird.
Bis dahin kann ich mich nur für die Superschnelle Lösung bedanken!
grtz
C0mmanda
Ja das wär super, bin gespannt wie lange das Bereinigen von einem Tag mit der aktuellen Version bei dir dauert.
Evtl. kannst du noch prüfen wieviel Records betroffen waren.
Das löschen von einem Tag (20.07.) an welchem von 23762, 21017 Records gelöscht wurden dauerte bei mir knappe 14 Minuten (~1.500/min) mit dieser Hardware:
VM mit 1 Core i5 @ 2.4 Ghz, 3GB RAM, SSD Samsung 512GB 840 Pro, SQLITE Datenbank
Das löschen von einem Tag (22.07.) an welchem von 24782, 22009 Records gelöscht wurden dauerte bei mir knappe 6,5 Minuten (~3300/min) mit dieser Hardware:
VM mit 2 Core i5 @ 2.4 Ghz, 3GB RAM, SSD Samsung 512GB 840 Pro, SQLITE Datenbank
Die benötigte Zeit hängt also sehr von den zur Verfügung stehenden CPU-Ressourcen ab.
BTW, hab die zuletzt gepostete Version nochmals bearbeitet,
mit "attr verbose 5" werden alle gelöschten Zeilen protokolliert,
mit "attr verbose 3" lässt sich wie im folgenden Beispiel loggen/beobachten welcher Tag gerade verarbeitet wird, ohne das ganze log zuzumüllen.
2015.09.16 18:04:55.413 3: DbLog dbLog: reduceLog requested.
2015.09.16 18:05:00.028 3: DbLog dbLog: reduceLog processing day: 2015-07-20
2015.09.16 18:18:59.499 3: ....
2015.09.16 18:21:58.196 3: DbLog dbLog: reduceLog requested.
2015.09.16 18:22:00.959 3: DbLog dbLog: reduceLog processing day: 2015-07-21
2015.09.16 18:28:19.784 3: DbLog dbLog: reduceLog processing day: 2015-07-22
2015.09.16 18:34:47.237 3: DbLog dbLog: reduceLog processing day: 2015-07-23
...
EDIT: Zu beachten gilt, die Änderungen werden erst in der DB sichtbar wenn der gerade zu bearbeitende Tag abgeschlossen ist!
Gruß
Claudiu
Wie versprochen hier die Infos zum bereinigen von 1 Tag:
Benutzt wurde deine zweite Version die du gepostet hast, habe noch kein fhem-update gemacht.
- Hardware: Intel NUC DN2820 (2,4GHz Dual-Core, Celeron), 2GB RAM, 60GB SSD (SanDisk), MySQL Datenbank
- Datensätze vor Bereinigung: 96.917
- Datensätze nach Bereinigung: 71.164
- Bereinigte Datensätze: 25.753
- Dauer der Bereinigung: 80 Min. was dann 320 Datensätze die Minute entspricht.
Also deutlich langsamer als deine 1500 Datensätze!
Da du jedoch einen i5 hast (wenn auch nur 1 Core eingesetzt bei den 1500) und ich "nur" einen Celeron wird es wohl daran liegen.
Was ich jedoch merkwürdig finde:
Ich habe set DBlog reduceLog 7 eingegeben.
Gelöscht würden jedoch "nur" folgende Tage:
2015.09.17 08:52:20 3: DbLog logdb: reduceLog requested.
2015.09.17 08:52:21 3: DbLog logdb: reduceLog processing day: 2015-09-07
2015.09.17 09:33:19 3: DbLog logdb: reduceLog processing day: 2015-09-08
Da wir heute den 17.09. haben hätte er meiner Meinung nach aber zumindest auch die Werte vom 09.09. löschen sollen. (Weil der 17. Tag ja noch nicht abgeschlossen ist).
Oha, ja das ist echt deutlich langsamer, mich würde mal ein Test von einem Raspi User interessieren, ob das auf so einer Platform überhaupt noch vertretbar ist...
Ich denke nicht dass es bei dir an MySQL liegt, vom Bauchgefühl her würde ich sogar behaupten das sollte schneller sein als meine SQLITE?
Da hast du allerdings recht, die Tagesangabe liegt um einen Tag daneben.
Habe in dem Beitrag http://forum.fhem.de/index.php/topic,41089.msg333552.html#msg333552 eine aktualisierte Version (und aktualisiertes Patch-File) angehangen wo dieses Problem nicht mehr auftritt.
Desweiteren wird nun nach Fertigstellung von reduceLog nochmal ein weiterer Logeintrag generiert damit man beim letzten Tag nicht raten muss :-)
Gruß
Claudiu
Die aktualisierte Version werde ich dann morgen nochmal testen 8)
Ist das schon soweit dass ich die aktuellste Version durch ein fhem-Update bekomme oder muss ich die 93_DBlog.pm noch manuell aktualisieren?
Ich denke auch nicht dass es an MySQL liegt, eher am NUC.
Laut Munin lag der Load bei max. 1,1, für einen Dual-Core eig. noch OK.
Frage mich gerade ob der NUC evtl. nur 1 Kern genutzt hat ?!
Müsste ich mal recherchieren wie ich das herausbekomme. Munin erweckt irgendwie den Verdacht....
Sollte sich keiner finden der das auf dem Raspi mal testen möchte kann ich das mal machen, brauche aber ein paar Tage dafür.
Ich bin erst vor kurzem vom Raspi 1 auf den Intel NUC umgestiegen und habe somit auf dem Raspi noch die komplette lauffähige fhem-Installation. Müsste nur ebend auf DBLog umstellen.
Auf meinem TV-Server läuft auch eine MySQL-Datenbank die ich dafür nutzen könnte. Ein altes Backup mit massig Datensätzen habe ich auch noch.
Da mir das aber Zeit kostet und auch etwas Aufwand bereitet wäre es toll wenn jemand anderes den Test machen könnte.
Meldet sich keiner in den nächsten 2-3 Tagen gehe ich die Sache an und melde mich dann.
i.M. ist die Verison noch nicht im Fhem-Update, habe Tobias (den Modul-Maintainer) angeschrieben, da stehen soweit ich weiss noch ein paar weitere commits für das Modul aus, er wird sich bestimmt hierzu melden sobald er dazu kommt :)
Denke da wird sich bestimmt jemand mit Raspi+DbLog finden der das auch nützlich findet und testet, da musst du nicht extra zurückrudern und das Basteln anfangen.
Grundsätzlich funktioniert es ja auf jeder Platform, hat mich nur interessiert ob dem Raspi bei sowas komplett die Puste ausgeht ;)
Gruß
Claudiu
Moin Claudiu,
Danke für Deine Erweiterung! 8)
Test von Gestern Abend, aber nicht sehr aussagekräftig.
Vorher: countHistory 30188
set myDbLog reduceLog 1 ca. 23:26 gestartet
countHistory 9953 2015-09-16 23:29:12
Nur Leider würde bei verbose=3, bei mir nix geloggt... daher das ca.
Version aus Antwort #4 ( von gestern Zeit ca. 23:20 Uhr )
Leider ohne Anzahl:
2015.09.17 01:29:40 3: Connecting to database SQLite:dbname=/opt/fhem/fhem.db with user
bis
2015.09.17 02:09:25 3: Connection to db SQLite:dbname=/opt/fhem/fhem.db established for pid 24780
Nutze SQLite, RPi2 mit USB-HDD als root.
Viele Grüße & Danke für Dein Knowhow
Sunny
PS: Werde gleich mal die neue Version kopieren und dann wird kurz nach 00:00 Uhr getestet.. Versuche diesmal die genauen Zeiten zu protokollieren.
Hi Sunny,
das bei dir nichts auf loglevel 3 geloggt wurde ist komisch...
Noch viel seltsamer ist deine Logausgabe welche du gepostet hast.
Die Verbindung zur Datenbank sollte direkt beim Fhem-Start von DbLog hergestellt und gecached werden,
reduceLog baut selber keine neue Verbindung auf, sondern nutzt nur das bestehende Datenbank-Handle.
Kann mir grad nicht erklären warum der Verbindungsaufbau bei dir fast eine Stunde gedauert hat? Das sind allerdings keine Logausgaben von reduceLog...
Hast du Fhem nach einspielen des Moduls neugestartet?
BTW, bei mir hat sich das bereinigen auf jedenfall gelohnt, konnte die DB um über 100 MB pro Monat verkleinern (vacuum).
Gruß
Claudiu
Moin Claudiu,
Ja, ich hatte den RPi komplett neugestartet nach "rüber kopieren" der 93_DbLog.pm.
In der Zeit mit den Aufrufen hatte ein at reduceLog gestartet.
DEF *01:30 set myDbLog reduceLog 1
mit anschliesendem zweitem at rereadcfg.
DEF *02:00 set myDbLog rereadcfg
Sehe aber gerade, das es wohl eher ein Zufall war. :(
Viele Grüße
Sunny
Hab das Modul und den Patch aus Post #4 nochmal um etwas zusätzliches Logging erweitert:
2015.09.17 19:00:41.359 3: DbLog dbLog: reduceLog requested.
2015.09.17 19:00:42.137 3: DbLog dbLog: reduceLog deleting 9264 records of day: 2015-08-20
2015.09.17 19:01:45.694 3: DbLog dbLog: reduceLog deleting 13551 records of day: 2015-08-21
2015.09.17 19:03:45.070 3: DbLog dbLog: reduceLog executed. Rows processed: 129797, deleted: 22815
Desweiteren wird nach Ausführung das neue Reading "lastReduceLogResult" aktualisiert (siehe Anhang).
@Sunny,
für was das rereadcfg? Das haut natürlich erstmal alles durcheinander :-) Der Befehl ist meiner Meinung nach sowieso nicht so optimal, und möglichst zu vermeiden.
Gruß
Claudiu
Moin Claudiu,
Bei rereadcfg, hatte ich mich am "Commandref" für DbLog orientiert.
Hatte bis vor kurzem noch eine Db-Datei, die auf 800 GB angewachsen war, und dort war der RPi danach deutlich "schneller".
Werde das rereadcfg at, dann mal deaktivieren. Die Datei kann jetzt eh nicht mehr so groß werden..
Danke & viele Grüße
Sunny
Ups, mein Fehler, du hast ja "<dblog> rereadcfg" gemacht und nicht fhem-rereadcfg, immer wieder dieses flüchtige lesen... :)
Uff, 800GB ist natürlich heftig!
Allerdings wird dadurch du Datenbankverbindung auf jedenfall neu aufgebaut, ehrlich gesagt k.A. welche Auswirkungen das hat während reduceLog gerade am werkeln ist :-)
Die delete's wurden nicht in ein eval gepackt, also sollte es denke ich zumindest nicht abbrechen... Aber obs noch funktioniert? Vll. doch mit eval arbeiten...
Probiers einfach nochmal mit der aktuellen Version aus, evtl. auch mal manuell aufrufen und schauen was passiert, sollte eigentlich bei dir auch klappen :)
Gruß
Claudiu
Moin Claudiu,
Danke, jetzt wird auch bei mir gelogged, ;D
Vorher Readings von myDbLog:
countCurrent 11 2015-09-17 19:55:30
countHistory 16089 2015-09-17 19:55:30
state connected 2015-09-17 19:54:14
Nachher:
countCurrent 51 2015-09-17 19:58:12
countHistory 15356 2015-09-17 19:58:12
lastReduceLogResult Rows processed: 8462, deleted: 779 2015-09-17 19:57:11
Und im Filelog, steht jetzt auch:
2015.09.17 19:57:06 3: DbLog myDbLog: reduceLog requested.
2015.09.17 19:57:07 3: DbLog myDbLog: reduceLog deleting 779 records of day: 2015-09-16
2015.09.17 19:57:11 3: DbLog myDbLog: reduceLog executed. Rows processed: 8462, deleted: 779
Falls Du noch etwas getestet haben möchtest...
Schönen Abend und nochmals Danke für diese schönen Funktion 8)
Sunny
PS: Die 800GB waren ein aus einem Versuch mal alles zu Loggen... Die Neugierde bzw. der Spieltrieb... :-[
Hi Sunny,
super, freut mich dass es bei dir jetzt auch klappt, und ohne Spieltrieb würde doch hier generell nichts voran gehen ;D
Bei deinen Log-Ausgaben viel mir gerade allerdings was interessantes auf, dein RasPi mit USB-HDD scheint i.M. die Records mit ~11.000/min zu bereinigen.
Anscheinend hat die reduceLog Geschwindigkeit aufgrund des fehlenden primary-keys in DbLog auch sehr sehr viel mit der Datenbankgröße zutun!
Ebenfalls schönen Abend!
Gruß
Claudiu
Nach der Erkenntnis durch @Sunny habe ich jetzt mal getestet einen INDEX auf die benötigten Zellen zu setzen:
sqlite> CREATE INDEX index_reduceLog ON history (TIMESTAMP,DEVICE,EVENT);
Das Ergebniss ist natürlich deutlich beeindruckender:
2015.09.17 20:55:05.106 3: DbLog dbLog: reduceLog requested.
2015.09.17 20:55:06.318 3: DbLog dbLog: reduceLog deleting 5264 records of day: 2015-08-21
...
2015.09.17 20:55:10.179 3: DbLog dbLog: reduceLog executed. Rows processed: 269088, deleted: 143360
Jetzt räumt reduceLog die Einträge mit 2.227.816 / min auf, was das Thema Blocking vollkommen unwichtig erscheinen lässt.
Die Datenbankgröße hat sich durch das erstellen des INDEX von 144 MB auf 200MB erhöht was ich verschmerzbar finde.
Ich überlege ob reduceLog automatisch einen INDEX anlegen soll beim verwenden falls nicht bereits vorhanden, oder ob dies dem User überlassen werden soll?
Was meint ihr?
Bei mir bleibt der INDEX auf jedenfall drin, und mit einer effektiven fhem blockier-Zeit von wenigen ms/Tag kann ich reduceLog nun auch beruhigt jeden Tag laufen lassen :)
Auf jedenfall muss ich das zumindest Morgen noch in die Commandref einbringen...
Evtl. könnt ihr das ja mal bei euch mit einer größeren Datenmenge verifizieren und mir eure Meinung mitteilen ;)
Gruß
Claudiu
Ein herzerfrischendes "Moin" vom hintern-Deich vorweg!
Wow!... und ich wollte schon ein eigene Modul namen "93_DbLog_MuckOut.pm" schreiben... Das dürfte sich hiermit erledigt haben.
Mein Ansatz war der, dass man mit dem Alter der Daten immer mehr auf Auflösung verzichten und auf arithmetische Mittel dieser zurückgreift.
Der grobe Ansatz der Daten sollte wie folgt zusammengefasst werden:
Dies ( t < 1d): Werte so lassen
Mensis ( 1d < t < EndOfMonth): Werte auf Mittelwerte eines 15 Minuten-Intervalls zusammenfassen
Annum (EndOfMonth < t < EndOfYear) Werte auf Mittelwerte eines 60 Minuten-Intervalls zusammenfassen (1h)
Lustrum (EndOfYear < t < 5years): Werte auf Mittelwerte eines 1440 Minuten-Intervalls zusammenfassen (1d)
Infinitum (5years < t): Werte auf Mittelwerte eines 10080 Minuten-Intervalls zusammenfassen (1w)
Wobei auch nicht alle Daten gespeichert werden brauchen. Man braucht nach einem Jahr ja nicht mehr die genauen Öffnungszeiten der Fenster und Türen, wohl aber einen Mittelwert der entsprechenden Temperaturen im Raum.
Daten die es Wert sind gepeichert zu werden:
Aktiver Tag Alle Daten bei höchster Auflösung
Aktiver Monat Alle Daten bei entsprechendem Mittelwert wo möglich
Aktives Jahr >> Nur entsprechende Mittelwerte von: Temperatur, Feuchtigkeit, Gasverbrauch, Heizkosten, E-Verbrauch, E-Kosten etc.
Euren Ansatz zu sagen, man reduziert jeden Wert auf 1nen pro Stunde ist dabei schon mal ein guter Anfang...
Jetzt müsste man nur noch den Mittelwert dieser letzten Stunde berechnen und diesen auf den Stundenwert der Folgestunde neu schreiben (Mittelwert aller Werte von 01:00 bis 02:00 auf 02:00 speichern)
Dies natürlich nur wenn die Werte nicht bereits auf kleiner 26 pro Tag reduziert worden sind.
Aber dann dürften die Ressourcen des Host-Systems wieder in die Knie gehen. ::)
Gruß
Sailor
Ein herzerfrischendes "Moin" vom hintern-Deich vorweg!
Zitat von: rapster am 17 September 2015, 16:25:06
Denke da wird sich bestimmt jemand mit Raspi+DbLog finden der das auch nützlich findet und testet, da musst du nicht extra zurückrudern und das Basteln anfangen.
Grundsätzlich funktioniert es ja auf jeder Platform, hat mich nur interessiert ob dem Raspi bei sowas komplett die Puste ausgeht ;)
Den habt Ihr gefunden.
Ich werde mal auf meinem Test-Raspi mit meiner gegenwärtigen-DB einen Test am WE machen.
Ich halte Euch auf dem Laufenden...
Gruß
Sailor
Zitat von: rapster am 17 September 2015, 21:04:07
Nach der Erkenntnis durch @Sunny habe ich jetzt mal getestet einen INDEX auf die benötigten Zellen zu setzen:
sqlite> CREATE INDEX index_reduceLog ON history (TIMESTAMP,DEVICE,EVENT);
Das Ergebniss ist natürlich deutlich beeindruckender:
2015.09.17 20:55:05.106 3: DbLog dbLog: reduceLog requested.
2015.09.17 20:55:06.318 3: DbLog dbLog: reduceLog deleting 5264 records of day: 2015-08-21
...
2015.09.17 20:55:10.179 3: DbLog dbLog: reduceLog executed. Rows processed: 269088, deleted: 143360
Jetzt räumt reduceLog die Einträge mit 2.227.816 / min auf, was das Thema Blocking vollkommen unwichtig erscheinen lässt.
Die Datenbankgröße hat sich durch das erstellen des INDEX von 144 MB auf 200MB erhöht was ich verschmerzbar finde.
Ich überlege ob reduceLog automatisch einen INDEX anlegen soll beim verwenden falls nicht bereits vorhanden, oder ob dies dem User überlassen werden soll?
Was meint ihr?
Bei mir bleibt der INDEX auf jedenfall drin, und mit einer effektiven fhem blockier-Zeit von wenigen ms/Tag kann ich reduceLog nun auch beruhigt jeden Tag laufen lassen :)
Auf jedenfall muss ich das zumindest Morgen noch in die Commandref einbringen...
Evtl. könnt ihr das ja mal bei euch mit einer größeren Datenmenge verifizieren und mir eure Meinung mitteilen ;)
Gruß
Claudiu
Ich habe wenig bis überhaupt keine Ahnung von SQL und müsste mich erstmal einlesen welche Vor- und Nachteile so ein Index haben würde :(
Ich würde also sagen, wenn das keine Auswirkungen auf fhem bzw DBLog hat, INDEX in jedem Fall setzen bei so einem Geschwindigkeitsgewinn!
Ich habe es direkt mal getestet. INDEX hinzugefügt (Die Datenbank ist von ca. 10 auf 14MB gewachsen) und reduceLog laufen lassen:
Zitat2015.09.18 08:36:27 3: DbLog logdb: reduceLog requested.
2015.09.18 08:36:28 3: DbLog logdb: reduceLog deleting 9839 records of day: 2015-09-09
2015.09.18 08:36:31 3: DbLog logdb: reduceLog deleting 5571 records of day: 2015-09-10
2015.09.18 08:36:33 3: DbLog logdb: reduceLog executed. Rows processed: 39358, deleted: 15410
In 6 sek. ist er mit 15410 Datensätzen durch.
Macht aktuell 154.100 Datensätze/Minute auf dem Intel NUC DN2820. (Gestern waren es noch 320 Datensätze/Minute.)
Die Datenbank hatte 76.362 Datensätze.
Absolut top, ich bin begeistert :)
@C0mmanda:
Super dass bei dir dadurch auch ein ordentlicher Geschwindigkeitszusatz entstanden ist.
Bei DbLog hat ein zusätzlicher INDEX erstmal keine negativen Auswirkungen bis auf die um ~ 1/4 vergrößerte Datenbank.
Generell werden durch zusätzliche INDEX, INSERT's und UPDATE's zwar etwas langsamer, weil zusätzlich bei jedem schreibvorgang der INDEX zusätzlich zu schreiben ist. Das ist allerdings bei diesem Modul vollkommen zu vernachlässigen.
Bei SQLITE wird durch DbLog schon Standardmäßig auf (DEVICE,READING,TIMESTAMP) ein INDEX erstellt, das hilft mir bei reduceLog nur nicht weiter, hier brauch ich einen INDEX auf (TIMESTAMP,DEVICE,EVENT).
@Sailor
Habe deine Idee (zwar etwas abgewandt) in die Tat umgesetzt und in Post #4 eine aktuelle Version angehangen.
Du kannst jetzt mit dem optionalen Parameter 'average' die db so bereinigen dass nichtmehr einfach nur der erste Eintrag zurückbleibt, sondern für alle numerischen Werte ein einzelner Mittelwerts-Eintrag pro Stunde um jeweils hh:30:00 zurückbleibt welcher von hh:00:00 bis hh:59:59 berechnet wird.
Bsp.: "set dbLog reduceLog 91 average"
Bitte mal ausprobieren, nicht vergessen zuvor INDEX zu erstellen, und bescheid geben :)
Beispiel Logausgabe mit 'average':
2015.09.18 19:10:32.501 3: DbLog dbLog: reduceLog requested.
2015.09.18 19:10:33.734 3: DbLog dbLog: reduceLog deleting 5729 records of day: 2015-08-25
2015.09.18 19:10:33.914 3: DbLog dbLog: reduceLog updating 302 averages of day: 2015-08-25
2015.09.18 19:10:34.194 3: DbLog dbLog: reduceLog deleting 14778 records of day: 2015-08-26
2015.09.18 19:10:34.494 3: DbLog dbLog: reduceLog updating 706 averages of day: 2015-08-26
2015.09.18 19:10:34.587 3: DbLog dbLog: reduceLog executed. Rows processed: 140774, deleted: 20507, updated: 1008
P.S. Die SQL-Statements werden nun in einem eval aufgerufen, und sollten somit bei einem eventuellen Fehler durch z.B. "rereadcfg" abbrechen und sich nicht mehr undefiniert verhalten.
Gruß
Claudiu
Nochmal kleines Update in Post #4 nachgeschoben, wodurch im EVENT Column erkennbar ist dass es sich hier um ein average handelt.
Siehe Anhang.
Gruß
Claudiu
Den INDEX muss ich aber nur einmal erstellen, oder?
Habs heute mal mit der "average" probiert, aber das scheint er nicht gemacht zu haben:
set DbLog reduceLog 7 averageZitat2015.09.19 10:21:07 3: DbLog logdb: reduceLog requested.
2015.09.19 10:21:08 3: DbLog logdb: reduceLog deleting 4978 records of day: 2015-09-11
2015.09.19 10:21:09 3: DbLog logdb: reduceLog executed. Rows processed: 29738, deleted: 4978
Zumindest für den 11.09. hätte er es ja machen sollen?! (Da bereits die DB bereits bereinigt ist sind für alle Tage davor ja keine Werte mehr vorhanden um die average zu berechenen)
Ja, einmal erstellen reicht :)
Hast du es mit der Version von gestern Abend nach einem Fhem-Neustart probiert?
Gruß
Claudiu
Ich habe einen Cubitruck 3 und in ca. 6 min 200.000 Daternsätze gelöscht, ohne average!
Seit der letzten Version funtioniert es auch! Vorher ist FHEM immer abgeschmiert!
Aber Klasse Idee die Erweiterung! Meine DB hatte schon 2GB!
Danke Lutz
Zitat von: rapster am 19 September 2015, 11:47:39
Ja, einmal erstellen reicht :)
Hast du es mit der Version von gestern Abend nach einem Fhem-Neustart probiert?
Gruß
Claudiu
Argh! Der Neustart... >:(
Morgen dann der nächste Versuch 8)
Danke!
Hallo Zusammen,
erstmal sorry,
es ist möglich dass die bisherigen Versionen, alle Datensätze von 00:xx:xx Uhr komplett gelöscht haben ohne einen Wert übrig zu lassen,
sowie dass die letzte Stunde welche mit Angabe von 'average' bearbeitet wurde, beim nächsten 'average' falsch berechnet wurde und der Wert somit falsch war.
Bitte prüft das!
Im Anhang eine neue Version + Patch, die sich an Sailor's wunsch angenähert hat.
2015.09.19 18:27:14.437 3: DbLog dbLog: reduceLog requested.
2015.09.19 18:27:15.543 3: DbLog dbLog: reduceLog deleting 7078 records of day: 2015-09-02
2015.09.19 18:27:15.710 3: DbLog dbLog: reduceLog (hourly-average) updating 365 records of day: 2015-09-02
2015.09.19 18:27:15.744 3: DbLog dbLog: reduceLog (daily-average) updating 106, deleting 1256 records of day: 2015-09-02
2015.09.19 18:27:16.006 3: DbLog dbLog: reduceLog deleting 25948 records of day: 2015-09-03
2015.09.19 18:27:16.624 3: DbLog dbLog: reduceLog (hourly-average) updating 1096 records of day: 2015-09-03
2015.09.19 18:27:16.702 3: DbLog dbLog: reduceLog (daily-average) updating 102, deleting 1300 records of day: 2015-09-03
2015.09.19 18:27:16.872 3: DbLog dbLog: reduceLog deleting 16699 records of day: 2015-09-04
2015.09.19 18:27:17.265 3: DbLog dbLog: reduceLog (hourly-average) updating 746 records of day: 2015-09-04
2015.09.19 18:27:17.313 3: DbLog dbLog: reduceLog executed. Rows processed: 132179, deleted: 52281, updated: 2415
Entweder wie bisher einfach "set <dblog> reduceLog <days>" um jeweils auf den ersten Device/Reading Eintrag pro Stunde zu reduzieren,
oder "set <dblog> reduceLog <days> average" um nicht mehr nur auf den ersten Eintrag pro Stunde zu reduzieren, sondern für jede Stunde einen Mittelwert zu bilden und diesen um hh:30:00 zu speichern,
oder nun "set <dblog> reduceLog <days> average=day" um alle numerischen Werte auf einen einzigen Mittelwert pro Tag (um 12:00:00 Uhr) zu reduzieren.
average=day ist auch nachträglich möglich, somit kann man sich z.B. ein Konstrukt bauen welches
- jeden record der letzten 2 Wochen behält
- nurnoch 1 record pro Stunde des letzten Jahres behält (optional mit Mittelwert)
- nur den Tages-Mittelwert der letzten 10 Jahre behält
('average=day' impliziert 'average')
Eine Reduzierung auf eine ganze Woche ist mMn zu viel und werde ich (zumindest vorerst) nicht einbauen.
Im Anhang Beispiele für die Ergebnisse der drei Befehle.
Bitte mal testen und bescheid geben falls was nicht passen sollte :)
Gruß
Claudiu
EDIT:
Es wird kein zusätzlicher INDEX mehr benötigt, es wird nun der standard 'Search_Idx' INDEX welcher durch die *.sql Dateien für die DbLog Erstellung erstellt wird verwendet.
Als letztes Argument kann nun "EXCLUDE=deviceRegExp1:readingRegExp1,deviceRegExp2:readingRegExp2,...." angegeben werden um device:reading Kombinationen (mehrere durch Komma getrennt) von reduceLog auszuschließen.
z.B. "set <dblog> reduceLog <days> average exclude=haustuer:state,katzenklappe\d\d:.*,.*:sabotageError"
EDIT2: Datei entfernt, wird nun über fhem-update verteilt!
Moin,
Habs geprüft und alle Werte von 00:xx:xx sind auch bei mir gelöscht! Doof, aber damit kann ich leben.
Mir geht es bei den Historischen Werten nur noch um die Plots und da wirkt sich das bei mir nicht aus.
Hätte ja auch immer ein Backup machen können schließlich ist die Funktion noch in Entwicklung.
Nur damit ich den Syntax richtig verstehe:
set <dblog> reduceLog 360 average=day
Würde von allen Werten älter als 360 Tage den Tagesdurchschnitt setzen? Alle jüngeren Werte bleiben unangetastet?
Danke.
grtz
C0mmanda
Richtig,
bei 360 würde jeder numerische Wert, bis zum 24.09.2014 auf den Tages-Mittel reduziert.
Am 25.09.2014 würden noch die vollen UTC Stunden zur aktuellen Uhrzeit auf den Stunden-Mittelwert reduziert, da <days> nicht vom Datum sondern von der Uhrzeit ausgeht und 'average=day', 'average' impliziert.
Der Rest bleibt unangetastet.
Gruß
Claudiu
Moin Claudiu,
Hut ab! Klasse was Du da erarbeitet hast.
Bin schon gespannt, wann es eingecheckt wird.
Heute Nacht, werden BPi und RPi, die Version von Heute mal testen...
Bin gespannt wie das Ergebnis ausschaut.
Hatte noch eine "596 MB (625.651.712 Bytes)" > mit INDEX ca. 800MB <
db zum testen mit dem BPi in Etappen auf 105 MB (110.684.160 Bytes) ins "VACUUM" geschickt.
Leider war der BPi mehrfach FHEM tot. Kann es ja demnächst noch mal mit der Heutigen Version testen.
Schönen Abend & bestem Dank
Sunny
Für intensive DBlog abfragen nutze ich ein 2. Fhem.
Meine Datenbank hat mittlerweile über 35440000 Datensätze
in knapp 5,6GByte gespeichert.
Ein set dblog count braucht bei mir fast 3Minuten.
Wenn ich wieder zu Hause bin werde ich mal testen.
Heute nochmal das volle Programm getestet, average + average=day und es funktioniert einwandfrei!
Vor allem sehen die Jahresplots jetzt auch viel sauberer (glatter) aus.
Wirklich eine Super Leistung für die ich mich nur noch einmal bedanken kann!
Ich hoffe diese Klasse Erweiterung wird bald eingecheckt!
grtz
CmdA
Kann mir bitte einer sagen wie ich das ganze Installieren kann? Bin etwas verwirrt mit den 2 Dateien 93_DbLog.pm_reduceLog.patch und 93_DbLog.pm
@DrJJ
Die 93_DbLog.pm_reduceLog.patch ist nur für den Modul Maintainer (Tobias) gedacht um die Änderung in's Fhem-Update zu übernehmen.
Du musst lediglich die 93_DbLog.pm im /FHEM/ Verzeichniss ersetzen und einen Fhem-Neustart machen.
@C0mmanda
Super dass bei dir auch alles geklappt hat!
Da du ja mysql hast, wie lange hat average=day bei dir gebraucht?
@stromer-12
Bin schon gespannt wieviel Speicherplatz du dadurch einsparen kannst :)
Meine logDb ist leider noch nicht besonders alt, deswegen habe ich noch nicht die Datenflut um hier viel zu testen...
Gruß
CLauidu
Ich habe auch noch nicht die wahnsinnig große DB, daher waren es nicht sonderlich viele Werte:
Zitat2015.09.21 10:28:56 3: DbLog logdb: reduceLog requested.
2015.09.21 10:28:56 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 36 records of day: 2015-08-15
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-16
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-17
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-18
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-19
2015.09.21 10:28:57 3: DbLog logdb: reduceLog deleting 29 records of day: 2015-08-20
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (hourly-average) updating 12 records of day: 2015-08-20
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-20
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 36 records of day: 2015-08-15
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-16
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-17
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-18
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-19
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-20
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 5 records of day: 2015-08-04
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-05
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-06
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-07
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-08
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-09
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-10
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-11
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-12
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-13
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-14
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-15
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 21 records of day: 2015-08-16
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-17
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-18
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-19
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-20
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 10 records of day: 2015-08-01
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 12 records of day: 2015-08-02
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 7 records of day: 2015-08-03
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 15 records of day: 2015-08-04
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 44 records of day: 2015-08-05
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 44 records of day: 2015-08-06
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 44 records of day: 2015-08-07
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 45 records of day: 2015-08-08
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 57 records of day: 2015-08-09
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 55 records of day: 2015-08-10
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 57 records of day: 2015-08-11
2015.09.21 10:28:57 3: DbLog logdb: reduceLog deleting 4 records of day: 2015-08-12
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (hourly-average) updating 3 records of day: 2015-08-12
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 57 records of day: 2015-08-12
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 53 records of day: 2015-08-13
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 61 records of day: 2015-08-14
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 58 records of day: 2015-08-15
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 59 records of day: 2015-08-16
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 56 records of day: 2015-08-17
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 55 records of day: 2015-08-18
2015.09.21 10:28:57 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 57 records of day: 2015-08-19
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 58 records of day: 2015-08-20
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 36 records of day: 2015-08-15
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-16
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-17
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-18
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-19
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 66 records of day: 2015-08-20
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 4 records of day: 2015-08-04
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-05
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-06
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-07
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 20 records of day: 2015-08-08
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-09
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-10
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-11
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-12
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-13
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-14
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-15
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-16
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-17
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-18
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-19
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 1, deleting 22 records of day: 2015-08-20
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 24 records of day: 2015-07-31
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 28 records of day: 2015-08-01
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 24 records of day: 2015-07-31
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 96 records of day: 2015-08-01
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 88 records of day: 2015-08-02
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 88 records of day: 2015-08-03
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 94 records of day: 2015-08-04
2015.09.21 10:28:58 3: DbLog logdb: reduceLog deleting 54 records of day: 2015-08-05
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (hourly-average) updating 32 records of day: 2015-08-05
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 88 records of day: 2015-08-05
2015.09.21 10:28:58 3: DbLog logdb: reduceLog deleting 15 records of day: 2015-08-06
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (hourly-average) updating 9 records of day: 2015-08-06
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 5, deleting 91 records of day: 2015-08-06
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 101 records of day: 2015-08-07
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 92 records of day: 2015-08-08
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 5, deleting 110 records of day: 2015-08-09
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 121 records of day: 2015-08-10
2015.09.21 10:28:58 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 112 records of day: 2015-08-11
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 5, deleting 110 records of day: 2015-08-12
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 118 records of day: 2015-08-13
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 123 records of day: 2015-08-14
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 120 records of day: 2015-08-15
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 132 records of day: 2015-08-16
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 131 records of day: 2015-08-17
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 118 records of day: 2015-08-18
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 5, deleting 110 records of day: 2015-08-19
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 5, deleting 110 records of day: 2015-08-20
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 15 records of day: 2015-08-01
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 17 records of day: 2015-08-02
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 13 records of day: 2015-08-03
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 18 records of day: 2015-08-04
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 44 records of day: 2015-08-05
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 46 records of day: 2015-08-06
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 2, deleting 44 records of day: 2015-08-07
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 45 records of day: 2015-08-08
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 60 records of day: 2015-08-09
2015.09.21 10:28:59 3: DbLog logdb: reduceLog deleting 4 records of day: 2015-08-10
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (hourly-average) updating 2 records of day: 2015-08-10
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 52 records of day: 2015-08-10
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 56 records of day: 2015-08-11
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 55 records of day: 2015-08-12
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 55 records of day: 2015-08-13
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 54 records of day: 2015-08-14
2015.09.21 10:28:59 3: DbLog logdb: reduceLog deleting 10 records of day: 2015-08-15
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (hourly-average) updating 3 records of day: 2015-08-15
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 62 records of day: 2015-08-15
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 61 records of day: 2015-08-16
2015.09.21 10:28:59 3: DbLog logdb: reduceLog deleting 8 records of day: 2015-08-17
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (hourly-average) updating 3 records of day: 2015-08-17
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 55 records of day: 2015-08-17
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 52 records of day: 2015-08-18
2015.09.21 10:28:59 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 59 records of day: 2015-08-19
Das ganze hat insgesamt 2 Sekunden gedauert, also recht fix!
grtz
Oha... oder besser Verdammt...!
Sorry, böser Schnitzer, das kommt davon wenn man sowas mit nur einem Datenbanksystem testet....
SQLITE gab mir die Werte sortiert nach TIMESTAMP zurück (obwohl das wahrscheinlich auch nur Glück war), die reduceLog funktion hat dies auch so erwartet.
Wie ich gerade an deiner Log Ausgabe und kurzer Recherche merke gibt MySQL (und SQLITE normalerweise auch) die Werte in einer undefinierten Reihenfolge zurück wenn man es nicht explizit anderst verlangt.
Bei dir wurde jetzt etwas völlig undefiniertes gemacht, ich kann ehrlich gesagt nichtmal sicher sagen ob das grundlegende aufräumen überhaupt richtig durchgeführt wurde (es sollte hier zumindest nichts "kaputt" gemacht worden sein, es könnten hier evtl. zu viele Werte in der DB zurückgeblieben sein),
allerdings kann meines erachtens die average keinesfalls richtig berechnet worden sein (Sie wurde mehrfach aus Teilabschnitten des Tages (bzw. der Stunden) berechnet, weswegen sich evtl. auch so ein glatter Plotverlauf ergeben hat).
Ich würde dir dringend empfehlen ein Backup der DB einzuspielen!
_________
Im Anhang von Post #28 habe ich eine aktuelle Version angehangen, wo dieses Problem behoben ist. > http://forum.fhem.de/index.php/topic,41089.msg334617.html#msg334617
Bitte teste es hiermit nochmal.
Gruß
Claudiu
Ich habe mal einen Test angestartet mit einen leeren Durchlauf.
set myDbLog reduceLog 560 average
Dabei braucht die Routine auf meinen Cubietruck 265 Sekunden.
Hi Stromer,
Ich hoffe mit der Version von heute 23:xx:xx Uhr, oder zumindest SQLITE? (Nicht dass dich der selbe Fehler wie C0mmanda trifft)
Was sagt das Reading "lastReduceLogResult" wieviel Zeilen bearbeitet wurden? Damit lässt sich dan die Zeit besser beurteilen :)
Gruß
Claudiu
Ich habe mysql seit etwa März/April letzten Jahres.
2015.09.21 23:38:56 5: Cmd: >set myDbLog reduceLog 560 average<
2015.09.21 23:43:21 5: Triggering myDbLog (1 changes)
2015.09.21 23:43:21 5: Notify loop for myDbLog lastReduceLogResult: Rows processed: 0, deleted: 0, updated: 0
2015.09.21 23:43:21 1: Perfmon: possible freeze starting at 23:38:57, delay is 264.503
OK, dann hast du glück gehabt,
vor 560 Tagen hast du noch keine Einträge in der DB gehabt, deswegen hat reduceLog hier nichts unternommen.
Bitte bei MySQL UNBEDINGT (bei SQLITE sehr empfehlenswert) auf die letzte Version von reduceLog updaten, ansonsten werden bei average oder average=day höchstwahrscheinlich falsche Werte berechnet!
Warum diese lange Wartezeit allerdings ist seltsam, das einzige was in deinem Fall ausgeführt wurde war die select Abfrage.
Ich gehe davon aus dass du noch keinen INDEX angelegt hast? Dies könnte die Dauer erklären...
Gruß
Claudiu
Mein Index:
mysql> SHOW INDEXES FROM history;
+---------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment |
+---------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
| history | 1 | Search_Idx | 1 | DEVICE | A | 18 | NULL | NULL | YES | BTREE | | |
| history | 1 | Search_Idx | 2 | READING | A | 18 | NULL | NULL | YES | BTREE | | |
| history | 1 | Search_Idx | 3 | TIMESTAMP | A | 35895919 | NULL | NULL | | BTREE | | |
+---------+------------+------------+--------------+-------------+-----------+-------------+----------+--------+------+------------+---------+---------------+
Ok, das ist der default index von DbLog, reducelog benötigt (allerdings erst später wenn wirklich etwas gelöscht wird) noch einen weiteren.
Das einzige Zeitintensive was in deinem Leerlauf-Test gemacht wird ist dieser SQL-Befehl:
SELECT TIMESTAMP,DEVICE,EVENT,READING,VALUE FROM history WHERE TIMESTAMP < DATE_SUB(CURDATE(),INTERVAL 560 DAY) ORDER BY TIMESTAMP ASC
Anschließend endet die Funktion fast sofort falls keine Werte zurückgeliefert werden.
Du kannst es ja mal direkt mit
SELECT count(*) FROM history WHERE TIMESTAMP < DATE_SUB(CURDATE(),INTERVAL 560 DAY) ORDER BY TIMESTAMP ASC
ausprobieren, ob du hier einen genauso hohen delay hast.
EDIT: Bin zwar kein MySQL Profi, denke allerdings dein Index wird bei dieser SQL abfrage nie verwendet, da TIMESTAMP in der sequence nur an dritter Stelle steht (und wenn er verwendet würde wäre er ziemlich langsam).
Der empfohlene reduceLog index setzt TIMESTAMP u.a. an erster Position des Index, und sollte somit auch bei dieser SELECT Abfrage helfen.
Zitat von: rapster am 22 September 2015, 00:44:59
Du kannst es ja mal direkt mit
SELECT count(*) FROM history WHERE TIMESTAMP < DATE_SUB(CURDATE(),INTERVAL 560 DAY) ORDER BY TIMESTAMP ASC
ausprobieren, ob du hier einen genauso hohen delay hast.
Damit ist der Delay ebenfalls so hoch.
Bin zwar kein MySQL Profi, denke allerdings dein Index wird bei dieser SQL abfrage nie verwendet, da TIMESTAMP in der sequence nur an dritter Stelle steht (und wenn er verwendet würde wäre er ziemlich langsam).
Der empfohlene reduceLog index setzt TIMESTAMP u.a. an erster Position des Index, und sollte somit auch bei dieser SELECT Abfrage helfen.
@Rapster:
Oha, das ist blöd... :(
Aber halb so wild, alte Werte zurückgespielt (ca. 60.000) und nochmal von vorn:
set <dblog> reduceLog 31 average=day
2015.09.22 10:58:20 3: DbLog logdb: reduceLog requested.
2015.09.22 10:58:21 3: DbLog logdb: reduceLog deleting 4 records of day: 2015-07-31
2015.09.22 10:58:21 3: DbLog logdb: reduceLog (hourly-average) updating 4 records of day: 2015-07-31
2015.09.22 10:58:21 3: DbLog logdb: reduceLog deleting 3204 records of day: 2015-08-01
2015.09.22 10:58:22 3: DbLog logdb: reduceLog (hourly-average) updating 25 records of day: 2015-08-01
2015.09.22 10:58:22 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 29 records of day: 2015-08-01
2015.09.22 10:58:22 3: DbLog logdb: reduceLog deleting 3438 records of day: 2015-08-02
2015.09.22 10:58:23 3: DbLog logdb: reduceLog (hourly-average) updating 32 records of day: 2015-08-02
2015.09.22 10:58:23 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 34 records of day: 2015-08-02
2015.09.22 10:58:23 3: DbLog logdb: reduceLog deleting 293 records of day: 2015-08-03
2015.09.22 10:58:23 3: DbLog logdb: reduceLog (hourly-average) updating 16 records of day: 2015-08-03
2015.09.22 10:58:23 3: DbLog logdb: reduceLog (daily-average) updating 4, deleting 25 records of day: 2015-08-03
2015.09.22 10:58:24 3: DbLog logdb: reduceLog deleting 1239 records of day: 2015-08-04
2015.09.22 10:58:24 3: DbLog logdb: reduceLog (hourly-average) updating 44 records of day: 2015-08-04
2015.09.22 10:58:24 3: DbLog logdb: reduceLog (daily-average) updating 6, deleting 43 records of day: 2015-08-04
2015.09.22 10:58:24 3: DbLog logdb: reduceLog deleting 1702 records of day: 2015-08-05
2015.09.22 10:58:25 3: DbLog logdb: reduceLog (hourly-average) updating 120 records of day: 2015-08-05
2015.09.22 10:58:25 3: DbLog logdb: reduceLog (daily-average) updating 5, deleting 115 records of day: 2015-08-05
2015.09.22 10:58:25 3: DbLog logdb: reduceLog deleting 1578 records of day: 2015-08-06
2015.09.22 10:58:25 3: DbLog logdb: reduceLog (hourly-average) updating 120 records of day: 2015-08-06
2015.09.22 10:58:25 3: DbLog logdb: reduceLog (daily-average) updating 5, deleting 115 records of day: 2015-08-06
2015.09.22 10:58:25 3: DbLog logdb: reduceLog deleting 1599 records of day: 2015-08-07
2015.09.22 10:58:26 3: DbLog logdb: reduceLog (hourly-average) updating 120 records of day: 2015-08-07
2015.09.22 10:58:26 3: DbLog logdb: reduceLog (daily-average) updating 5, deleting 115 records of day: 2015-08-07
2015.09.22 10:58:26 3: DbLog logdb: reduceLog deleting 1772 records of day: 2015-08-08
2015.09.22 10:58:27 3: DbLog logdb: reduceLog (hourly-average) updating 122 records of day: 2015-08-08
2015.09.22 10:58:27 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 117 records of day: 2015-08-08
2015.09.22 10:58:27 3: DbLog logdb: reduceLog deleting 3712 records of day: 2015-08-09
2015.09.22 10:58:28 3: DbLog logdb: reduceLog (hourly-average) updating 168 records of day: 2015-08-09
2015.09.22 10:58:28 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 161 records of day: 2015-08-09
2015.09.22 10:58:28 3: DbLog logdb: reduceLog deleting 3422 records of day: 2015-08-10
2015.09.22 10:58:30 3: DbLog logdb: reduceLog (hourly-average) updating 168 records of day: 2015-08-10
2015.09.22 10:58:30 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 161 records of day: 2015-08-10
2015.09.22 10:58:30 3: DbLog logdb: reduceLog deleting 3332 records of day: 2015-08-11
2015.09.22 10:58:31 3: DbLog logdb: reduceLog (hourly-average) updating 168 records of day: 2015-08-11
2015.09.22 10:58:31 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 161 records of day: 2015-08-11
2015.09.22 10:58:31 3: DbLog logdb: reduceLog deleting 3380 records of day: 2015-08-12
2015.09.22 10:58:33 3: DbLog logdb: reduceLog (hourly-average) updating 168 records of day: 2015-08-12
2015.09.22 10:58:33 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 161 records of day: 2015-08-12
2015.09.22 10:58:33 3: DbLog logdb: reduceLog deleting 3178 records of day: 2015-08-13
2015.09.22 10:58:34 3: DbLog logdb: reduceLog (hourly-average) updating 168 records of day: 2015-08-13
2015.09.22 10:58:35 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 161 records of day: 2015-08-13
2015.09.22 10:58:35 3: DbLog logdb: reduceLog deleting 3151 records of day: 2015-08-14
2015.09.22 10:58:36 3: DbLog logdb: reduceLog (hourly-average) updating 168 records of day: 2015-08-14
2015.09.22 10:58:36 3: DbLog logdb: reduceLog (daily-average) updating 7, deleting 161 records of day: 2015-08-14
2015.09.22 10:58:36 3: DbLog logdb: reduceLog deleting 4882 records of day: 2015-08-15
2015.09.22 10:58:38 3: DbLog logdb: reduceLog (hourly-average) updating 285 records of day: 2015-08-15
2015.09.22 10:58:38 3: DbLog logdb: reduceLog (daily-average) updating 16, deleting 269 records of day: 2015-08-15
2015.09.22 10:58:38 3: DbLog logdb: reduceLog deleting 7280 records of day: 2015-08-16
2015.09.22 10:58:40 3: DbLog logdb: reduceLog (hourly-average) updating 384 records of day: 2015-08-16
2015.09.22 10:58:41 3: DbLog logdb: reduceLog (daily-average) updating 16, deleting 368 records of day: 2015-08-16
2015.09.22 10:58:41 3: DbLog logdb: reduceLog deleting 6301 records of day: 2015-08-17
2015.09.22 10:58:43 3: DbLog logdb: reduceLog (hourly-average) updating 384 records of day: 2015-08-17
2015.09.22 10:58:43 3: DbLog logdb: reduceLog (daily-average) updating 16, deleting 368 records of day: 2015-08-17
2015.09.22 10:58:44 3: DbLog logdb: reduceLog deleting 6823 records of day: 2015-08-18
2015.09.22 10:58:46 3: DbLog logdb: reduceLog (hourly-average) updating 384 records of day: 2015-08-18
2015.09.22 10:58:47 3: DbLog logdb: reduceLog (daily-average) updating 16, deleting 368 records of day: 2015-08-18
2015.09.22 10:58:47 3: DbLog logdb: reduceLog deleting 1962 records of day: 2015-08-19
2015.09.22 10:58:48 3: DbLog logdb: reduceLog (hourly-average) updating 128 records of day: 2015-08-19
2015.09.22 10:58:48 3: DbLog logdb: reduceLog (daily-average) updating 16, deleting 128 records of day: 2015-08-19
2015.09.22 10:58:48 3: DbLog logdb: reduceLog (daily-average) updating 3, deleting 60 records of day: 2015-08-20
2015.09.22 10:58:48 3: DbLog logdb: reduceLog executed. Rows processed: 68357, deleted: 65372, updated: 3341
Am Ende hat er 28 Sekunden gebraucht für:
2015.09.22 10:58:48 3: DbLog logdb: reduceLog executed. Rows processed: 68357, deleted: 65372, updated: 3341
Das entspricht ca. 2.300 gelöschte Werte/Sekunde und 120 updated/Sekunde.
Sieht deutlich besser aus als gestern :)
Hi C0mmanda,
ja das stimmt, jetzt schauts gut aus, super! :)
Zeitlich ist es schwer zu sagen, da dein log keine Millisekunden Werte speichert,
sind jetzt aber so grob 1,5 Sekunden pro Tag, denke das ist verschmerzbar...
Gruß
Claudiu
Das ist absolut in Ordnung, das muss ich nicht auf Millisekunden runtergebrochen haben!
Werde reduceLog als "at" jede Nacht um 1Uhr durchlaufen lassen, da merkt niemand ob fhem 1,5 oder 10sek. "hängt" ;)
Danke für die großartige Arbeit!
Habe mir das Modul mal installiert und dann folgenden Befehl abgesetzt set logdb reduceLog 31 average=day
Jetzt nach ca 1 Std lebt mein fhem immer noch nicht. Mache ich da was falsch oder ist die DB mit ca 1,5 Mio Einträgen zu groß?
An der Größe der Datenbank hat sich nach der Stunde auch nichts getan
Hallo DrJJ,
hast du zuvor den INDEX erstellt?
Was steht im fhem-Log? (über die Linux Commandline mit "tail fhem.log" anschauen wenn fhem gerade hängen sollte)
Die DB ändert sich erst nach abgeschlossenen Tages-Änderungen, so lange kann es eigenltich nur dauern wenn du keinen INDEX zuvor erstellt hast.
Gruß
Claudiu
Danke für die Antwort. Einen Index habe ich nicht erstellt. Was muss ich dafür tun?
Zitat von: DrJJ am 22 September 2015, 15:50:30
Danke für die Antwort. Einen Index habe ich nicht erstellt. Was muss ich dafür tun?
Siehe : http://forum.fhem.de/index.php/topic,41089.msg333967.html#msg333967
Du kannst die Sache jetzt natürlich einfach aussitzen oder die Brechstange rausholen und fhem killen und neustarten.
Ob da was schiefgehen kann (DB kaputt oder sowas) weiß ich leider nicht. Bin mir nicht sicher....
Ohne Index hat es bei mir auf dem Intel NUC bei ca. 330.000 Einträgen 25Std. gedauert.
grtz
Den benötigten INDEX kannst du mit diesem SQL-Befehl erstellen:
CREATE INDEX index_reduceLog ON history (TIMESTAMP,DEVICE,EVENT);
Überprüfen ob der INDEX erstellt ist/wurde kannst du folgendermaßen:
sqlite> PRAGMA INDEX_LIST('history');
0|index_reduceLog|0|c|0
1|Search_Idx|0|c|0
......
mysql> SHOW INDEXES FROM history;
......
Was für Datenbank-Typ verwendest du?
Bei SQLITE z.B. wird die DB-Datei nicht automatisch kleiner, die gelöschten Zeilen werden nur intern wieder freigegeben. Um die Datei selber zu verkleinern muss manuel VACUUM; ausgeführt werden.
Habe den Befehl in meiner Mysql DB ausgeführt. Index scheint erstellt zu sein. Die DB scheint laut log gerade Tageweise reduziert zu werden.
2015.09.22 15:58:08 3: DbLog logdb: reduceLog requested.
2015.09.22 15:58:50 3: DbLog logdb: reduceLog deleting 3020 records of day: 2015-04-03
2015.09.22 15:58:55 3: DbLog logdb: reduceLog (hourly-average) updating 184 records of day: 2015-04-03
2015.09.22 15:58:57 3: DbLog logdb: reduceLog (daily-average) updating 25, deleting 154 records of day: 2015-04-03
2015.09.22 15:58:58 3: DbLog logdb: reduceLog deleting 6153 records of day: 2015-04-04
2015.09.22 15:59:06 3: DbLog logdb: reduceLog (hourly-average) updating 232 records of day: 2015-04-04
2015.09.22 15:59:08 3: DbLog logdb: reduceLog (daily-average) updating 41, deleting 242 records of day: 2015-04-04
2015.09.22 15:59:09 3: DbLog logdb: reduceLog deleting 8836 records of day: 2015-04-05
2015.09.22 15:59:20 3: DbLog logdb: reduceLog (hourly-average) updating 247 records of day: 2015-04-05
2015.09.22 15:59:21 3: DbLog logdb: reduceLog (daily-average) updating 31, deleting 265 records of day: 2015-04-05
2015.09.22 15:59:24 3: DbLog logdb: reduceLog deleting 561 records of day: 2015-04-06
2015.09.22 15:59:25 3: DbLog logdb: reduceLog (hourly-average) updating 161 records of day: 2015-04-06
2015.09.22 15:59:25 3: DbLog logdb: reduceLog (daily-average) updating 19, deleting 166 records of day: 2015-04-06
Zitat von: C0mmanda am 22 September 2015, 15:56:56
Du kannst die Sache jetzt natürlich einfach aussitzen oder die Brechstange rausholen und fhem killen und neustarten.
Ob da was schiefgehen kann (DB kaputt oder sowas) weiß ich leider nicht. Bin mir nicht sicher....
Nein kann nicht wirklich was kaputt gehen,
reduceLog Ändert die DB erst wenn ein Tag vollständig verarbeitet ist.
Das einzige was passieren kann ist, das ein Tag an dem eigentlich eine hourly-'average' gesetzt werden soll einfach nur auf die ersten Einträge pro Stunde reduziert wurde (wie reduLog ohne average).
Das passiert dann wenn der Tag zwar schon vollständig aufgeräumt wurde, die hourly-average's allerding noch nicht vollständig auf den Tag angewendet wurden.
Zitat von: DrJJ am 22 September 2015, 16:02:29
Habe den Befehl in meiner Mysql DB ausgeführt. Index scheint erstellt zu sein. Die DB scheint laut log gerade Tageweise reduziert zu werden.
Schaut doch gut aus, man sieht dass du eine relativ große DB hattest, da das holen der Daten relativ lange dauerte.
Die reduzierung scheint von der Geschwindigkeit allerdings relativ OK zu sein, denke bei der Geschwindigkeit kann es allerdings trotzdem einige Minuten dauern bis reduceLog abgeschlossen ist.
Du kannst das log mit "tail -f fhem.log" folgen, damit du siehst wie es voran geht :)
Gruß
Claudiu
Vielen Dank euch beiden, es scheint immer noch zu laufen. Ich denke durch den Index ist die DB jetzt noch mal etwas größer geworden. Mal abwarten wie es sich entwickelt wenn alle Tage abgearbeitet wurde.
Das ist auch richtig so, steht meine ich auch in dem verlinkten Post.
Durch INDEX wird die DB um ca. ¼ größer.
So, habe noch den INDEX angelegt, ich musste mich aber erst einmal mit einer Fehlermeldung beim anlegen des Index auseinandersetzen.
Aber jetzt ist die Abfrage richtig flott geworden.
War vorher noch für eine Abfrage 5 Minuten notwendig sind es jetzt nur noch Bruchteile einer Sekunde.
2015.09.22 21:44:47 5: Cmd: >set myDbLog reduceLog 500 average<
2015.09.22 21:48:43 5: Triggering myDbLog (1 changes)
2015.09.22 21:48:43 5: Notify loop for myDbLog lastReduceLogResult: Rows processed: 126141, deleted: 106515, updated: 7962
Edit: 20 Tage Berechnet:
fhem> set myDbLog reduceLog 450 average
2015.09.22 23:55:48 3: DbLog myDbLog: reduceLog executed. Rows processed: 1022592, deleted: 835458, updated: 40651
2015.09.22 23:55:52 1: Perfmon: possible freeze starting at 23:24:51, delay is 1861.974
So, habe mal ein
fhem>set myDbLog reduceLog 400 average
Da hat er 50 Tage bearbeitet und
2015.09.23 07:37:50 3: DbLog myDbLog: reduceLog requested.
2015.09.23 08:50:55 3: DbLog myDbLog: reduceLog executed. Rows processed: 2383469, deleted: 2009049, updated: 99942
2015.09.23 08:51:10 1: Perfmon: possible freeze starting at 07:37:51, delay is 4399.717
Ein wiederholter Aufruf bringt folgende Zeilen
2015.09.23 09:08:41 3: DbLog myDbLog: reduceLog requested.
2015.09.23 09:09:38 3: DbLog myDbLog: reduceLog executed. Rows processed: 374410, deleted: 0, updated: 0
2015.09.23 09:09:40 1: Perfmon: possible freeze starting at 09:08:42, delay is 58.779
Bei jedem Aufruf war fhem blockiert.
Ich habe jetzt ca. 105 Tage mit average behandelt und knapp 4000000 Datensätze dabei gelöscht.
Hallo Stromer,
das war ja mal eine größere Bereinigung :)
Hast du zufällig den RAM, SWAP, CPU Verbrauch währenddessen beobachtet? (reduceLog liest i.M. die zu verarbeitenden Daten vor Beginn komplett in den RAM ein)
Gruß
Claudiu
Mysql lauft hier mit einer InnoDb Engine.
CPU lag so bei 110%
Swap stieg von 2MB auf 116MB an.
Wait lag so bei 3%
Gesendet von meinem GT-I9295
Hallo Stromer,
da habe ich direkt eine Frage: Ich plage mich auch gerade mit der Fehlermeldung beim Anlegen des Index. Wie hast du es behoben, ich komm da gerade nicht weiter.
Ich bin jedenfalls schon gespannt wie schnell das Teil auf meinem Raspberry mit dem Index dann laufen wird...
Danke und vg
Der Fehler ist etwas irritierent, da angeblich die Datenbank voll ist.
Es liegt am tmp-Verszeichnis, welches beim Cubie in der RAM liegt und maximal 1GB Platz hat.
Ich habe ein tmp-Verzeichnis mit entsprechenden Berechtigungen auf meiner SSD angelegt und in der my.cnf angepasst.
von
tmpdir = /tmp
nach
tmpdir = /opt/tmp
Nach dem erstellen des Index habe ich es wieder zurückgeändert.
Bei den 35,5Millionen Datensätzen hat es knapp 39Minuten gedauert.
mysql> CREATE INDEX index_reduceLog ON history (TIMESTAMP,DEVICE,EVENT);
Query OK, 0 rows affected, 2 warnings (38 min 34.58 sec)
Records: 0 Duplicates: 0 Warnings: 2
Hallo Zusammen,
keine Ahnung was mich dazu geritten hat einen eigenen INDEX zu erstellen... ;D
Hab die Funktion nochmals umgebaut damit KEIN zusätzlicher INDEX mehr benötigt wird !
Es wird nun der standard 'Search_Idx' INDEX welcher durch die *.sql Dateien für die DbLog Erstellung erstellt wird verwendet.
Dieser sollte bereits bei jedem vorhanden sein!
Vorsichtshalber kann man kontrollieren ob der 'Search_Idx' INDEX über die Columns (DEVICE, READING, TIMESTAMP) vorhanden ist.
sqlite> PRAGMA INDEX_LIST('history');
-----
mysql> SHOW INDEXES FROM history;
Die Verarbeitungszeit sollte hierdurch (wenn überhaupt) nur minimal in Mitleidenschaft gezogen werden, der RAM Ressourcenverbrauch sollte sich allerdings verringert haben.
Für Leute die den 'index_ruduceLog' erstellt haben, dieser kann mit folgendem Befehl wieder gelöscht werden. (Der belegte Speicherplatz wird hierdurch ebenfalls wieder freigegeben.)
sqlite> DROP INDEX index_reduceLog;
----
mysql> DROP INDEX index_reduceLog ON history;
Die Aktualisierte Version ist wieder in Post #28 zu finden => http://forum.fhem.de/index.php/topic,41089.msg334617.html#msg334617
________
Werde bei Gelegenheit noch ein weiteres Feature einbauen, welches insbesondere Leuten wie @stromer-12 zugute kommt welche bereits eine relativ große DB haben.
Hierdurch soll dann der Anfangsdelay deutlich verkürzt werden, indem Daten welche bereits verarbeitet wurden nicht erneut geprüft werden.
Gruß
Claudiu
Habe gerade noch mal nach dem RAM Bedarf meiner Fheminstanz geschaut, der lag jetzt noch 850MB.
Bevor ich es zitiere :) => http://learn.perl.org/faq/perlfaq3.html#How-can-I-free-an-array-or-hash-so-my-program-shrinks
Kurz gesagt, der durch reduceLog verwendete Speicher wird intern für den Fhem-Prozess wieder freigegeben, für das OS unter umständen allerdings nicht. (erst nach einem Fhem-restart.)
Durch das geplante Feature was ich vorhin erwähnte sollte aber zukünftig zumindest der RAM-Verbrauch der Funktion deutlich reduziert werden, da nurnoch Daten aus der DB gelesen werden, welche noch nicht verarbeitet wurden.
Gruß
Claudiu
Hallo Claudiu
Zitat von: rapster am 23 September 2015, 22:30:39
keine Ahnung was mich dazu geritten hat einen eigenen INDEX zu erstellen... ;D
Das habe ich mich auf gefragt! ;D
Zitat von: rapster am 23 September 2015, 22:30:39
Hab die Funktion nochmals umgebaut damit KEIN zusätzlicher INDEX mehr benötigt wird !
Es wird nun der standard 'Search_Idx' INDEX welcher durch die *.sql Dateien für die DbLog Erstellung erstellt wird verwendet.
Dieser sollte bereits bei jedem vorhanden sein!
Na Gott-sei-Dank!
Ich versuche nun schon seit 3 Tagen diesen verdammten Index anzulegen und bin immer wieder gescheitert! >:(
Dann werde ich mal die neuste Version versuchen. :)
Magst Du nochmal eine kurze Erklärung über alle möglichen Optionen der fhem.cfg Definitionen geben? ::)
Danke
Sailor
Zitat von: Sailor am 24 September 2015, 07:20:01
Ich versuche nun schon seit 3 Tagen diesen verdammten Index anzulegen und bin immer wieder gescheitert! >:(
...
Magst Du nochmal eine kurze Erklärung über alle möglichen Optionen der fhem.cfg Definitionen geben? ::)
Mensch hättst halt früher was gesagt, hatte das seit der ersten Version "auf die schnelle" so eingebaut und mir erst jetzt als die ersten zwei Leute Probleme beim Einrichten hatten Gedanken darüber gemacht ob das überhaupt so optimal ist...
An der Definition von DbLog selber hat sich nichts geändert, das einzige was dazu gekommen ist, ist das Set-Kommando"reduceLog".
In diesem Post hab ich die verschiedenen reduceLog Parameter (mit Beispielen) erklärt => http://forum.fhem.de/index.php/topic,41089.msg334617.html#msg334617
Ausgeführt werden muss der Befehl immer manuell, oder durch ein at o.ä. getriggert.
Gruß
Claudiu
Sehr schöne Sache! Vielen Dank für die Umsetzung!
Ich bin grade beim "Großreinemachen". Meine MySQL-Datenbank liegt auf einem schnarchlangsamen Server (ReadyNAS), von daher dauert alles etwas länger. Dazu kommt die relativ hohe Datenmenge, die den Speicherbedarf auf dem fhem-Rechner (Raspi2) offenbar hoch treibt. Ich reduziere daher jetzt in 5-Tages-Blöcken und starte zwischendurch neu. Hier mal ein Logauszug:
2015.09.24 11:24:38 3: DbLog DBLOG1: reduceLog deleting 3102 records of day: 2015-06-15
2015.09.24 11:24:55 3: DbLog DBLOG1: reduceLog (hourly-average) updating 56 records of day: 2015-06-15
2015.09.24 11:25:01 3: DbLog DBLOG1: reduceLog deleting 33753 records of day: 2015-06-16
2015.09.24 11:26:32 3: DbLog DBLOG1: reduceLog (hourly-average) updating 661 records of day: 2015-06-16
2015.09.24 11:26:41 3: DbLog DBLOG1: reduceLog deleting 57814 records of day: 2015-06-17
2015.09.24 11:30:39 3: DbLog DBLOG1: reduceLog (hourly-average) updating 1188 records of day: 2015-06-17
2015.09.24 11:30:52 3: DbLog DBLOG1: reduceLog deleting 56771 records of day: 2015-06-18
2015.09.24 11:33:52 3: DbLog DBLOG1: reduceLog (hourly-average) updating 1608 records of day: 2015-06-18
2015.09.24 11:34:20 3: DbLog DBLOG1: reduceLog deleting 56736 records of day: 2015-06-19
2015.09.24 11:36:40 3: DbLog DBLOG1: reduceLog (hourly-average) updating 1158 records of day: 2015-06-19
2015.09.24 11:36:50 3: DbLog DBLOG1: reduceLog deleting 55551 records of day: 2015-06-20
2015.09.24 11:39:09 3: DbLog DBLOG1: reduceLog (hourly-average) updating 1108 records of day: 2015-06-20
2015.09.24 11:39:16 3: DbLog DBLOG1: reduceLog executed. Rows processed: 1043911, deleted: 263727, updated: 5779
[..]
2015.09.24 11:39:25 1: Cannot fork: Nicht genügend Hauptspeicher verfügbar
Hallo Claudiu
Zitat von: rapster am 24 September 2015, 09:33:32
An der Definition von DbLog selber hat sich nichts geändert, das einzige was dazu gekommen ist, ist das Set-Kommando"reduceLog".
In diesem Post hab ich die verschiedenen reduceLog Parameter (mit Beispielen) erklärt => http://forum.fhem.de/index.php/topic,41089.msg334617.html#msg334617
Habe vorhin mal den Befehl
set myDbLog reduceLog 30 average
eingegeben und schwupps war mein fhem abgestürzt...
Ich mache mich heute Abend mal auf die Suche da im Augenblick keine Zeit für die Fehlersuche...
Gruß
Sailor
@nesges: Denke wenn dann erstmal eine gewisse Grundreinigung durch ist, und du es evtl. täglich startest sollte das auch unproblematischer sein ;)
Allerdings werden i.M. auch bereits bearbeitete Daten in den RAM gelesen, das will ich noch ändern...
@Sailor: Abgestürzt oder blockiert? Das Fhem während der ausführung blockiert ist, ist normal. Falls wirklich abgestürzt, was tauchte zuletzt im Log auf?
Gruß
Claudiu
Hallo Claudiu
Zitat von: rapster am 24 September 2015, 12:17:57
@Sailor: Abgestürzt oder blockiert? Das Fhem während der ausführung blockiert ist, ist normal. Falls wirklich abgestürzt, was tauchte zuletzt im Log auf?
OK Habe
set myDbLog reduceLog 360 average
gestartet...
CPU auf 100%
RAM nach 10s auf 100%
:o
pi@DeekeHomeServer /opt/fhem $ htop
CPU[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||100.0%] Tasks: 28, 5 thr; 2 running
Mem[||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||70/434MB] Load average: 0.96 0.61 0.36
Swp[||||| 4/99MB] Uptime: 7 days, 18:01:46
PID USER PRI NI VIRT RES SHR S CPU% MEM% TIME+ Command
3323 fhem 20 0 59892 53552 7440 R 93.0 12.0 17:23.73 perl fhem.pl fhem.cfg
7467 pi 20 0 5432 2944 1964 R 4.0 0.7 0:08.92 htop
Schau mer mal... Ich harre noch der Dinge.
Die fhem.db ist immerhin 3,8GB gross!
Gruss
Sailor
Hallo Sailor,
100% CPU ist auf jedenfall OK, 500MB RAM ist zwar etwas wenig, sollte aber hoffe ich trotzdem alles gut gehen :-)
Mach mal ein "tail -f /opt/fhem/fhem.log" auf den Commandline und schau mal was er gerade tut....
Gruß
Claudiu
Zitat von: rapster am 24 September 2015, 14:50:39
100% CPU ist auf jedenfall OK, 500MB RAM ist zwar etwas wenig, sollte aber hoffe ich trotzdem alles gut gehen :-)
Mach mal ein "tail -f /opt/fhem/fhem.log" auf den Commandline und schau mal was er gerade tut....
Schau mer mal...
2015.09.24 14:41:09 3: DbLog myDbLog: reduceLog requested.
Da muss auf alle Faelle 'ne Forke her! ;)
Gruss
Sailor
Zitat von: rapster am 24 September 2015, 14:50:39
100% CPU ist auf jedenfall OK, 500MB RAM ist zwar etwas wenig, sollte aber hoffe ich trotzdem alles gut gehen :-)
Mach mal ein "tail -f /opt/fhem/fhem.log" auf den Commandline und schau mal was er gerade tut....
Schau mer mal...
2015.09.24 14:41:09 3: DbLog myDbLog: reduceLog requested.
2015.09.24 14:57:08 3: DbLog myDbLog: reduceLog executed. Rows processed: 0, deleted: 0, updated: 0
Naechster Versuch:
set myDbLog reduceLog 150 average
Da muss auf alle Faelle 'ne Forke her! ;)
Gruss
Sailor
Oha, ja bei dir ist er immer noch mit dem Einlesen der DB beschäftigt.
reduceLog liest i.M. die kompletten zu verarbeitenden Tage zuvor in den RAM ein, allerdings ist bei dir grad nicht viel RAM verfügbar... :-\
Wieviel Tage umfasst deine DB?
Du kannst es nur mal mit mehr <days> versuchen, damit nicht so viel auf einmal eingelesen werden muss.
Oder mal warten... Bin gespannt!
Das auslagern in einen eigenen Prozess ist schwierig, da SQLITE bei vielen Usern keine mehrfachen Verbindungen unterstützt.
Gruß
Claudiu
EDIT:
sehe gerade bei 360 kam kein Ergebniss zurück, anscheinend hat die DB noch nicht soviele Tage gespeichert, und die dauer ist auf die select-Abfrage zurückzuführen.
Was kam bei 150 raus?
Zitat von: rapster am 24 September 2015, 15:03:44
Oha, ja bei dir ist er immer noch mit dem Einlesen der DB beschäftigt.
reduceLog liest i.M. die kompletten zu verarbeitenden Tage zuvor in den RAM ein, allerdings ist bei dir grad nicht viel RAM verfügbar... :-\
Wieviel Tage umfasst deine DB?
Du kannst es nur mal mit mehr <days> versuchen, damit nicht so viel auf einmal eingelesen werden muss.
Oder mal warten... Bin gespannt!
Ist halt nur ein RasPI-B und der fhem-Prozess ist wieder abgeschmiert.
set myDbLog reduceLog 360 average
2015.09.24 14:41:09 3: DbLog myDbLog: reduceLog requested.
2015.09.24 14:57:08 3: DbLog myDbLog: reduceLog executed. Rows processed: 0, deleted: 0, updated: 0
set myDbLog reduceLog 150 average
2015.09.24 15:01:07 3: DbLog myDbLog: reduceLog requested.
Absturz
Vorher war sogar das SWAP-file randvoll...
Hmmm
Wie bekomme ich nochmal die Anzahl der gespeicherten Tage raus?
Gruss
Sailor
Zitat von: Sailor am 24 September 2015, 15:20:46
Vorher war sogar das SWAP-file randvoll...
Das ist auch das Problem, reduceLog versucht die Daten in den RAM einzulesen, falls der nicht ausreicht wird das SWAP-File herangezogen, dieses hat allerdings auf deinem System nur bescheidene 100 MB :)
Den ältestens Eintrag in der DB bekommst du mit diesem SQL Command:
select * from history ORDER BY TIMESTAMP ASC LIMIT 1;
Gruß
Claudiu
Zitat von: Sailor am 24 September 2015, 15:20:46
Wie bekomme ich nochmal die Anzahl der gespeicherten Tage raus?
select count(distinct(date_format(timestamp,"%Y-%m-%d"))) from history;
Wenn du nur den ersten gelogten Timestamp wissen möchtest:
select min(timestamp) from history;
Ich habe mal eine generelle Frage zu diesem Projekt: Werden hier einfach alle geloggten Werte auf einen in der Stunde gekürzt? Das wäre für mein Vorhaben etwas unpassend. Zwar habe ich auch Daten die ich ausdünnen möchte, eben diese Temperaturverläufe usw, allerdings habe ich auch Daten die ich komplett speichern möchte. In meinem Fall die Ein und Aus Werte der Brunnenpumpe. Oder aber auch der Fenster.
Zitat von: th1984 am 25 September 2015, 08:20:42
Ich habe mal eine generelle Frage zu diesem Projekt: Werden hier einfach alle geloggten Werte auf einen in der Stunde gekürzt? Das wäre für mein Vorhaben etwas unpassend. Zwar habe ich auch Daten die ich ausdünnen möchte, eben diese Temperaturverläufe usw, allerdings habe ich auch Daten die ich komplett speichern möchte. In meinem Fall die Ein und Aus Werte der Brunnenpumpe. Oder aber auch der Fenster.
Stimmt, daran habe ich auch noch nicht nachgedacht.
Wenn ich das Fenster einmal am Tag geöffnet habe, kann der Average nicht "Halb geöffnet" sein. ;D
Gruss
Sailor
Zitat von: th1984 am 25 September 2015, 08:20:42
Ich habe mal eine generelle Frage zu diesem Projekt: Werden hier einfach alle geloggten Werte auf einen in der Stunde gekürzt? Das wäre für mein Vorhaben etwas unpassend. Zwar habe ich auch Daten die ich ausdünnen möchte, eben diese Temperaturverläufe usw, allerdings habe ich auch Daten die ich komplett speichern möchte. In meinem Fall die Ein und Aus Werte der Brunnenpumpe. Oder aber auch der Fenster.
Ja, daran hab ich zwar auch am Anfang schon gedacht.
Alphanumerische Zeichen werden i.M. immer auf den ersten Eintrag pro Stunde reduziert (auch bei average=day).
Bei mir hat es dadurch z.B. die Fensterzustände, oder on/off Werte anderer Aktoren in den Plots zwar etwas ungenauer gemacht, aber empfand es jetzt als ganz O.K.
Ich könnte noch einen FILTER einbauen, um z.B. komplett alphanumerisch auszlassen, oder um device/reading kombinationen auszuschließen, würde das helfen?
Gruß
Claudiu
Hallo Claudiu,
ZitatIch könnte noch einen FILTER einbauen, um z.B. komplett alphanumerisch auszlassen, oder um device/reading kombinationen auszuschließen, würde das helfen?
Das wäre super wenn man ein Opt-Out machen könnte. Ich denke das wäre auch die Variante die besser ist, als wenn man alphanumerische Zeichen komplett auslässt. Ein anderer möchte womöglich genau diese reduziert.
Zitat von: rapster am 25 September 2015, 13:00:50Ich könnte noch einen FILTER einbauen, um z.B. komplett alphanumerisch auszlassen, oder um device/reading kombinationen auszuschließen, würde das helfen?
Evtl. ein Attribute ähnlich dem "DbLogExclude" mit dem man Ausnahmen von deiner Erweiterung festlegen kann.
Für mich würde auch eine Option average=min zur Reduzierung auf minütlichen Durchschnittswert Sinn ergeben. Da ich insbesondere dewpoint nicht verbieten möchte im Sekundentakt Events zu erzeugen (da ich eine sekundengenaue Anzeige behalten möchte), die Vielzahl der Werte aber später in den Plots gar nicht mehr benötige - bzw. sogar störend finde, da sie die Plots ausbremsen. Die Detailstufe average=hour ist mir für die tagesaktuellen Werte dann aber auch wieder zu grob.
Hallo Zusammen,
als letztes Argument kann nun "EXCLUDE=deviceRegExp1:readingRegExp1,deviceRegExp2:readingRegExp2,...." angegeben werden um device:reading Kombinationen (mehrere durch Komma getrennt) von reduceLog auszuschließen.
z.B. "set <dblog> reduceLog <days> average exclude=haustuer:state,katzenkl.*:.*,.*:sabotageError"
Die einzelnen RegEx Pattern müssen immer aufs gesamte device und reading matchen, nicht nur teile davon!
@nesges
average reicht dir hier nicht? Damit hast du dann 24 Werte pro Tag...
Verstehe ehrlich gesagt nicht für was du in den Plots bei historischen Werten was genaueres benötigst als einen Wert pro Stunde?
@Sailor
Habe die Funktion nochmal bzql. der Datenverarbeitung umgebaut.
Der RAM-Verbrauch sollte nun (hoffe ich) nicht mehr auffallen.
Kannst du das bitte mal testen und bescheid geben ob dein FHEM nun bei einer größeren Abfrage durchhält?
Die Aktualisierte Version ist wieder in Post #28 zu finden => http://forum.fhem.de/index.php/topic,41089.msg334617.html#msg334617
Gruß
Claudiu
Moin Claudiu,
durch Deine Version von Heute morgen hat mein BPi es erstmals geschafft, eine Test DB mit 596 MB (625.651.712 Bytes) ohne das FHEM "weggeschossen" wird, in einem "Rutsch" zu verarbeiten. 8)
2015.09.26 03:44:17.051 3: DbLog myDbLog: reduceLog requested.
2015.09.26 04:01:01.385 3: DbLog myDbLog: reduceLog deleting 162415 records of day: 2015-09-02
2015.09.26 04:05:33.640 3: DbLog myDbLog: reduceLog executed. Rows processed: 3096278, deleted: 2653331
2015.09.26 04:28:22.534 3: DbLog myDbLog: reduceLog requested.
2015.09.26 04:28:36.617 3: DbLog myDbLog: reduceLog (daily-average) updating 25, deleting 328 records of day: 2015-05-30
2015.09.26 04:28:36.859 3: DbLog myDbLog: reduceLog (daily-average) updating 25, deleting 547 records of day: 2015-05-31
2015.09.26 04:28:37.186 3: DbLog myDbLog: reduceLog (daily-average) updating 55, deleting 510 records of day: 2015-06-01
2015.09.26 04:28:37.718 3: DbLog myDbLog: reduceLog (daily-average) updating 68, deleting 1072 records of day: 2015-06-02
2015.09.26 04:31:06.732 3: DbLog myDbLog: reduceLog (hourly-average) updating 18 records of day: 2015-09-02
2015.09.26 04:31:11.586 3: DbLog myDbLog: reduceLog executed. Rows processed: 432965, deleted: 287404, updated: 20187
Schade, das Du nicht den Sinn siehst, für z.B. Temperatur-Daten die Möglichkeit für 1 Minute, 5 Minuten oder 15 Minuten Intervalle "ein zubauen". :'(
( Ich weiß, allerdings auch nicht, wie viel Arbeit dahinter steckt, bzw. ob dies überhaupt Möglich ist.. )
Ich würde mich sehr darüber freuen...
Aber wenn es nicht geht, ist es auch so Klasse, was Du da "gebaut" hast. Und andere daran Teilhaben lässt! ( sehr 8) )
Vielen Dank & viele Grüße
Sunny
Hi Sunny,
super, dann hat das geklappt!
Müsste denke ich jetzt auch bei @Sailor funktionieren :)
Möglich ist ja erstmal so ziemlich alles ;)
Werde mir mal Gedanken drüber machen wie sich das am besten einbauen lässt, denke da an sowas wie "average=min=<mins>", und falls mir was gutes einfällt bei Gelegenheit einbauen :)
Hab grad nochmal eine kleines Update eingebaut, hauptsächlich bisschen aufgeräumt und die Log-Meldungen etwas erweitert...
2015.09.26 17:23:25.388 3: DbLog dbLog: reduceLog requested with DAYS=5, AVERAGE=HOUR, EXCLUDE=.*:.*
2015.09.26 17:23:32.588 3: DbLog dbLog: reduceLog executed. Rows processed: 603562, deleted: 0, updated: 0, excluded: 603562, time: 7.20sec
Gruß
Claudiu
Moin Claudiu,
Zitat von: rapster am 26 September 2015, 16:11:52
Müsste denke ich jetzt auch bei @Sailor funktionieren :)
Hatte per "htop" aber durchgängig mehr als 450 MB Speicherbelegung bei 100% Prozessorlast...
Zitat von: rapster am 26 September 2015, 16:11:52
Möglich ist ja erstmal so ziemlich alles ;)
Werde mir mal Gedanken drüber machen wie sich das am besten einbauen lässt, denke da an sowas wie "average=min=<mins>", und falls mir was gutes einfällt bei Gelegenheit einbauen :)
Das klingt ja Klasse! ;D
Falls Du etwas getestet haben möchtest ...
Vielen Dank & viele Grüße
Sunny
Zitat von: Sunny am 26 September 2015, 16:24:41
Hatte per "htop" aber durchgängig mehr als 450 MB Speicherbelegung bei 100% Prozessorlast...
Wie hoch war die Speicherbelegung vor reduceLog?
Wichtig wäre mit der neuen Version ebenfalls von wem der Speicher verbraucht wurde,
da jetzt die Datenbank-Seite das Ergebniss buffern sollte, und die Perl-Seite (fhem) eigentlich nur zusätzlichen Speicher für etwa 2x alle Zeilen des gerade zu bearbeitenden Tages benötigt.
Die CPU wird allerdings immer auf 100% laufen, egal wie groß die auch ausfällt, reducLog will ja schnellstmöglich fertig werden ;D
Gruß
Claudiu
Moin Claudiu,
Zitat von: rapster am 26 September 2015, 17:37:39
Die CPU wird allerdings immer auf 100% laufen, egal wie groß die auch ausfällt, reducLog will ja schnellstmöglich fertig werden ;D
Ist ja auch besser so... ;)
Hier mal Ausgaben der letzten Version:
2015.09.26 17:29:41.016 3: DbLog sysDb: reduceLog requested.
2015.09.26 17:29:50.317 3: DbLog sysDb: reduceLog executed. Rows processed: 27841, deleted: 26012, time: 9.00sec
2015.09.26 17:29:50.344 2: DbLog_sysDb_log_di: set sysDb reduceLog 1: reduceLog executed. Rows processed: 27841, deleted: 26012, time: 9.00sec
2015.09.26 17:30:50.016 3: DbLog myDbLog: reduceLog requested.
2015.09.26 17:30:50.440 3: DbLog myDbLog: reduceLog executed. Rows processed: 1551, deleted: 798, time: 0.00sec
2015.09.26 17:30:50.457 2: DbLog_sysDb_log_di: set myDbLog reduceLog 1: reduceLog executed. Rows processed: 1551, deleted: 798, time: 0.00sec
Zitat von: rapster am 26 September 2015, 17:37:39
Wie hoch war die Speicherbelegung vor reduceLog?
Siehe Bild im Anhang.
Zitat von: rapster am 26 September 2015, 17:37:39
Wichtig wäre mit der neuen Version ebenfalls von wem der Speicher verbraucht wurde,
da jetzt die Datenbank-Seite das Ergebniss buffern sollte, und die Perl-Seite (fhem) eigentlich nur zusätzlichen Speicher für etwa 2x alle Zeilen des gerade zu bearbeitenden Tages benötigt.
Kann ich später nochmal testen, gib es eine Möglichkeit, dieses "Mitzuschneiden" ?
(Sorry, bin noch Linux "beginner"... :-[ )
Oder willst Du ein paar Screenshots?
<OT an> Muss jetzt erstmal noch etwas zu beißen "jagen"... ;) <OT aus>
Viele Grüße & bis später
Sunny
Hi Sunny,
reduceLog scheint bei dir i.M. 2x ausgeführt zu werden, entweder nach absetzen des Befehls in Fhem die Browser-Seite schließen, oder direkt über Telnet den Befehl absetzen.
Da sonst der Browser den Befehl aufgrund der Wartezeit evtl. doppelt sendet.
Als einfache Möglichkeit könntest du mal diesen Shell Befehl vor und während der Ausführung von reduceLog ausführen und die Ergebnisse mal posten (Fhem davor bitte 1x neustarten):
ps aux | grep "fhe[m].pl\|mysq[l]"
Die Grep Suchpattern mit den richtigen Namen deiner Prozesse ersetzen...
Gruß
Claudiu
Juten Abend Claudiu,
Zitat von: rapster am 26 September 2015, 18:29:05
reduceLog scheint bei dir i.M. 2x ausgeführt zu werden...
Jupp, sind zwei Datenbanken, die per Dummy, Doif und at aufgerufen werden können.
( Bild im Anhang )
Eine für Systemnahe Daten und eine für meine Sensordaten. ;)
Daher passt das schon, mit dem grep muss ich wohl noch mal schauen, wie das genau funzt. :-[
Lang Dir das mit den jetzigen Daten oder lieber wieder mit der größeren "Test-DB" ?
Viele Grüße
Sunny
PS: Teste im Moment nur mit dem BPi (legacy(Debian 7/Wheezy) version: 15.04), die RPi's sind vom Linux ein bißchen abgespeckt.
Stimmt, in deinem Log sind ja auch 2 verschiedene definition-Namen, dann passt das natürlich :)
Das ps aux kann man auch jeweils mit 2 Befehlen vor und während der Ausführung machen
ps aux | grep "fhe[m].pl"
ps aux | grep "nameDeinesMySqlProzesses"
das Grep soll nur die Ausgabe von "ps aux" filtern, damit nicht alle deine Prozesse ausgegeben werden :)
Von der Datenmenge her kommts drauf an, ob es zumindest so viele Daten sind damit man bisschen was erkennen kann, dann reichts ;)
Allerdings ist das ganze ja mehr informativ, also nicht so schlimm, viel Aufwand brauchst du da jetzt nicht betreiben!
Gruß
Claudiu
Juten Abend Claudiu,
Zitat von: rapster am 26 September 2015, 20:10:37
Stimmt, in deinem Log sind ja auch 2 verschiedene definition-Namen, dann passt das natürlich :)
Tja, so ist das manchmal mit dem lesen. ;)
habe gerade mal ohne "Neustart" dieses:
ps aux | grep "fhe[m].pl\|myDbLog[l]"
eingegeben und dies:
root@BPiServer:~# ps aux | grep "fhe[m].pl\|myDbLog[l]"
fhem 1987 0.8 4.3 47196 43444 ? S 16:28 1:47 perl fhem.pl fhem.cfg
fhem 7840 0.1 4.0 47196 40688 ? S 20:08 0:00 perl fhem.pl fhem.cfg
root@BPiServer:~#
wurde ausgegeben.
Entspricht das in etwa dem, was Du sehen möchtest...
Du warst schneller... Teste ich auch gleich mal.
Viele Grüße
Sunny
<EDIT an>
Dies:
ps aux | grep "fhe[m].pl"
ps aux | grep "myDbLog"
ergibt ohne "Neustart", das:
root@BPiServer:~# ps aux | grep "fhe[m].pl"
fhem 1987 0.7 4.3 47196 43444 ? S 16:28 1:50 perl fhem.pl fhem.cfg
fhem 8115 0.4 4.0 47196 40580 ? S 20:19 0:00 perl fhem.pl fhem.cfg
root@BPiServer:~# ps aux | grep "myDbLog"
root 8119 0.0 0.0 3720 744 pts/0 S+ 20:19 0:00 grep myDbLog
root@BPiServer:~#
Ach so, soll ich es als "root" oder als "user" aufrufen?
<EDIT ist aus>
Nochmals Grüße & Danke
Sunny
Hi Sunny,
fast,
das "myDbLog[l]" ist deine Fhem-Devicename, hier muss der Name des Linux-Prozess deiner SQL-Datenbak rein.
in der Ausgabe erkennt man jetzt z.B. das die PID 1987 (dein FHEM) ~47MB Virtuel-Memory und eine ~43MB Resident Set Size hat.
Jetzt noch irgendwie den Memory Verbrauch deiner SQL-Datenbak dann kann man das mit dem Daten während reduceLog vergleichen :)
Hat es einen Grund warum du fhem 2x gestartet hast? (Evtl. kommt das aber auch durch irgend ein Modul...)
Gruß
Claudiu
EDIT ;)
root@BPiServer:~# ps aux | grep "myDbLog"
root 8119 0.0 0.0 3720 744 pts/0 S+ 20:19 0:00 grep myDbLog
gibt grad den grep-Prozess selber aus, dies kann man durch eine suche wie nach der fhem.pl verhindern in dem man einen beliebigen Buchstaben in [] setzt.
Also so z.B.: ps aux | grep "my[D]bLog"
Jetzt muss nurnoch der Name des Linux Prozess da rein :)
Nabend Claudiu,
Zitat von: rapster am 26 September 2015, 20:25:32
Hat es einen Grund warum du fhem 2x gestartet hast? (Evtl. kommt das aber auch durch irgend ein Modul...)
Habe es nicht bewusst 2x gestartet.
Liegt es an "FHEM2FHEM"
Fhem info:
Release : 5.6
OS : linux
Arch : arm-linux-gnueabihf-thread-multi-64int
Perl : v5.14.2
uniqueID : 0a012df4a0cb2361b1ac081c61a5f836
upTime : 03:58:10
Defined modules:
CUL : 1
CUL_TCM97001 : 1
DOIF : 3
DbLog : 2
FBAHA : 2
FBDECT : 7
FHEMWEB : 3
FRITZBOX : 3
FileLog : 3
IT : 21
PROPLANTA : 1
SVG : 15
SYSMON : 1
Twilight : 1
Weather : 1
at : 9
autocreate : 1
dummy : 2
eventTypes : 1
holiday : 1
notify : 4
readingsGroup : 1
telnet : 1
weblink : 1
Defined models per module:
CUL : CUL
CUL_TCM97001 : TCM97...
FBDECT : Dect200,Powerline546E
IT : itswitch
?
Meinst Du mit:
Zitat von: rapster am 26 September 2015, 20:25:32
Jetzt noch irgendwie den Memory Verbrauch deiner SQL-Datenbak dann kann man das mit dem Daten während reduceLog vergleichen :)
die Größe der "fhem.db" (myDbLog-File) werden dann "596 MB (625.651.712 Bytes)".
Hoffe ich verstehe Dich richtig...
Vielen Dank
Sunny
Warum es 2x gestartet ist kann ich leider nicht sagen, fhem2fhem setze ich selber nicht ein :-\
verwendest du SQLITE? Dann hast du keinen zusätzlichen prozess die ene ps aux abfrage reicht aus :)
Gruß
Claudiu
Zitat von: rapster am 26 September 2015, 20:51:47
verwendest du SQLITE? Dann hast du keinen zusätzlichen prozess die ene ps aux abfrage reicht aus :)
Ja, verwende ich.
Meinst Du:
2015.09.26 20:51:02.545 3: Connection to db SQLite:dbname=/opt/fhem/fhem.db established for pid 8813
2015.09.26 20:51:02.555 3: Connection to db SQLite:dbname=/opt/fhem/fhem.db established
2015.09.26 20:51:02.567 3: Connecting to database SQLite:dbname=/opt/fhem/sys.db with user
2015.09.26 20:51:02.571 3: Connection to db SQLite:dbname=/opt/fhem/sys.db established for pid 8813
2015.09.26 20:51:02.581 3: Connection to db SQLite:dbname=/opt/fhem/sys.db established
Das ich dann "pid 8813" eingeben soll ?
Danke für Deine Geduld
Sunny
Ne, SQLITE hat keinen eigenen Linux Prozess, dachte schon fast ich bin hier der einzige im Thread der SQLITE verwendet :D
also einfach einmal
root@BPiServer:~# ps aux | grep "fhe[m].pl"
vor, und einmal während reduceLog ausgeführt wird :)
Gruß
Claudiu
So, der Test läuft. Bpi ist Neugestartet.
Vorher:
countCurrent 0 2015-09-26 21:15:53
countHistory 3096306 2015-09-26 21:15:53
ps aux | grep "fhe[m].pl"
root@BPiServer:~# ps aux | grep "fhe[m].pl"
fhem 1983 4.2 3.6 40324 36492 ? S 21:11 0:13 perl fhem.pl fhem.cfg
Und während:
root@BPiServer:~# ps aux | grep "fhe[m].pl"
fhem 1983 6.7 8.8 91676 87972 ? R 21:11 0:27 perl fhem.pl fhem.cfg
root@BPiServer:~# ps aux | grep "fhe[m].pl"
fhem 1983 15.6 28.5 287036 283292 ? R 21:11 1:10 perl fhem.pl fhem.cfg
root@BPiServer:~# ps aux | grep "fhe[m].pl"
fhem 1983 34.2 42.6 427384 423676 ? R 21:11 3:20 perl fhem.pl fhem.cfg
root@BPiServer:~# ps aux | grep "fhe[m].pl"
fhem 1983 36.0 42.6 427480 423772 ? R 21:11 3:37 perl fhem.pl fhem.cfg
Und Sorry, hatte ja FHEM2FHEM vom BPi runter geschmissen und nur noch auf dem RPi.
Bin gerade nicht so voll konzentriert... :-[
Recht herzlichen Dank für Deine Geduld
Sunny
root@BPiServer:~# ps aux | grep "fhe[m].pl"
fhem 1983 47.9 42.7 428312 424604 ? R 21:11 6:12 perl fhem.pl fhem.cfg
So, mal von mir auch wieder was:
2015.09.26 21:26:52 3: DbLog myDbLog: reduceLog requested with DAYS=400, AVERAGE=HOUR
2015.09.26 21:27:56 3: DbLog myDbLog: reduceLog deleting 1941 records of day: 2014-08-18
2015.09.26 21:28:00 3: DbLog myDbLog: reduceLog (hourly-average) updating 107 records of day: 2014-08-18
2015.09.26 21:28:05 3: DbLog myDbLog: reduceLog deleting 48598 records of day: 2014-08-19
2015.09.26 21:29:27 3: DbLog myDbLog: reduceLog (hourly-average) updating 2647 records of day: 2014-08-19
2015.09.26 21:29:40 3: DbLog myDbLog: reduceLog deleting 47575 records of day: 2014-08-20
2015.09.26 21:31:02 3: DbLog myDbLog: reduceLog (hourly-average) updating 2639 records of day: 2014-08-20
2015.09.26 21:31:18 3: DbLog myDbLog: reduceLog deleting 46389 records of day: 2014-08-21
2015.09.26 21:32:43 3: DbLog myDbLog: reduceLog (hourly-average) updating 2488 records of day: 2014-08-21
2015.09.26 21:32:50 3: DbLog myDbLog: reduceLog executed. Rows processed: 532824, deleted: 144503, updated: 7881, time: 358.00sec
Vor reduceLog
root@cubietruck:~# ps aux | grep "fhe[m].pl\|mysq[l]"
root 2465 0.0 0.0 1420 124 ? S Sep22 0:00 /bin/sh /usr/bin/mysqld_safe
mysql 2883 6.8 7.3 318780 150888 ? Sl Sep22 390:44 /usr/sbin/mysqld .....
fhem 12628 0.0 0.6 31020 13632 ? S 01:12 0:58 /usr/bin/perl fhem.pl fhem2.cfg
fhem 12642 6.8 3.5 92048 71768 ? S 01:13 76:32 /usr/bin/perl fhem.pl fhem.cfg
Während reduceLog
root@cubietruck:~# ps aux | grep "fhe[m].pl\|mysq[l]"
root 2465 0.0 0.0 1420 124 ? S Sep22 0:00 /bin/sh /usr/bin/mysqld_safe
mysql 2883 6.8 7.3 318780 150916 ? Sl Sep22 396:00 /usr/sbin/mysqld ........
fhem 12628 0.1 4.2 105140 87768 ? R 01:12 2:07 /usr/bin/perl fhem.pl fhem2.cfg
fhem 12642 6.8 3.5 92048 71768 ? S 01:13 83:01 /usr/bin/perl fhem.pl fhem.cfg
Nach reduceLog
root@cubietruck:~# ps aux | grep "fhe[m].pl\|mysq[l]"
root 2465 0.0 0.0 1420 124 ? S Sep22 0:00 /bin/sh /usr/bin/mysqld_safe
mysql 2883 6.8 7.3 318780 150944 ? Sl Sep22 399:41 /usr/sbin/mysqld ......
fhem 12628 0.2 1.9 56792 39452 ? S 01:12 3:10 /usr/bin/perl fhem.pl fhem2.cfg
fhem 12642 6.8 3.5 92048 71768 ? S 01:13 83:23 /usr/bin/perl fhem.pl fhem.cfg
Hmm, da laufen auf jedenfall immer noch reichlich MB in den Perl-Prozess rein, sowohl bei SQLITE als auch bei Mysql.
Den Mysql Dienst selber scheint das ganze allerdings nicht weiter zu stören...
Könnte also immer noch sein dass eine große Bereinigung bei Systemen mit (zu) wenig RAM & SWAP die Stabilität beeinflussen kann.
Das einzige was mir dazu einfällt ist die Verarbeitung in kleinere Häppchen aufzuteilen, damit es jenige die es betrifft mit einem zusätzlichen Argument "separate=<days>" steuern können.
Mir fällt gerade nichts weiter ein wie ich ansonsten ram schonender vorgehen soll :-\
Werde mir mal Gedanken drüber machen.
Bitte bescheid geben falls bei jemanden mit der aktuellen Version der fhem-prozess sterben sollte.
Gruß
Claudiu
Zitat von: rapster am 26 September 2015, 16:11:52
super, dann hat das geklappt!
Müsste denke ich jetzt auch bei @Sailor funktionieren :)
Leider nein... :(
Habe seit dem 2015-02-09 13:29:49 insgesammt 3,28GB an Daten gesammelt.
Ich denke das wird nix mehr auf meinem kleinen RasPi... So wie es aussieht werde ich wohl einen Schnitt mit einer neuen Tabelle machen müssen und ab dann regelmaessig zum Monatsende einen ReduceLog fahren müssen. :(
Vielleicht auch einen Gelegenheit auf den RasPi2 mit 1GB RAM umzusteigen... ;D
Es sein denn ihr habt noch Ideen...
Zur Info: Ich habe 13 Raum-Thermostate, 15 Heizungsventile, einen Gaszähler, einen Stromzaehler und einen km200.
Die schreiben alle 2,5 Minuten eifrig Daten.
Gruss
Sailor
Hast du es probiert mit wenigen Tagen auf einmal, Sailor?
Du könntest das auch einmal mit einer Schleife erledingen, die z.b. immer nur 2 Tage auf einmal durchführt:
for (my $i = 500 ; $i > 31; $i = $i-2) {
fhem("set <dblog> reduceLog $i average");
}
Gruß
Claudiu
Zitat von: rapster am 28 September 2015, 12:55:37
Hast du es probiert mit wenigen Tagen auf einmal, Sailor?
Du könntest das auch einmal mit einer Schleife erledingen, die z.b. immer nur 2 Tage auf einmal durchführt:
for (my $i = 500 ; $i > 31; $i = $i-2) {
fhem("set <dblog> reduceLog $i average");
}
Gruß
Claudiu
Hallo Claudiu
Die Syntax stimmte in deinem Beispiel für das Kommandozeilenfenster nicht ganz...
Ich habe es mit
{for (my $i = 500 ;; $i > 31;; $i = $i-2) {fhem("set myDbLog reduceLog $i average exclude=.*_Window,.*_Door");;};;}
probiert.
Das Ergebnis im Log-File:
2015.09.28 14:06:11 3: DbLog myDbLog: reduceLog requested with DAYS=500, AVERAGE=HOUR
2015.09.28 14:22:47 3: DbLog myDbLog: reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 996.00sec
2015.09.28 14:22:48 3: set myDbLog reduceLog 500 average exclude=.*_Window,.*_Door : reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 996.00sec
2015.09.28 14:22:48 3: DbLog myDbLog: reduceLog requested with DAYS=498, AVERAGE=HOUR
2015.09.28 14:39:54 3: DbLog myDbLog: reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 1026.00sec
2015.09.28 14:39:55 3: set myDbLog reduceLog 498 average exclude=.*_Window,.*_Door : reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 1026.00sec
2015.09.28 14:39:55 3: DbLog myDbLog: reduceLog requested with DAYS=496, AVERAGE=HOUR
Na das kann dauern... Wird Zeit fürn Kaffee ::)
Gruß
Sailor
Bei deiner Zeit scheint kein Index zu greifen.
Bei meinen CT kommt aktuell:
fhem> set myDbLog reduceLog 500 average
reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 0.00sec
Zitat von: rapster am 26 September 2015, 01:56:52
@nesges
average reicht dir hier nicht? Damit hast du dann 24 Werte pro Tag...
Verstehe ehrlich gesagt nicht für was du in den Plots bei historischen Werten was genaueres benötigst als einen Wert pro Stunde?
Ich würde gerne Staffeln: Die letzten 24 Stunden volle Auflösung; die letzten 31 Tage minütlicher Durchschnitt; älter stündlicher Durchschnitt
Die "volle Auflösung" heisst bei einigen meiner Devices, dass 30-50 Werte pro Minute geloggt werden. Ich möchte das nicht unterbinden, da ich die sekundengenaue Liveanzeige behalten möchte, aber in den Plots ist diese Genauigkeit einfach nicht notwendig, von daher können die Werte raus. Ich erhoffe mir durch die Ausdünnung einen kleinen Performancegewinn, sehe das Feature aber auch nur als "nice to have" - bin auch ohne schon sehr zufrieden :-)
PS: Vielleicht kann der Thread auch mal in ein passenderes Subforum verschoben werden
Zitat von: stromer-12 am 28 September 2015, 14:33:17
Bei deiner Zeit scheint kein Index zu greifen.
Bei meinen CT kommt aktuell:
fhem> set myDbLog reduceLog 500 average
reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 0.00sec
Ja, war mein Fehler... Wie ich oben bereits schrieb fängt meine fhem.db erst im Februar diesen Jahres an...
Das heisst, das dauert noch bis der an die 180 Tage kommt. ???
Gruss
Sailor
Meine fhem.db fängt am 30. April letzten Jahres an.
Gesendet von meinem GT-I9295
Zitat von: nesges am 28 September 2015, 14:38:53
Ich würde gerne Staffeln: Die letzten 24 Stunden volle Auflösung; die letzten 31 Tage minütlicher Durchschnitt; älter stündlicher Durchschnitt
Die "volle Auflösung" heisst bei einigen meiner Devices, dass 30-50 Werte pro Minute geloggt werden. Ich möchte das nicht unterbinden, da ich die sekundengenaue Liveanzeige behalten möchte, aber in den Plots ist diese Genauigkeit einfach nicht notwendig, von daher können die Werte raus. Ich erhoffe mir durch die Ausdünnung einen kleinen Performancegewinn, sehe das Feature aber auch nur als "nice to have" - bin auch ohne schon sehr zufrieden :-)
PS: Vielleicht kann der Thread auch mal in ein passenderes Subforum verschoben werden
da hätte ich mir zum loggen schon mal ein extra userreading angelegt, dass dann entsprechend weniger events erzeugt (event-aggregator)
Zitat von: Sailor am 28 September 2015, 14:50:52
Ja, war mein Fehler... Wie ich oben bereits schrieb fängt meine fhem.db erst im Februar diesen Jahres an...
Das heisst, das dauert noch bis der an die 180 Tage kommt. ???
Oha ja, die "500" waren einfach mal Beispielhaft, am besten nochmal abbrechen mit mit ~180 nochmals starten
Gruß
Claudiu
EDIT:
Allerdings hat stromer recht, diese Abfrage dauert schon verdammt lange dafür das 0 Zeilen zurückgeliefert werden... Hmm.... Kommt evtl. von der Gesamtgröße der DB von ~4GB ?
Zitat von: nesges am 28 September 2015, 14:38:53
Die "volle Auflösung" heisst bei einigen meiner Devices, dass 30-50 Werte pro Minute geloggt werden. Ich möchte das nicht unterbinden, da ich die sekundengenaue Liveanzeige behalten möchte, aber in den Plots ist diese Genauigkeit einfach nicht notwendig, von daher können die Werte raus.
Benötigst du dann in DbLog überhaupt die volle Auflösung, oder benötigst du nur so häufig Fhem-Events?
Falls du nur auf die häufigen Events aus bist, würde ich das Reading mit DbLogExclude erstmal komplett herausnehmen, und manuell mit einem at das Reading loggen.
Zum manuellen Loggen von Readings hatte ich mal hier einen Lösungsvorschlag gepostet: http://forum.fhem.de/index.php/topic,38685.msg312484.html#msg312484
Gruß
Claudiu
Hallo,
ein Vorschlag: wie wäre es wenn es bei deleteOldDays eine Sicherheitsabfrage oder ähnlich gäbe, um unabsichtliches Löschen zu verhindern?
z.B. deleteOldDays 30 yes
Ihr dürft raten was mir passiert ist...
Grüße
Wie wäre es,
1. wenn du nicht irgendeinen Thread kapern würdest
2. selber etwas Sorgfalt walten lässt (das impliziert auch das erstellen eines Backups)
?
Das erinnert mich an meinen 1. Lehrjahrs Azubi vor einigen Jahren, "Ups, 'rm -rf /' löscht ja tatsächlich alles..."
Gruß
Claudiu
Ein herzerfirschendes "Moin" vom "Hintern-Deich" vorweg!
Also ich habe jetzt mal den Schnitt gemacht
set myDbLog deleteOldDays 120
ergibt bei folgender Abfrage
set myDbLog userCommand select min(timestamp) from history;
folgenden Output:
Vorher: 2015-02-09 13:29:49
Nachher: 2015-06-02 04:31:27
Die Datenbankgroesse ist unveraendert auf 3,8 GB!
Wie geht das denn? :o
Muss ich die db noch "purgen"? ???
Gruss
Sailor
Moin Sailor ;)
Was hast du denn für eine Datenbank, SQLITE?
Bei SQLITE zumindest musst du, falls du eine kleinere Datei willst, noch manuell VACUUM; ausführen.
Gruß
Claudiu
Hallo Claudiu
Zitat von: rapster am 30 September 2015, 11:43:25
Was hast du denn für eine Datenbank, SQLITE?
Bei SQLITE zumindest musst du, falls du eine kleinere Datei willst, noch manuell VACUUM; ausführen.
Correct. Was anderes bleibt mir auf dem RasPi nicht.
Kannst du mir den "set myDbLog userCommand ..." dafuer geben. ???
Ich habs nicht so mit SQL Befehlssaetzen. ;D
Danke
Gruss
Sailor
Moin Sailor,
hatte Claudiu Dir schon geschrieben: ;)
set myDbLog userCommand VACUUM
Viele Grüße
Sunny
Hallo Sunny
Zitat von: Sunny am 30 September 2015, 12:12:05
hatte Claudiu Dir schon geschrieben: ;)
set myDbLog userCommand VACUUM
OK 1:0 fuer Dich?
Leider war der Befehl mal wieder gut fuer einen fhem - Absturz erster Sahne >:(
Diesmal hats fuer den Absturz aber nicht so lange gebraucht... Immerhin schon mal ein Fortschritt! ;D
Gruss
Sailor
Moin Sailor,
Zitat von: Sailor am 30 September 2015, 12:40:43
OK 1:0 fuer Dich?
Dies war und ist nicht meine Intension... ;D
Läuft Dein RPi mit einer USB-HDD ?
Falls ja, könntest Du ja mal testen, ob eine Erweiterung der Swap-Datei Dir eventuell weiterhilft.
z.B.:http://jankarres.de/2012/11/raspberry-pi-swap-erweitern/ (http://jankarres.de/2012/11/raspberry-pi-swap-erweitern/)
Habe damit selber aber noch keine Erfahrung.
Viele Grüße
Sunny
Zitat von: Sailor am 30 September 2015, 12:40:43
Hallo Sunny
OK 1:0 fuer Dich?
Leider war der Befehl mal wieder gut fuer einen fhem - Absturz erster Sahne >:(
Diesmal hats fuer den Absturz aber nicht so lange gebraucht... Immerhin schon mal ein Fortschritt! ;D
Gruss
Sailor
Du kannst auch das Kommando direkt vom Terminal aus starten, genauso wie ich es mit cron jobs nachts auf meinen MySQL Server mache. Ich denke es muss nicht unbedingt Aufgabe von FHEM sein reine Datenbank Abfragen zu handeln. Eine Blockierung von FHEM wirst du aber auch von der Konsolenseite nicht komplett vermeiden können, was je nach Modul sicherlich auch zum Absturz führen kann.
Ein beendetes FHEM zzgl. eines Aufräum Kommandos sollte allerdings auch im Problemfall relativ gute Ergebnisse liefern können.
Hallo Zusammen,
habe nun reduceLog nach Rücksprache mit dem Modul Maintainer ins svn eingecheckt.
Ab Morgen früh wird die Funktion über das Fhem-Update verteilt.
Gruß
Claudiu
Zitat von: rapster am 01 Oktober 2015, 17:51:08
Hallo Zusammen,
habe nun reduceLog nach Rücksprache mit dem Modul Maintainer ins svn eingecheckt.
Ab Morgen früh wird die Funktion über das Fhem-Update verteilt.
Gruß
Claudiu
Großartig! :)
Moin Claudiu,
freut mich, das Deine Arbeit "gewürdigt" wurde und jetzt auch ein Teil von FHEM ist. 8)
Bin schon gespannt auf das, was Dir noch so einfällt... ;)
DANKE für Deine Zeit & viele Grüße
Sunny
So jetzt aber,
1) fhem runtergefahren
2) Den VACUUM Befehl von der Konsole aus gestartet
3) 13h gewartet
4) fhem.db wurde um 1,5 GB reduziert
5) fhem neu gestartet
So weit so gut. Jetzt wollen wir mal sehen wa passiert wenn wir die verbleibenden 100 Tage stundenweise reduzieren...
Gruss
Sailor
13 Stunden hört sich nach DbLog@SD-Karte an :-)
Ich bin gespannt ;)
Gruß
Claudiu
Hallo
mit Interesse habe ich diese Diskussion gelesen und bin dabkbar für die neuen Möglichkeiten, die Datenbank zu reduzieren.
Ich habe als Laie aber Verständnisfragen, die ich aus der Diskussion nicht beantworten konnte
1. Was ist der Unterschied zwischen deleteOldDays und reduceLog (ohe Parameter) ?
2. Nach der Reduzierung sollte immer ein "set myDbLog userCommand VACUUM" erfolgen ?
3. Weitere Befehle sind nicht erforderlich, um FHEMDB zu reduzieren
4. Beide set-Kommandos können in einem "at" als auszuführende Befehle stehen ?
Übrigen, der Hinweis auf
Zitatpragma auto_vacuum=2
steht nur in der fhem.pl reference unter "configdb" und nicht bei fhemdb. Ebenso steht dort leider nicht der Hinweis, dass dies nur beim Anlegen einer neuen Tabelle möglich ist.
Danke für die Geduld mit einem Laien
Jürgen
1. deleteOldDays schneided die DB nach den gegebenen Tagen ab, reduceLog lässt bei älteren Einträgen jeweils einen Eintrag pro Stunde je device:reading zurück.
2. Bei der ersten Reduzierung einer großen Menge kann man das machen, wenn reduceLog regelmäßig aufgerufen wird (bei mir z.B. täglich) ist es nicht notwendig, da davon ausgegangen werden kann dass der Speicherplatz der bereits einmal verwendet wurde wieder benötigt wird.
3. Ich würde empfehlen reducelog immer mit dem parameter "average" aufzurufen, da hierdurch die zurückbleibenden Daten genauer sind, und auch bei einer nachträglich average=day Berechnung das korrekte Ergebnis berechnet wird.
Die Bereinigung ist allerdings etwas Ressourcenintensiver.
Allerdings wird durch die average Werte auch weniger Speicherplatz verwendet, da der 'EVENT' Column verkleinert wird.
4. Wie bereits geschrieben, würde ich vacuum wenn überhaupt nur bei der ersten "Grundreinigung" ausführen, anschließend ist vacuum nicht notwendig.
Zu beachten ist das vacuum immer die gesamte Datenbank auf dem Datenträger kopieren muss um sie zu verkleinern, und fhem während dessen nicht mit der Datenbank arbeiten kann.
Gruß
Claudiu
Hallo Claudiu
das nenne ich eine schnelle und klasse Antwort. :)
man könnte also, so man es möchte, im mittelfristigen Bereich average und dann nochmals im lanfristigen Bereich average=day ausführen ?
Danke
Ja, genau so ist es gedacht, habe ich schonmal hier versucht zu beschreiben: http://forum.fhem.de/index.php/topic,41089.msg334617.html#msg334617 (http://forum.fhem.de/index.php/topic,41089.msg334617.html#msg334617)
Zitat von: rapster am 19 September 2015, 19:45:09
average=day ist auch nachträglich möglich, somit kann man sich z.B. ein Konstrukt bauen welches
- jeden record der letzten 2 Wochen behält
- nurnoch 1 record pro Stunde des letzten Jahres behält (optional mit Mittelwert)
- nur den Tages-Mittelwert der letzten 10 Jahre behält
Hallo rapster, hatte heute mal vor meine sqlite fhem DB aufzuräumen. Da fhem für die Zeit des Aufräumens blockiert, möchte das bei runtergefahrenen fhem machen.
Meine Frage (so fit bin ich mit Datenbanken nicht) wie sieht das Statement für sqLite aus um die DB auszudünnen (mit dem Äquivalent zu average, ausgeführt direkt in der DB.
VG
Frank
Hallo Frank,
reduceLog ist ein Fhem-Befehl welcher nur zugänglich ist während dein fhem gerade läuft.
Allerdings macht es so direkt keinen Unterschied ob fhem durch reduceLog blockiert wird oder du es herunterfährst, erreichbar ist es während der Bereinigung so oder so nicht :)
Wenn man nach einer Grundreinigung anschließend reduceLog regelmäßig ausführt beschränkt sich die Blocking-Time auf einem einigermaßen flotten System auf wenige Sekunden.
Gruß
Claudiu
Ist schon klar, dass das ein fhem-Befehl ist.
In der DBLog.pm steht doch dann irgendwo das Statement, welches reduceLog auf der DB ausführt, das meine ich ;)
P.S. da mein fhem ziemlich umfangreich ist, Heizung, Brennersteuerung und und und.... kann ich fhem nicht lange blockieren
VG
Frank
Das sind mehrere Befehle
Gesendet von meinem GT-I9295
Das Problem ist dass reduceLog nicht ein einzelnes Statement ist, sondern die reduceLog Perl-Funktion geht jeden Datensatz einzeln durch und verarbeitet ihn anschließend in einer Tageweißen Transaktion.
Du könntest allerdings durch minimale Anpassungen die reduceLog Funktion in ein eigenes .pl Script auslagern um es ohne Fhem verwenden zu können.
Die Funktion findest du in der 93_DbLog.pm Z. 1334 - 1538
Nur der Sinn erschließt sich mir grad noch nicht so wirklich, warum willst du das ganze manuell an der DB anwenden?
P.S. stromer-12 war schneller :-)
Gruß
Claudiu
Zitat von: franky08 am 27 Oktober 2015, 09:50:20
P.S. da mein fhem ziemlich umfangreich ist, Heizung, Brennersteuerung und und und.... kann ich fhem nicht lange blockieren
Du kannst reduceLog allerdings aus einer zweiten Fhem-Instanz starten, dann wird dein Haupt-Fhem nicht durch die Bereinigung blockiert.
Bei MySQL sollte das problemlos funktionieren, bei SQLITE bin ich mir nicht sicher, da das eigtl. nicht für mehrere gleichzeitige Zugriffe gedacht ist.
PS, die tägliche Bereinigung bei mir blockiert fhem ~10 Sekunden, das bekomm ich Nachts nicht mit :)
Mmh, eigentlich hast du Recht. Ob ich fhem nun beende und die DB direkt aufräume oder ob fhem läuft aber in der Zeit blockiert ist, spielt eigentlich keine Rolle. Die Heizung läuft dann so oder so nicht, müsste ich das Backup Teil für die Steuerung anwerfen ;)
Anfang Januar habe ich sonst immer ein delete old day´s angeworfen, wenn ich das Anfang Januar wieder so mache, dann ist die DB ja schon einmal klein und dann könnte man ein at mit reduceLog einbauen.
Danke
VG
Frank
Wie wäre es, wenn wir bei blockiertem Mysql die Daten temporär in eine Sqlite schreiben, und diese später dort wieder abholen? Das hätte mich schon vor einigen Datenverlusten gerettet.
Hallo Claudiu,
vielen Dank für die nützliche Erweiterung.
Allerdings hätte ich noch einen kleinen Featurerequest:
Zur Zeit lassen sich nur Devices über das exclude Pattern ausschließen. Ich fände es allerdings praktischer (zusätzlich) ein positives Pattern anzugeben, um meine Devices gezielt selektieren zu können.
Momentan habe ich reduceLog minimal modifiziert, so dass als zweiter Parameter eine db-regexp der Form device:reading erwartet wird.
set <name> reduceLog <n> <device>:<reading> [average[=day]] [exclude=deviceRegExp1:ReadingRegExp1,deviceRegExp2:ReadingRegExp2,...]
Mit device:reading = %:% erhält man die bisherige Funktionalität.
Für die Umsetzung habe ich hauptsächlich $sth_get um ein WHERE (DEVICE like ?) AND (READING like ?) erweitert.
Diese Erweiterung halte ich auch für deleteOldDays für sinnvoll, da es Daten gibt, die ich nur für ein bestimmtes zurückliegendes Zeitfenster benötige. Wohingegen ich für andere Daten eine Langzeit-Aufzeichnung haben möchte. Evtl. sollte man reduceLog um eine Option delete erweitern und könnte auf deleteOldDays komplett verzichten.
Weitere fehlende Funktionen (die aber natürlich auch manuell gelöst werden können), die mir bei der Bereinigung meiner Datenbank aufgefallen sind :
- Ermitteln von nicht mehr existierenden Devices und Löschen der Daten
. Umbennenen von Devices in der Datenbank ( z.B. nach einem rename)
Gruß,
Gero
Hi Gero,
ZitatZur Zeit lassen sich nur Devices über das exclude Pattern ausschließen.
nicht ganz, über den exclude Parameter kannst du auch explizit nur ein device respektive eine device:reading Kombination durch reduceLog reduzieren lassen (Also einschließen).
Um z.B. nur das reading 'measured-temp' des devices 'wt_wohnzimmer' mit average zu reduzieren müsste die regexp so aussehen:
set <dbLog> reduceLog <days> average exclude=(?!wt_wohnzimmer:measured-temp).*
In dem Fall matcht die regexp einfach alle anderen devices außer 'wt_wohnzimmer:measured-temp'.
Oder zweites Beispiel um alle readings von 'wt_wohnzimmer' und 'wt_esszimmer' zu reduzieren und andere devices unberührt zu lassen:
set <dbLog> reduceLog <days> average exclude=(?!wt_(esszimmer|wohnzimmer):.*).*
Zitat
Diese Erweiterung halte ich auch für deleteOldDays für sinnvoll, da es Daten gibt, die ich nur für ein bestimmtes zurückliegendes Zeitfenster benötige. Wohingegen ich für andere Daten eine Langzeit-Aufzeichnung haben möchte. Evtl. sollte man reduceLog um eine Option delete erweitern und könnte auf deleteOldDays komplett verzichten.
Weitere fehlende Funktionen (die aber natürlich auch manuell gelöst werden können), die mir bei der Bereinigung meiner Datenbank aufgefallen sind :
- Ermitteln von nicht mehr existierenden Devices und Löschen der Daten
. Umbennenen von Devices in der Datenbank ( z.B. nach einem rename)
Sowas mache ich i.M. immer über manuelle sql-statements, das ist schon richtig das einfache Funktionen welche über fhem bedienbar sind hierfür sinnvoll währen.
Kann ich mir gerne mal bei Gelegenheit anschauen, ist sowieso noch eine weitere DbLog Funktion in Planung, das kann allerdings noch ein bisschen dauern.
Gruß
Claudiu
Danke für die Antwort. Aud die exclude regexp bin ich gerade nicht gekommen. Du hast natürlich recht.
Wie sieht es aber mit der Performance aus? Sollte die nicht deutlich besser sein, wenn man schon im SELECT Statement alles unnötige wegfiltert?
Gruß,
Gero
Das ist die Frage, ob es wirklich "deutlich" besser ist,
Da das exclude direkt beim ersten Anfassen der Datensätze evaluiert wird, werden zwar wenn das SELECT weniger Daten zurückliefert auch weniger Daten verglichen, allerdings finden sich die Zeitfresser in reduceLog üblicherweiße an anderen Stellen.
Allerdings da du ja reduceLog schon entsprechen modifiziert hast und mich das schon interessieren würde :), Kannst du mal probieren ein einzelnes device mit deiner Methode und mit der exlucde Methode zu reduzieren um den Zeitunterschied festzustellen?
Gruß
Claudiu
Hier ein direkter Vergleich (die beiden Readings kommen immer simultan in der db vor):
Filtern im SELECT:
reduceLog requested for OG.WZ.MAX.HT.pid:delta with DAYS=30
reduceLog executed. Rows processed: 18371, deleted: 13975, time: 86.00sec
Filtern im exclude:
reduceLog requested with DAYS=30, EXCLUDE=(?!OG.WZ.MAX.HT.pid:p_p).*
reduceLog executed. Rows processed: 3022650, deleted: 13975, excluded: 3004279, time: 302.00sec
Bei der zweiten Methode (exclude) hatte ich nachdem reduceLog fertig war, hatte ich ständig folgenden Fehlermeldugen im Log:
2015.10.29 14:43:20 1: Cannot fork: Cannot allocate memory
2015.10.29 14:43:20 3: stacktrace:
2015.10.29 14:43:20 3: main::fhemFork called by FHEM/Blocking.pm (68)
2015.10.29 14:43:20 3: main::BlockingCall called by ./FHEM/73_PRESENCE.pm (535)
2015.10.29 14:43:20 3: main::PRESENCE_StartLocalScan called by fhem.pl (2701)
2015.10.29 14:43:20 3: main::HandleTimeout called by fhem.pl (584)
2015.10.29 14:43:20 1: Cannot fork: Cannot allocate memory
2015.10.29 14:43:20 1: Cannot fork: Cannot allocate memory
Ein shutdown restart hat den fhem Prozess zwar beendet, aber nicht mehr neu gestartet. Erst ein manueller service fhem start hat funktioniert.
Zur Information: Das System ist ein odroid C1 mit 1GB Hauptspeicher.
Gruß,
Gero
Das scheint schon wirklich was zu bringen bzgl. RAM Belastung und Geschwindigkeit auf einem kleineren System.
Hab ich eingebaut:
set <dbLog> reduceLog <days> average include=Database-deviceRegExp:Database-ReadingRegExp
Bei mir hat es allerdings nur ein paar Sekunden gebracht, allerdings ist meine DB auch nur etwa 1/6 so groß.
Gruß
Claudiu
Danke. Für meine Belange ist es ausreichend.
Aber auf der Fahrt nach Hause kam mir so ein Gedanke:
Vielleicht ist es für viele User verwirrend, dass sie bei include eine Database-deviceRegExp angeben müssen und bei exclude eine Perl-Regexp.
Evtl. ist es besser und komfortabler beim include (und evtl. auch beim exclude) auf die Standard devspec zu gehen.
Wenn man die mit devspec2array auflöst und über die Devices loopt, sollte die Performance noch weiter steigen, weil das like durch ein = ersetzt werden kann.
Zusätzlich wären automatisch auch Filter möglich, wie z.B. TYPE=LaCrosse.
Gruß,
Gero
Allerdings hat man dann keine Möglichkeit mehr nur einzelne Readings zu includen, bzw. müsste man für das Reading weiterhin die Database-ReadingRegExp verwenden?
Für die devices würde es allerdings sicherlich Sinn machen das sowohl für include als auch exclude über devspec2array zu lösen.
Wenn du Lust has hierfür einen Patch zu bauen, gerne, ansonsten schreib ich mir das mal auf die todo und mach das bei Gelegenheit (Kann aber bisschen dauern).
Gruß
Claudiu
Zitat von: rapster am 29 Oktober 2015, 16:53:05
Allerdings hat man dann keine Möglichkeit mehr nur einzelne Readings zu includen, bzw. müsste man für das Reading weiterhin die Database-ReadingRegExp verwenden?
Einzelne Readings wären im SELECT doch kein Problem. Sobald eine Perl-Regexp angegeben ist , müßte man allerdings im nachfolgenden Code filtern.
Ich muß aber über das Problem nochmal nachdenken.
Zitat von: rapster am 29 Oktober 2015, 16:53:05
Für die devices würde es allerdings sicherlich Sinn machen das sowohl für include als auch exclude über devspec2array zu lösen.
Wenn du Lust has hierfür einen Patch zu bauen, gerne, ansonsten schreib ich mir das mal auf die todo und mach das bei Gelegenheit (Kann aber bisschen dauern).
Mal sehen, wann ich Zeit habe. Meine TODO Liste ist auch noch ziemlich lang.
Gruß,
Gero
Hallo rapster,
danke für dein reduceLog-Feature. Es ist genau war ich gesucht hatte.
Ich habe es vor kurzem ausprobiert, leider ist meine SD parallel voll gelaufen und nun habe ich beim Schreiben in die DB-Datei folgende Fehler:
- DbLog: Failed to insert new readings into database: DBD::SQLite::st execute failed: database disk image is malformed at ./FHEM/93_DbLog.pm line 465.
- DbLog: Failed to insert new readings into database: DBD::SQLite::st execute failed: attempt to execute on inactive database handle at ./FHEM/93_DbLog.pm line 465.
(siehe auch http://forum.fhem.de/index.php/topic,42714.msg351612.html#msg351612)
Hast du eine Idee, wie ich sowas wieder behoben bekomme. Ich habe erst mal eine neue DB angefangen, da leider mal wieder kein geeignetes Backup da war...
Könnte ein erneutes reduceLog es besser machen? oder schlimmer? Wird die DB bei einem reduceLog zunächst mit einem LOCK versehen?
PS: Parallel grüble ich aktuell hier (http://forum.fhem.de/index.php/topic,43279.msg352645.html#msg352645) wie ich meine DB schlank bekomme.
Habt ihr eine Idee? Ich wollte mit der Frage nicht das Thema hier sprengen. Gerne aber den Link zu meiner Frage herstellen.
Besten Dank für eure Ideen. Viele Grüße,
zYloriC
Da deine SD vollgelaufen ist, hast du nun leider eine beschädigte sqlite-Datei, deswegen erhälst du den "malformed" fehler.
Sqlite bietet hierfür integrity check Funktionen, sowie kannst du versuchen die Daten in eine neue sqlite-datei zu dumpen.
Siehe hier: http://www.sqlite.org/faq.html#q21
Oder einfach mal nach "sqlite database disk image is malformed" googlen, da findet sich recht viel.
Gelockt selber wird das file nicht, allerdings arbeitet reduceLog mit Tranactions, ich kann leider nicht sagen wie sich das DB-File verhält wenn mitten während einer Transaction die Disk vollläuft :-\
Wegen dem schlank bekommen, hast du bestimmt schonmal einen Blick ins Wiki geworfen oder? http://www.fhemwiki.de/wiki/DbLog
Gruß
Claudiu
Hi rapster,
vielen Dank für deinen schnellen Hinweis.
Wie bekomme ich inf Fhem etwa "PRAGMA schema.quick_check; " an die SQL übergeben? Funktioniert das als userCommmand?
Wie muss ich "PRAGMA schema.quick_check; " anpassen, damit sich meine DB angesprochen fühlt?
Gruß, zYloriC
Du musst die Befhele direkt über den sqlite Konsole ausführen.
Also in der Linux shell mit "#sqlite3 meindb.db" die Datenbank öffnen und dann den Befehl eingeben.
hallo zusammen,
ich habe mir den code gerade angeschaut - wird das AVG bestimmen wirklich in PERL durchgeführt?
warum nicht das DBMS das ganze selbst machen lassen?
Ich hatte das mal für mich umgesetzt, allerdings schon etwas länger her.
https://github.com/mdorenkamp/fhem_dbcleansing/blob/master/cleanse.sql
viele grüße
marcel
ja bei reduceLog wird i.M. alles in Perl erledigt.
Du kannst allerdings gerne einen Patch bereitstellen der das für die supporteten Datenbanktypen (SQLITE, MYSQL, ORACLE und POSTGRES) anders implementiert.
ich bin gerade an der umsetzung, dabei ist mir jedoch ein problem aufgefallen. die zeitzone. wird das momentan überhaupt in irgendeiner form betrachtet und entsprechend korrigiert? wir bewegen uns ja zwischen +1 und +2h offset zu utc
Und wo genau liegt das Problem In meiner DB wird die Ortszeit eingetragen, nicht die UTC. somit sehe ich hier keine Schwierigkeiten...?!?
ganz einfach: keine bzw doppelte werte zwischen 2 und 3 uhr an den tagen an denen es zum wechsel zwischen MEZ und MESZ kommt
Hallo,
ich wollte mal fragen ob es Bestrebungen gibt auch rrd-Datenbanken bei dblog zu unterstützen. Mit denen würde das Problem die Daten nachträglich aufwändig auszudünnen gar nicht erst stellen ...
Beruflich habe ich viel mit Nagios zu tun, da ist das seit Jahren der defacto-Standard um historische Daten zu speichern und zu visualisieren und das Ganze funktioniert mit rrd auch sehr performant und ressourcensparend für viele Messwerte gleichzeitig (z.B. Auslastung der Switchports eines Unternehemnsnetzwerks, da kommen problemlos viele tausend Messwerte pro Sekunde zusammen).
Grüße,
gadget
Moin Claudiu,
wollte mal nach horchen, ob Dir schon etwas zu folgendem
Zitat von: Sunny am 26 September 2015, 15:34:39
... für z.B. Temperatur-Daten die Möglichkeit für 1 Minute, 5 Minuten oder 15 Minuten Intervalle "ein zubauen".
...
Ich würde mich sehr darüber freuen...
Zitat von: rapster am 26 September 2015, 16:11:52
...
Werde mir mal Gedanken drüber machen wie sich das am besten einbauen lässt, denke da an sowas wie "average=min=<mins>", und falls mir was gutes einfällt bei Gelegenheit einbauen :)
eingefallen ist ? ;)
Vielen Dank & viele Grüße
Sunny
Moin Sunny,
ja eingefallen schon, nur leider zeitlich noch keine Möglichkeit gehabt... :-\
Denke wird leider auch noch ein bissi dauern, stehn davor noch paar andere Sachen auf der ToDo zu denen ich leider genausowenig komme, aber vergessen hab ichs nicht ;)
Gruß
Claudiu
Zitat von: gadget am 19 Dezember 2015, 14:14:34
rrd-Datenbanken bei dblog zu unterstützen
Das passt nicht zusammen, dblog ist ein sql wrapper. Unterhalb von ./contrib/rrd findest Du aber vielleicht etwas, dass Du zur Implementierung nutzen kannst.
Moin Claudiu,
bloß keinen Stress, um Diese Zeit. ;)
Das Du schon eine Idee hast freut mich.
Danke & eine entspannte Zeit
Sunny
Ein herzerfrischendes "Moin" vom "hinternDeich" vorweg!
Eine Frage an die SQL - Hacks in dieser Runde:
Wie lautet der Befehl in der mySQL - Konsole des RasPi, wenn von dem Device "myGasCalculator" alle DbLog - Werte des Readings "CH_GasCounter_counters.A_FinanceReserve" gelöscht werden sollen deren Wert größer als 600 oder kleiner als 300 sind?
Wie kann ich hinterher die Werte auch wirklich "purgen"?
Danke für Eure Hilfe... Bin absolut nicht SQL-bewandert!
Gruß
Sailor
Hallo Sailer
Ich hoffe ich habe es richtig verstanden.
Anzeige die Anzahl der Datensätze die gelöscht werden sollen
Select count(*) from history where device = 'CH_GasCounter_counters.A_FinanceReserve' and (value > 600 or value < 300);
Anschließend zum Löschen
delete from history where device = 'CH_GasCounter_counters.A_FinanceReserve' and (value > 600 or value < 300);
Das kannst du in DBLog bei userCommand eingeben.
Aber bitte vorher erst mal nur den Select testen wieviel Einträge anschließend gelöscht werden.
Ergebnis steht in den Reading userCommandResult
Ich habe so etwas ähnliches schon öfters auf meine SQLite DBLog angewendet.
Kann leider im Moment nur via TapaTalk antworten
Gruß Hannes
Gesendet von meinem SM-T715 mit Tapatalk
Hallo Hannes
Zitat von: AHA1805 am 25 Januar 2016, 22:32:35
Ich hoffe ich habe es richtig verstanden.
Hast Du!
Ich probiere es aus und gebe Rückmeldung! Danke
Gruß
Sailor
Nachtrag: Mit "reading" statt "device" hat es geklappt! Danke!
Zitat von: Sailor am 26 Januar 2016, 06:19:17
Hallo Hannes
Hast Du!
Ich probiere es aus und gebe Rückmeldung! Danke
Gruß
Sailor
Nachtrag: Mit "reading" statt "device" hat es geklappt! Danke!
Hallo Sailer,
sorry hab ich oben nicht richtig gelesen.
Aber Hauptsache du bist ans Ziel gekommen.
Gruß Hannes
Gesendet von meinem SM-T715 mit Tapatalk
Hallo CLauidu,
Erst mal ein Danke für die Arbeit. Ich denke dass ich meine auf mittlerweile 16G angewachsene Datenbank doch erheblich reduzieren kann.
Ich benutze eine PostgreSQL Datenbank und damit mir ist ein Fehler in dem Modul aufgefallen.
Nachdem ich die Zeile 1337 geändert habe funktioniert es(habe aber nur geringe Programmierkenntnisse)
elsif ($hash->{DBMODEL} eq 'POSTGRESQL') { $cmd = "NOW() - INTERVAL '$a[2] DAY"; }
elsif ($hash->{DBMODEL} eq 'POSTGRESQL') { $cmd = "NOW() - INTERVAL '$a[2]' DAY"; }
Gruß Alfons
Hallo Alfons,
danke für den Hinweis, habs gefixt und eingecheckt.
Gruß
Claudiu
Hallo CLauidu,
Habe gerade gesehen dass in der Zeile 1574 der gleiche Fehler ist.
Gruß Alfons
richtig, danke, habs ebenfalls gefixt und eingecheckt.
Von der Stelle hatte ich es für reduceLog kopiert gehabt :-)
Allerdings habe ich reduceLog selber noch nie unter PostgreSQL getestet, hoffe dass sonst alles passt ;)
Gruß
Claudiu
Danke, werde es später testen und mich melden wenn ich noch Probleme habe.
Gruß Alfons
in Zeile 1884 fehlt ein ; am Zeilenende.
Ich habe von mysql leider nicht so viel Ahnung und würde nun gerne mittels reduceLog meine Datenbank reduzieren. Wie kann ich feststellen, oder dieser "Search_Idx" vorhanden ist?
z.B. mit mysql command line tool:
mysql -u <user> -p
use <db>
SHOW INDEX FROM <table>;
Das habe ich gemacht und das Ergebnis sieht wie auf dem Bild aus. Ich sehe, dass bei Device und Reading ein Yes für Search_Idx steht, bei Timestamp aber kein Yes. Ist das so richtig und kann ich damit den reduce Befehl ausführen, oder müsste bei Timestamp auch ein Yes stehen?
sieht bei mir genau so aus. Ich habe keine Probleme mit reduceLog. Ich glaube du beziehst dich auf die Stelle wo es heisst dass ohne den entsprechenden Index die Sache ewig dauert und dass fhem während dieser Zeit brach liegt?
Kleiner Tip: mache das ganze nochmal mit putty als Vollbild, dann sieht das viel übersichtlicher aus.
Beziehe mich auf die CommandRef, wo folgendes steht:
ZitatACHTUNG: Es wird dringend empfohlen zu überprüfen ob der standard INDEX 'Search_Idx' in der Tabelle 'history' existiert!
Daher wollte ich es vorher klären :)
besser ist das :-)
Das 'yes' besagt nur dass in dem entsprechenden Feld kein Eintrag erfolgen muss. Beim index muss aber ein Eintrag erfolgen. Siehst du aber wie gesagt wenn du das ganze nochmal im Vollbild modus ausführst
Zitat von: Amenophis86 am 25 März 2016, 15:29:19
Beziehe mich auf die CommandRef, wo folgendes steht:
Daher wollte ich es vorher klären :)
Schaut gut aus, Index ist bei dir laut Bild vorhanden 8)
Gruß
Claudiu
Danke für die Infos und ja, im Vollbildmodus sieht man es ganz eindeutig ;)
Hi,,
habe gerade den ganzen Thread gelesen und freue mich, dass er genau an der Stelle endet, wo meine Frage anfängt :-)
Ich würde gerne meine Datenbank verkleinern.
Zitat von: Amenophis86 am 23 März 2016, 13:18:31
Ich habe von mysql leider nicht so viel Ahnung und würde nun gerne mittels reduceLog meine Datenbank reduzieren. Wie kann ich feststellen, oder dieser "Search_Idx" vorhanden ist?
Wie geht das ganze bei sqlite?
sqlite> select * from sqlite_master;
table|history|history|2|CREATE TABLE 'history' (TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32))
table|current|current|3|CREATE TABLE 'current' (TIMESTAMP TIMESTAMP, DEVICE varchar(32), TYPE varchar(32), EVENT varchar(512), READING varchar(32), VALUE varchar(32), UNIT varchar(32))
index|Search_Idx|history|4|CREATE INDEX Search_Idx ON `history` (DEVICE, READING, TIMESTAMP)
sqlite>
sqlite> .databases
seq name file
--- --------------- ----------------------------------------------------------
0 main /opt/fhem/fhem_sqlite.db
sqlite> .dbinfo main
database page size: 1024
write format: 2
read format: 2
reserved bytes: 0
file change counter: 131
database page count: 1151196
freelist page count: 0
schema cookie: 4
schema format: 4
default cache size: 0
autovacuum top root: 0
incremental vacuum: 0
text encoding: 1 (utf8)
user version: 0
application id: 0
software version: 3008011
number of tables: 2
number of indexes: 1
number of triggers: 0
number of views: 0
schema size: 385
Danke schonmal für eure tolle Arbeit!!
Stephan
da ich auch gerade aufgeräumt habe und feststellen musste dass ein löschen alter einträge per deleteolddays bezogen auf die datenbankgröße auf dem datenträger genau nichts bringt, habe ich ein wenig probiert.
per usercaommand VACUUM [tablename] also VACUUM history konnte ich nach dme löschen alter einträge auch die filegrößer erheblich verringern.
evtl etwas was man ins modul mit aufnehmen könnte (oder in der anleitung zum erstellen der db gleich auf auto setzen, vor dem erstellen der db).
Zitat von: rapster am 29 Oktober 2015, 14:14:01
Um z.B. nur das reading 'measured-temp' des devices 'wt_wohnzimmer' mit average zu reduzieren müsste die regexp so aussehen:
set <dbLog> reduceLog <days> average exclude=(?!wt_wohnzimmer:measured-temp).*
In dem Fall matcht die regexp einfach alle anderen devices außer 'wt_wohnzimmer:measured-temp'.
Oder zweites Beispiel um alle readings von 'wt_wohnzimmer' und 'wt_esszimmer' zu reduzieren und andere devices unberührt zu lassen:
set <dbLog> reduceLog <days> average exclude=(?!wt_(esszimmer|wohnzimmer):.*).*
Kurze Verständnisfrage: Wieso braucht es das .* hinter device:reading?
Hintergrund: Ich habe mit folgendem set versucht nur einige Readings zusammenzufassen, dblog hat aber wohl über alle Readings einen Durchschnitt gebildet
set mydblog reduceLog 14 average exclude=(?!Heizung:(Neigung|Niveau|Temp-Aussen|Temp-Ruecklauf|Temp-Vorlauf|Temp-WarmWasser-Ist|Temp-WarmWasser-Soll))
Zitat von: Lars am 05 Juli 2016, 22:40:53
Kurze Verständnisfrage: Wieso braucht es das .* hinter device:reading?
Hinter device:reading brauchts kein .*
Da du hier allerdings einen negative lookahead hast, also erstmal nur sagst, "was darf nicht im text enthalten sein", musst du anschließend auch noch sagen was soll enthalten sein.
Ziel dieser RegEx an der Stelle ist ja dass sie auf alle anderen devices und readings matcht, die du nicht im negative lookahead angegeben hast.
Also müsste dein cmd so aussehen:
set mydblog reduceLog 14 average exclude=(?!Heizung:(Neigung|Niveau|Temp-Aussen|Temp-Ruecklauf|Temp-Vorlauf|Temp-WarmWasser-Ist|Temp-WarmWasser-Soll)).*
Hallo liebe DbLoG-Gemeinde,
wird mein Vorhaben so gelingen alles zu reduzieren, bis auf ALLE Kontostand und Zaehlerstand Werte?
set myDbLog reduceLog 30 average=hour exclude=.*:Kontostand,Zaehlerstand
Hi Chris
Zitat von: chris1284 am 19 Juni 2016, 14:02:54
per usercaommand VACUUM [tablename] also VACUUM history konnte ich nach dme löschen alter einträge auch die filegrößer erheblich verringern.
Der Command sorgt mit zuverlässiger Sicherheit für ein fhem-Komplett-Absturz.
Selbst die MySQL - Konsole unter Telnet hängt sich auf...
Vielleicht sind die mittlerweile 3GB in der fhem.db einfach zu groß...
Dann bleicbt mir nichts anderes übrig als die Tabelle von 0 an neu zu beginnen... Schade.
Gruss
Sailor
Versuche gerade ebenfalls meine fhem.db auszudünnen, was zu FHEM Totalabsturz führt... Mein Plan für's Wochenende: DB exportieren, in eine "richtige" DB importieren, ausdünnen und dann als CSV wieder zurück... Mal sehen wie das klappt...
Ich nutze mySQL und schicke jede Nacht um 0400 ein Statement auf die DB
optimize table fhem.history
Zitat von: KernSani am 05 August 2016, 12:47:53
Versuche gerade ebenfalls meine fhem.db auszudünnen, was zu FHEM Totalabsturz führt..
in der regel kackt es nicht ab, wird aber solange blockiert wie in der db gearbeitet wird (warum man bei dblog kein nonblocking hinbekommt, wer weiss).
wenn du es einmal bereinigt hast werden die regelmäßigen folgenden bereinigungen fhem nicht so lange ausbremsen.
ich würd einfach mal fhem beenden, die db über konsole bereinigen und fhem wieder starten. mit export "in eine richtige db" (was auch immer das sein soll) und daraus wieder ein export zum import in die fhemdb macht dir wahrscheinlich mehr arbeit und erhöht die gefahr von fehlern.
ich habe wir einen wartungsdummy mit allen notwendigen set befehlen gebaut der regelmäßig per at geschaltet wird (alte einträge löschen alle 14 Tage und alle 30 das db-file verkleinern)
Die Funktion ist IMHO ohne non-blocking in Produktivsystemen sinnlos.
Zitat von: chris1284 am 05 August 2016, 15:06:12
in der regel kackt es nicht ab, wird aber solange blockiert wie in der db gearbeitet wird.
FHEM verabschiedet sich tatsächlich komplett. Ich gehe aber davon aus, dass - wenn die DB einmal beteinigt ist - regelmäßige Bereinigung über FHEM Bordmittel funktioniert.
Grüße,
Oli
Zitat von: kleineslichtHH am 04 August 2016, 18:14:33
Hallo liebe DbLoG-Gemeinde,
wird mein Vorhaben so gelingen alles zu reduzieren, bis auf ALLE Kontostand und Zaehlerstand Werte?
set myDbLog reduceLog 30 average=hour exclude=.*:Kontostand,Zaehlerstand
Nein,
Wenn du bei allen Devices die Readings Namens "Kontostand" und "Zaehlerstand" ausschließen möchtest dann so:
set myDbLog reduceLog 30 average=hour exclude=.*:(Kontostand|Zaehlerstand)
Wenn du bei dem Device "Bank" das Reading "Kontostand" und bei Device "Strom" das Reading "Zaehlerstand" ausschließen willst, dann so:
set myDbLog reduceLog 30 average=hour exclude=Bank:Kontostand,Strom:Zaehlerstand)
Zitat von: marvin78 am 05 August 2016, 15:09:24
Die Funktion ist IMHO ohne non-blocking in Produktivsystemen sinnlos.
Sehe ich nicht so, zumindest nicht völlig sinnlos, reduceLog läuft bei mir jede Nacht mit DAYS=21 und AVERAGE=Hour:
2016.07.01 04:01:00.000 3: DbLog dbLog: reduceLog requested with DAYS=21, AVERAGE=HOUR
2016.07.01 04:01:22.307 3: DbLog dbLog: reduceLog deleting 89596 records of day: 2016-06-09
2016.07.01 04:01:23.701 3: DbLog dbLog: reduceLog (hourly-average) updating 2602 records of day: 2016-06-09
2016.07.01 04:01:23.984 3: DbLog dbLog: reduceLog deleting 9087 records of day: 2016-06-10
2016.07.01 04:01:24.392 3: DbLog dbLog: reduceLog (hourly-average) updating 252 records of day: 2016-06-10
2016.07.01 04:01:24.416 3: DbLog dbLog: reduceLog executed. Rows processed: 1428754, deleted: 98683, updated: 2854, time: 24.42sec
Das blockiert mein fhem um die 25 Sekunden jede Nacht, nehme ich lieber in Kauf als alle meine alten Daten komplett wegschmeißen zu müssen.
Edit: Log aus leerem dbLog gepostet :-)
Alles über eine Sekunde ist in einem Produktivsystem zu viel. Es ist ja nicht so, als könnte man die Datenbank nicht auf andere Weise ausdünnen. Warum so eine Funktion nicht non-blocking einzubauen ist, verstehe ich nicht ganz, ich gebe aber zu, dass ich mich auch nicht im Detail mit DBLog beschäftigt habe. Das soll keine Kritik sein, nur eine Feststellung.
tja, die 28 sekunden stillstand können schon ärgerlich sein (fensteroffenmeldung, wassermeldung, regenmeldung ), in der zeit kann nichts geschaltet oder gelogged werden (gut wenn man weis sum 4 uhr nachts muss ich nichts schalten, bricht niemand ein oder wird kein feuer ausbrechen ;) sollte es nicht tragisch sein
was ich sagen will: ich finde es auch einfach unschön dass fhem blockiert wird durch sowas. ich glaube zwar auch nicht das es in einem produktivsystem wenn nur 20 sekunden sind was ausmacht
EDIT bei mir sinds 10 sek bei 30 tagen
ZitatreduceLog executed. Rows processed: 76568, deleted: 61060, time: 11.00sec
Die Frage die sich mir stellt ist nicht warum fhem es nicht kann, sondern wie sich die dahinter liegende DB verhält wenn es auf nonblocking umgebaut werden würde.
Was macht so eine SQLite DB z.B. wenn reduceLog nonblocking eine zweite Verbindung zur DB aufbaut, und am anderen Ende DbLog fleißig weiter Temperaturwerte usw. loggt?
Wie verhält sich da Postgres, MySql, Oracle usw...
Wenn man einfach eine zweite Fhem-Instanz mit der gleichen DbLog.conf startet, und hier reduceLog aufruft, sollte es doch genau das tun, nonBlocking reduceLog ausführen.
Müsste ich mal probieren ob es mir dann meine SQLite zerreisst :-)
Ich habe gestern über die sqlite Konsole Daten gelöscht während FHEM lief... Hat funktioniert, ich weiß aber nicht, ob einzelne Daten verloren gingen und FHEM war währenddessen kaum bedienbar.
sqlite ist explizit nicht multithreaded und sollte auch nicht von mehr als einem prozess schreibend verwendet werden. du kannst dir die komplette db zerschießen.
die anderen 'richtigen' datenbanken können natürlich mehr als eine verbindung aber je nach db und sql anweisung wird bei einem delete automatisch mehr oder weniger der db gelockt (zeilen, tabellen oder doch alles) und die anderen prozesse warten mehr oder weniger lange. je besser die db um so granularer ist das locking und desto weniger muss gewartet werden.
das reine löschen ist auch nur ein teil der aufräumarbeit. der platz muss auch zur wiederverwendung freigegeben/bereitgestellt werden. dazu dienen regelmäßige (automatische) vacum läufe. auch diese blockieren die db mehr oder weniger lange.
je nach anwendung ist es besser öfter kleine häppchen löschen und zu reorganisieren als seltener und dafür mehr.
schnellere platten und die richtige db struktur helfen auch.
noch besser als aufräumen ist erst garnicht loggen.
gruss
andre
Hi Andre,
VACUUM ist der nächste Schritt, dann aber ohne laufenden FHEM;-) Habe kürzlich DBLog von exlude auf include umgestellt und irgenwie muss ich jetzt den alten Schotter loswerden ;-) ReduceLog in 5-Tages-Häppchen macht nicht wirklich Spaß;-)
vaccum + laufendes fhem geht problemlos (hat mir noch nichts zerschossen) da sqlite die optimierung nicht in der original database macht, sondenr in einer temporären kopie (auf die greift fhem garnicht zu ) und dann nur kurz das alte file durch das neu ersetzt. es könnte ein problem geben wenn fhem gerade eine transaction durchführt (dann würde vacuum nicht starten). währen vacuum läuft kann fhem eh nicht in die db schreiben weil das modul fhem (und so das speichern von readings ) blockiert (bitte korrigireren wenn falsche annahme!!!!).
https://www.sqlite.org/lang_vacuum.html
kann man den Vacuum Befehl auch von FHEM automatisch absetzen? oder geht das nur direkt über die shell?
Zitat von: DerFrickler am 16 August 2016, 10:15:24
kann man den Vacuum Befehl auch von FHEM automatisch absetzen? oder geht das nur direkt über die shell?
Damit sollte sich Vacuum aus FHEM aufrufen lassen:
set <name> userCommand "VACUUM history"
Und das ganze jetzt noch per AT:
define DBvacuum at *02:00:00 set <name> userCommand "VACUUM history"
Und schon sollte das jeden Tag um 2 Uhr ausgeführt werden.
Hallo,
Zitat von: justme1968 am 06 August 2016, 16:47:03
noch besser als aufräumen ist erst garnicht loggen.
dem kann ich nur 100% zustimmen, hat mich auch etwas Überlegung und Zeit gekostet, jetzt wird aber nur noch geloggt, was ich haben will, in sinnvollen Zeitabständen für einen Plot usw. und ich überlege mir jedes neue Logging 3x ob und wofür ich es wirklich brauche.
Gruß aus Berlin
Michael
Ich finde mehrere Loginstanzen oftmals praktisch.
Eine DB in der einfach alles geloggt wird, allerdings nur für wenige Tage verbleibt.
Dadurch lässt sich einfacher etwas neues Entwickeln, oder auf Ereignisse reagieren, da man zumindest von den letzten Tage einfach zu allen Werten Logdaten vorliegen hat.
Eine zweite DB in der nur geloggt wird was auch benötigt/geplottet usw. wird.
Das mit zwei Datenbanken macht durchaus Sinn... die meisten Daten können nach 30 Tagen verworfen werden, aber z.B. Zählerstände würde ich gerne zu Vergleichszwecken 2 Jahre aufbewahren. Nur wie verteile ich dann die jeweiligen Readings auf die DBs? Bisher habe ich alles über DbLogInclude geregelt. Die Einträge für die DB mit Zählerstände kann man ja durch
/opt/fhem/DBlog.conf .*:(meterReading_kWh|meterReading_m3|energy_kWh).*
eingrenzen. Nur gibt es eine Möglichkeit die Werte aus der allgemeinen DB herauszuhalten?
Hallo,
Du wirfst eine interessante Frage auf.
Ich filtere in define logdb DbLog ./db.conf (RFM12.*|BME280.*|E3k.*|PIR_S_.:.*|Tierpark:.*unnamed.*) nur die Device-Gruppen, die ich überhaupt haben will.
Die exludes der uninteressanten Werte erfolgt dann bei jedem Device über das Attribut:
DbLogExclude .*state.*|.*consumption.*|.*powerMax.*
DbLogInclude gibt es ja auch noch, allerdings müte man dann wohl im define von DbLog erstmal alles verbieten?
Und jetzt kommt Deine Frage, die auch meine sein könnte: kann ich einem z.B. Device per DbLogInclude sagen, was er wohin loggen soll?
Das wäre dann eine praktische Lösung um z.B. getrennte Tabellen mit ausgewählten Readings zu füllen.
Gruß aus Berlin
Michael
Zitat von: amithlon am 16 August 2016, 20:50:57
DbLogInclude gibt es ja auch noch, allerdings müte man dann wohl im define von DbLog erstmal alles verbieten?
Die Frage kann ich beantworten: Nein. Wenn in der DEF des DBLogs, DbLogSelectionMode auf Include steht, wird nur geloggt, wenn das device ein DBLogInclude-Attribut hat (in dem dann die zu loggenden readings definiert wird).
Ich habe allerdings nur ein DBLog und keine Ahnung, ob ich irgendwie in ein anderes loggen könnte... rein logisch sollte es aber möglich sein, ein Log mit DbLogSelectionMode = Include und eines mit Exclude zu definieren and dann gezielt die readings in eines zu includen und aus dem anderen zu excluden... was aber viel Pflegeaufwand erfordert....
Grüße,
Oli
Zitat von: amithlon am 16 August 2016, 20:50:57
DbLogExclude .*state.*|.*consumption.*|.*powerMax.*
Du musst das nicht so kompliziert als eine zusammenhängende regex schreiben,
lass DbLog einfach mehere regexe daraus machen und schrieb die readings kommagetrennt:
DbLogExclude state,consumption,powerMax
Das sollte DbLogExclude umdrehen und ein Include daraus machen,
DbLogExclude (?!.*Max)(?!state)(.*)
sollte nur "state" und alle readings die mit "Max" enden loggen.
Moin
Ich weiss, Ihr haltet mich fuer verrueckt, aber meine DB hat ca 21Mbyte. Ich wuerde die jetz auch gerne mal eindampfen, aber wie? Hab vorhin mal probehalber reducelog gestartet, aber zu sehen war nichts. (RPI2) Wie kriege ich die am einfachsten klein, und dann wieder mit fhemverheiratet?
Gruss Christoph
P.S.: Ich bin ein echter NOOB was Datenbanken und Befehle angeht!
Wenn Du mysql/innodb verwendest und es dir darum geht, dass die Datei(en) kleiner werden, dann geht das mWn nur über dump - löschen - restore:
http://dev.mysql.com/doc/refman/5.5/en/innodb-resize-system-tablespace.html
Auch ein optimize hilt nicht, im Gegenteil sogar.
Moin
Sorry, ich hatte keine Zeit!
Ich moechte eigentlich reducelog ausfuehren, allerdings gerne ohne dass fhem so lange steht! Deshalb DB-Kopie nehmen (sqlite) einschrumpfen, und dann fhem wieder unterjubeln!
Ich weiss leider auch nicht wie ich mir die DB auf dem RPI ansehen kann! Ich habe zwar einen DB-Browser, aber wie verbinde ich den mit der DB auf dem RPI?
Gruss Christoph
Hallo,
Zitat von: pc1246 am 04 September 2016, 13:36:14
Ich weiss leider auch nicht wie ich mir die DB auf dem RPI ansehen kann! Ich habe zwar einen DB-Browser, aber wie verbinde ich den mit der DB auf dem RPI?
Mein Versuch mit einem DB-Browser unter Windows hat zumindest dafür gesorgt, daß die Datenbank auf dem Pi danach kaputt war...
Muß irgendeine Einstellung der Zeichencodierung gewesen sein, die ich übersehen hatte.
Auf dem Pi per Telnet mit
sudo sqlite3 /opt/fhem/fhem.db
den sqlite-Client öffnen und sich dort auszutoben war dann für mich sicherer...
Man kann natürlich eine Kopie woanders anlegen und dort rumspielen.
Gruß aus Berlin
Michael
Ein herzerfrischendes "Moin" vom "hintern Deich" vorweg!
Einen Wunsch an das DbLog - Modul hätte ich da noch:
Ich hätte gerne ein Reading mit dem Namen DbFileSize welches mir in Byte die Größe der Datei anzeigt.
Das Reading sollte nur kurz vor und kurz nach dem "ReduceLog" bzw. zu "sinnigen" Zeiten aktualisiert werden.
Dann kann man wunderschön die Größe der db-Datei plotten und sehen, inwieweit die Datei aus dem Ruder läuft bzw. wieder schrumpft.
Code-Idee
Filesize($)
{
my $FileName = @_;
my $Filesize = -s $FileName;
}
Gruss
Sailor
Hi Sailor,
ein simples userReading sollte das tun, z.B. in MB:
attr dbLog userReadings DbFileSize:lastReduceLogResult.* { (split(' ',`du -m dbLog.db`))[0] }
Hi Rapster
Zitat von: rapster am 05 September 2016, 14:13:39
ein simples userReading sollte das tun, z.B. in MB:
attr dbLog userReadings DbFileSize:lastReduceLogResult { (split(' ', `du -m dbLog.db`))[0]}
Man bist Du schnell! ;)
OK, jetzt muss ich mir nur einfallen lassen, wie ich den Pfad hinter der Dateigröße loswerde, und schon haben wir es.
Ich denke aber "du-b" ist die Byte-Variante.
Gruß
Sailor
probiers nochmal aus, habs bischen modifiziert, jetzt steht nurnoch die größe da :-)
mir hat es auch gerade geholfen, vielen Dank :-)
So, jetzt habe ich die DB erst mal kopiert. Aber es sind nicht 21 MB sondern 21 GB. Ich wusste gar nicht, dass ich so eine grosse SD-Karte gesteckt hatte!
Jetzt will ich mal sehen, ob ich das irgendwie halbwegs vernuenftig zusammenschrumpfen kann!
Wie lange wuerde das denn auf einem RPI 2 dauern? Nachts brauche ich den ja nicht!
Gruss Christoph
Moin PC
Zitat von: pc1246 am 05 September 2016, 23:24:40
So, jetzt habe ich die DB erst mal kopiert. Aber es sind nicht 21 MB sondern 21 GB. Ich wusste gar nicht, dass ich so eine grosse SD-Karte gesteckt hatte!
Tja ich habe zwangsweise vor 3 Tagen eine Radikalschrumpfkur machen müssen: Nach Stromausfall war nix mehr mit fhem.db.
Und auf das alte Backup wollte nicht. :'(
So habe ich von Null angefangen und werde die wichtigen Daten irgendwie von aus der alten DB in die Neue kopieren müssen. >:(
Gruß
Sailor
Ich hatte das glaube ich schon mal irgendwo geschrieben... ich mache das monatsweise, der Zeitraum lässt sich ja nach Gusto definieren. Bei mir MySQL auf einem externen Win-Rechner, wenn Du MySQL auf dem RPI nutzt kannst Du z.B. mit HeidiSQL drauf zugreifen.
Ich schicke ein Select auf den Zeitraum (z.B. August, jetzt Anfang September):
select * from fhem.history where Timestamp between '2016-08-01' and '2016-08-31'
Die Ergebnisse exportiere ich als SQL-INSERTS in eine entsprechende Datei (z.B. Aug16.SQL)
Denn lösche ich die Datensätze raus
select * from fhem.history where Timestamp between '2016-08-01' and '2016-08-31'
anschließend noch ein Optimize
Zitatoptimize table fhem.history
fertig. Hält meine DB schlank, <60Mb. Wenn ich historische Daten brauche kann ich die jederzeit wieder importieren. Kannst natürlich auch einengen, wenn Du für Jahresüberblicke z.B. Temperaturwerte brauchst:
select * from fhem.history where Timestamp between '2016-08-01' and '2016-08-31' and Device not like 'LaCrosse_2A'
Würde alle Geräte außer dem TempSensor LaCrosse_2A selektionieren (und bei analogem Handeln exportieren und löschen).
Aber: alleine ein optimize table düfte deine DB geschätzt um 30-40% schrumpfen!
Hallo Tedious
Zitat von: Tedious am 06 September 2016, 09:35:55
Die Ergebnisse exportiere ich als SQL-INSERTS in eine entsprechende Datei (z.B. Aug16.SQL)
Ich bin eine absolute Niete bezüglich SQL daher meine Frage:
Wenn ich theoretisch eine zweite DbLog Datei in fhem öffnen würde, kann ich die Daten mittels Usercommand diverse Datensätze (Readings) von fhem_old.db nach fhem.db verschieben?
Gruß
Sailor
Am einfachsten gehts via HeidiSQL, einer kleinen schlanken Workbench für SQL. Du connestest die DB (IP, User, Passwort), generierst die Abfrage - in die Ergebnisse, rechte Maustaste - exportieren (in eine Datei). Am besten als INSERT, denn kannst Du die Inhalte bei Bedart per Mausklick importieren.
(http://www2.pic-upload.de/thumb/31637388/Heidi1.png) (http://www.pic-upload.de/view-31637388/Heidi1.png.html)
(http://www2.pic-upload.de/thumb/31637389/Heidi2.png) (http://www.pic-upload.de/view-31637389/Heidi2.png.html)
Hallo zusammen
Nun habe ich endlich mal wieder Zeit, Urlaub und andere Aktivitaeten sind beendet. Es wird so langsam eng auf meiner SD-Karte, 1,4GB sind noch frei! Da ich ja eine SQlite Datenbank habe, habe ich mal mein Glueck mit phpLiteAdmin versucht. Dummerweise kriege ich beim Oeffnen gleich ein paar nette Fehlermeldungen, mit denen ich dann leider nichts anfangen kann.
Checking supported SQLite PHP extensions...
PDO: installed
PDO SQLite Driver: not installed
SQLite3: not installed
SQLiteDatabase: not installed
Ich verstehe, dass etwas fehlt, aber wo ist mir nicht klar. Koennt Ihr mir auf die Spruenge helfen?
Gruss Christoph
wenn du sql lite hast nutze doch einfach die sqlite befehle (zb direkt aus fehm) oder fhem beenden und über die shell.
zum ausdünnen reducelog im dblog modul und dann "userCommand vacuum" um das file selbst zu verkleinern
Hallo Chris
Ich habe es dann jetzt wirklich geschafft. Ist nur bloed wenn man sich eine offenen DB vom RPI holt. Die ist dann defekt fuer SQLITE. Naja ich habe es geschafft, 1,5 Jahre geloescht, und mit dem DBBrowser komprimiert, Vacuum wollte nicht! Morgen spiele ich die dann auf den RPI, und dann kann ich wieder ruhiger schlafen.
Gruss und Danke nochmals Christoph
Moin
Nun habe ich doch noch ein Problem. Seitdem die "kleine" DB auf dem RPI ist, wird nichts mehr reingeschrieben. Lediglich die .shm ist aktuell. Dblog sagt auch connected, und ein reread config erfolgt auch anstandslos! Ich habe ja kein Problem damit, dass mir jetzt eine Woche fehlt, aber wie kriege ich das loggen jetzt wieder in Gang?
Gruss Christoph
Edit: Beim Plot kann ich auch nichts mehr auswaehlen. Aber die alten Werte, sind noch da!
Och man
Beim kopieren haben sich leider die Dateirechte veraendert, kaum macht man es richtig!
Danke fuer Eure Geduld
Christoph
Moin zusammen
was die Geschichte um das "Vacuum" betrifft habe ich folgendes im Internet gefunden: https://www.tutorialspoint.com/sqlite/sqlite_vacuum.htm
Kann man das auf unsere fhem.db anwenden und was hat das für Konsequenzen?
ZitatAuto-VACCUM
SQLite Auto-VACUUM does not do the same as VACUUM rather it only moves free pages to the end of the database thereby reducing the database size. By doing so it can significantly fragment the database while VACUUM ensures defragmentation. So Auto-VACUUM just keeps the database small.
You can enable/disable SQLite auto-vacuuming by the following pragmas running at SQLite prompt:
sqlite> PRAGMA auto_vacuum = NONE; -- 0 means disable auto vacuum
sqlite> PRAGMA auto_vacuum = INCREMENTAL; -- 1 means enable incremental vacuum
sqlite> PRAGMA auto_vacuum = FULL; -- 2 means enable full auto vacuum
You can run following command from command prompt to check the auto-vacuum setting:
$sqlite3 database_name "PRAGMA auto_vacuum;"
Gruss
Sailor
PS: Obwohl meine Datenbank "nur" 1400MB groß ist, dauert der direkte "VACUUM;" - Befehl in der SQLITE3 - Konsole bei vorher gestoppten fhem Service nunmehr schon 10 Minuten an...
Das kann doch nicht gesund sein, oder?
PSPS: Abgeschlossen und nun ist sie nur noch 910MB groß...
Bitte entschuldigt, dass ich einen so alten Beitrag zitiere.
Bei mir ist die Datenbank mittlerweile auch recht groß und ich möchte mich an das Ausdünnen machen.
Ich möchte das ganze möglichst wenig invasiv auf einzelne Devices beschränken und mir rantasten. Prüfen wie lange es dauert, etc.
Deshalb ist der der Include Parameter für mich interessant:
Zitat von: gero am 29 Oktober 2015, 16:40:25
Vielleicht ist es für viele User verwirrend, dass sie bei include eine Database-deviceRegExp angeben müssen und bei exclude eine Perl-Regexp.
Ich stehe auf dem Schlauch, was eine Database-deviceRegExp sein soll, bzw. warum ich mich als Anwender damit auseinander setzen soll.
Die Regex Syntax unterscheidet sich nach meinem Stand nicht zwischen SQL und Perl.
Für sqlite kann das Paket "Perl regular expressions"
sqlite3-pcre
für sqlite installiert werden.
Wird das im Moment verwendet, wenn es installiert ist? Das Keyword REGEXP habe ich im Quellcode nicht finden können. Demnach nehme ich an, es handelt sich hier um gar keine Regexp sondern um etwas anderes.
Zu dem Thema Blockieren von FHEM, habe ich eventuell auch eine Idee.
Es wäre möglich, die SQL Statements mit einem Limit auszustatten (z.B. immer nur 100 Zeilen) und das ganze über einen internal timer asyncron laufen zu lassen.
Dann wird FHEM zwar in Summe ebenso lange blockiert, aber eben nicht kontinuierlich.
Grüße Sidey
Zitat von: rapster am 05 September 2016, 14:13:39
Hi Sailor,
ein simples userReading sollte das tun, z.B. in MB:
attr dbLog userReadings DbFileSize:lastReduceLogResult.* { (split(' ',`du -m dbLog.db`))[0] }
Funktioniert das nur mit SQLite?
Ich nutze MYSQL und in meinen "lastReduceLogResult" steht nichts von Dateigröße:
Rows processed: 44724, deleted: 0, time: 0.93sec
Gruß Detlef
Zitat von: Sidey am 06 November 2016, 00:51:27
Zu dem Thema Blockieren von FHEM, habe ich eventuell auch eine Idee.
Es wäre möglich, die SQL Statements mit einem Limit auszustatten (z.B. immer nur 100 Zeilen) und das ganze über einen internal timer asyncron laufen zu lassen.
Dann wird FHEM zwar in Summe ebenso lange blockiert, aber eben nicht kontinuierlich.
Versuche aber den Sinn dahinter zu finden,
entweder einmal 10 Minuten Events verpassen,
oder 5 mal 2 Minuten Events verpassen,
...
dazwischen 1ne Minute warten,
um eine Aktion zu starten von der ich in den nächsten 5 Minuten keine Ahnung mehr habe ob da noch was passiert oder nicht
Zitat von: rapster am 22 Dezember 2015, 06:01:05
Moin Sunny,
ja eingefallen schon, nur leider zeitlich noch keine Möglichkeit gehabt... :-\
Denke wird leider auch noch ein bissi dauern, stehn davor noch paar andere Sachen auf der ToDo zu denen ich leider genausowenig komme, aber vergessen hab ichs nicht ;)
Gruß
Claudiu
Hi,
gibt es zum Thema der einstellbaren Intervalle schon was neues?
Ich wäre ebenfalls v.a. an einem 15min-Intervall interessiert.
Grüße
Vergessen hab ichs immer noch nicht, aber das wird wohl trotzdem ein Projekt für ruhige Abende 2017 :-)
Zitat von: rapster am 07 November 2016, 18:18:31
Versuche aber den Sinn dahinter zu finden,
entweder einmal 10 Minuten Events verpassen,
oder 5 mal 2 Minuten Events verpassen,
...
dazwischen 1ne Minute warten,
um eine Aktion zu starten von der ich in den nächsten 5 Minuten keine Ahnung mehr habe ob da noch was passiert oder nicht
Ok, ich sehe es ein. Mein Ansatz war zu kurz gedacht.
Ich habe bestimmt noch nicht alle Programmteile von Fhem verstanden.
Mein Stand ist, dass Fhem periodisch die IO Schnittstellen bedient.
Sozusagen ist Fhem immer blockiert, wenn eine Funktion eines Modules aufgerufen wird. In der Regel benötigen diese Funktionen wohl wenig CPU Zeit, so dass weder der Anwender noch die IO Schnittstellen davon in Mitleidenschaft gezogen werden.
Umgangssprachlich spricht man von blockieren wohl immer dann, wenn FHEM beeinträchtigt wird.
Der Programmcode macht wohl zwei Dinge im Moment:
Eine DB Abfrage stellen und auf die Antwort warten.
Je nachdem wie lange die Abfrage dauert, kann man hier von einem Blocking reden.
Eine relativ einfache Option um langlaufende Abfragen auf non blocking zu migrieren, kann sein, auf die Antwort nicht zu aktiv zu warten, sondern immer periodisch über einen Timer prüfen, ob eine Antwort bereits vorliegt.
Im Falle einer Zusammenfassung von Datensätzen:
Danach werden in Perl die erhaltenen Datensätze verarbeitet. Was da passiert habe ich noch nicht durchdrungen.
Ich nehme an, es wird ein Durchschnitt für eine definierte Zeitperiode errechnet.
Ein Datensatz erhält dann via Update diesen Mittelwert und die anderen werden gelöscht.
Ich bin nicht der absolute Datenbank oder FHEM Spezialist, jedoch nehem ich an, dass man überhaupt keine Messwerte verliert, wenn man die CPU Zeit die bei einem Funktionsaufruf verbraucht wird, drastisch reduziert.
Dazu gibt es zwei Ansätze die mir einfallen:
Berechnungen in die Datenbank verlagern und auf die Antwort ansynchron warten.
Berechnungen in FHEM in kleine Transaktionen unterteilen, die nur wenige ms Andauern.
Wie seht ihr das?
Viele Grüße
ich verstehe ehrlich das problem nicht.
ich fahre jede nacht um 00:10 reducelog 1 ( ca. 6 sek) und danach vaccum (ca 3sek) . meine db ist somit seit geraumer zeit unter ca 50mb groß und nachts stört das blocking nicht. die regelmäßigkeits machts halt (und esparsames loggen)
Zitat von: Sidey am 08 November 2016, 17:24:37
Ok, ich sehe es ein. Mein Ansatz war zu kurz gedacht.
Ich habe bestimmt noch nicht alle Programmteile von Fhem verstanden.
Mein Stand ist, dass Fhem periodisch die IO Schnittstellen bedient.
Sozusagen ist Fhem immer blockiert, wenn eine Funktion eines Modules aufgerufen wird. In der Regel benötigen diese Funktionen wohl wenig CPU Zeit, so dass weder der Anwender noch die IO Schnittstellen davon in Mitleidenschaft gezogen werden.
Umgangssprachlich spricht man von blockieren wohl immer dann, wenn FHEM beeinträchtigt wird.
Der Programmcode macht wohl zwei Dinge im Moment:
Eine DB Abfrage stellen und auf die Antwort warten.
Je nachdem wie lange die Abfrage dauert, kann man hier von einem Blocking reden.
Eine relativ einfache Option um langlaufende Abfragen auf non blocking zu migrieren, kann sein, auf die Antwort nicht zu aktiv zu warten, sondern immer periodisch über einen Timer prüfen, ob eine Antwort bereits vorliegt.
Im Falle einer Zusammenfassung von Datensätzen:
Danach werden in Perl die erhaltenen Datensätze verarbeitet. Was da passiert habe ich noch nicht durchdrungen.
Ich nehme an, es wird ein Durchschnitt für eine definierte Zeitperiode errechnet.
Ein Datensatz erhält dann via Update diesen Mittelwert und die anderen werden gelöscht.
Ich bin nicht der absolute Datenbank oder FHEM Spezialist, jedoch nehem ich an, dass man überhaupt keine Messwerte verliert, wenn man die CPU Zeit die bei einem Funktionsaufruf verbraucht wird, drastisch reduziert.
Dazu gibt es zwei Ansätze die mir einfallen:
Berechnungen in die Datenbank verlagern und auf die Antwort ansynchron warten.
Berechnungen in FHEM in kleine Transaktionen unterteilen, die nur wenige ms Andauern.
Wie seht ihr das?
Viele Grüße
Ja, es hört sich gut an,
nur mir fällt kein Weg ein es irgendwie zu implementieren,
- ohne das am Ende fhem doch durch die DB-Aktion blockiert wird,
- oder das mehrere Verbindungen zur DB geöffnet werden (sqlite)
Evtl. abfragen ob sqlite oder mysql ..., und dementsprechend in eigenem Process starten und eigene DB-Verbindung öffnen?
EDIT, Den Weg sollte mysql Anwender jetzt schon haben, einfach eine zweite fhem Instanz mit der selbe db-conf starten, und in dieser reduceLog aufrufen.
Zitat von: Sidey am 06 November 2016, 00:51:27
Ich möchte das ganze möglichst wenig invasiv auf einzelne Devices beschränken und mir rantasten. Prüfen wie lange es dauert, etc.
Deshalb ist der der Include Parameter für mich interessant:
Ich stehe auf dem Schlauch, was eine Database-deviceRegExp sein soll, bzw. warum ich mich als Anwender damit auseinander setzen soll.
Die Regex Syntax unterscheidet sich nach meinem Stand nicht zwischen SQL und Perl.
Für sqlite kann das Paket "Perl regular expressions" sqlite3-pcre
für sqlite installiert werden.
Wird das im Moment verwendet, wenn es installiert ist? Das Keyword REGEXP habe ich im Quellcode nicht finden können. Demnach nehme ich an, es handelt sich hier um gar keine Regexp sondern um etwas anderes.
Das war glaub ich nur schwierig zu Dokumentieren :)
Include wird direkt bei der DB-Abfrage ausgewertet:
SELECT TIMESTAMP,DEVICE,'',READING,VALUE FROM history WHERE ($a[-1] =~ /^INCLUDE=(.+):(.+)$/i ? "DEVICE like '$1' AND READING like '$2' AND " : '') TIMESTAMP < $cmd ORDER BY TIMESTAMP ASC
WHERE ($a[-1] =~ /^INCLUDE=(.+):(.+)$/iExclude wird im Perl-Code erledigt
Exclude kann auch als Include verwendet werden, einfach die RegExp entsprechend umstellen.
Include bleibt aber Include ;)
Zitat von: rapster am 08 November 2016, 18:39:58
Das war glaub ich nur schwierig zu Dokumentieren :)
Ok verstanden. Ich kenne das unter Like operator und Wildcard operators:
The percent sign represents zero, one, or multiple characters. The underscore represents a single number or character. The symbols can be used in combinations.
Mehr geht da ja nicht, somit verwirrend dass von REGEX in der Doku geschrieben wir.
Include bleibt aber Include ;)
[/quote]
Das Exclude auch die Funktion eines Includes erfüllt verstehe ich. Jedoch müssen dann erst mal alle Datensätze aus der Datenbank geladen werden.
Ich habe mir die Abfrage mal genauer angesehen und ein paar Versuche angestellt:
SELECT TIMESTAMP,DEVICE,READING,VALUE FROM history WHERE DEVICE like 'MYSENSOR_106' AND READING like 'wz.temperature' AND TIMESTAMP < 'NOW() - INTERVAL 30 DAY' ORDER BY TIMESTAMP ASC;
Das dauert in etwa um die 75 Sekunden bei mir. Manchmal auch um die 65.
Eine kleine Optimierung der Abfrage reduziert die Dauer erheblich auf 5-10 Sekunden:
SELECT TIMESTAMP,DEVICE,READING,VALUE FROM history WHERE DEVICE = 'MYSENSOR_106' AND READING ='wz.temperature' AND TIMESTAMP < 'NOW() - INTERVAL 30 DAY' ORDER BY TIMESTAMP ASC;
Ist schon klar, da ja ein genauer Vergleich durchgeführt wird und ich den Like Operator eleminiert habe. Könnte man die Abfrage nicht so anpassen, dass der Like Operator nur genutzt wird, wenn ein % oder _ Operator im Include auch verwendet wird?
Ich hab dann noch ein bisschen weiter experimentiert und auch festgestellt, dass INTERVAL auf eine SQLIte DB nicht unterstützt wird. Aber das ist für meine Tests eher unerheblich gewesen.
Den Mittelwert eines Readings pro Stunde habe ich über Group by und strftime herstellen können:
SELECT TIMESTAMP,DEVICE,READING,VALUE,AVG(VALUE) as AVG_VAL from history WHERE (DEVICE="MYSENSOR_106" and READING="wz.temperature" and TIMESTAMP < datetime('now', '-300 days')) GROUP BY strftime("%d",TIMESTAMP),strftime("%H",TIMESTAMP) ORDER BY TIMESTAMP ASC;
Die Abfrage hat nun unter 3 Sekunden gedauert.Einzige Haken ist, dass wohl immer der Zeitstempel des letzten Readings der Stunde übernommen wird.
Das sieht dann so aus:
2016-01-13 18:57:27|MYSENSOR_106|wz.temperature|21.4|21.5573033707865
2016-01-13 19:56:29|MYSENSOR_106|wz.temperature|21.5|21.4174603174603
2016-01-13 20:56:50|MYSENSOR_106|wz.temperature|21.6|21.5702127659574
2016-01-13 21:45:25|MYSENSOR_106|wz.temperature|21.5|22.2723684210526
2016-01-13 22:18:22|MYSENSOR_106|wz.temperature|21.7|21.6769230769231
Besser wäre natürlich, wenn es eher zum Anfang der Stunde übernommen wird. Da habe ich aber gerade keine Idee, sich das filtern lässt.
Andere Zeitabstände sollten mittel Abfrage auf den timestamp und round Funktion eigentlich auch machbar sein...
Grüße Sidey
ZitatIch habe mir die Abfrage mal genauer angesehen und ein paar Versuche angestellt:
Code: [Auswählen]
SELECT TIMESTAMP,DEVICE,READING,VALUE FROM history WHERE DEVICE like 'MYSENSOR_106' AND READING like 'wz.temperature' AND TIMESTAMP < 'NOW() - INTERVAL 30 DAY' ORDER BY TIMESTAMP ASC;
Das dauert in etwa um die 75 Sekunden bei mir. Manchmal auch um die 65.
Eine kleine Optimierung der Abfrage reduziert die Dauer erheblich auf 5-10 Sekunden:
Code: [Auswählen]
SELECT TIMESTAMP,DEVICE,READING,VALUE FROM history WHERE DEVICE = 'MYSENSOR_106' AND READING ='wz.temperature' AND TIMESTAMP < 'NOW() - INTERVAL 30 DAY' ORDER BY TIMESTAMP ASC;
Ist schon klar, da ja ein genauer Vergleich durchgeführt wird und ich den Like Operator eleminiert habe. Könnte man die Abfrage nicht so anpassen, dass der Like Operator nur genutzt wird, wenn ein % oder _ Operator im Include auch verwendet wird?
Das sollte sich machen lassen um schonmal etwas schneller zu sein, schaue ich mir an
ZitatIch hab dann noch ein bisschen weiter experimentiert und auch festgestellt, dass INTERVAL auf eine SQLIte DB nicht unterstützt wird. Aber das ist für meine Tests eher unerheblich gewesen.
Bei sqlite wird
DATE_SUB(CURDATE(),INTERVAL $a[2] DAY)
statt
NOW() - INTERVAL '$a[2]' DAY
verwendet.
Das Ausmisten über DB eigene Funktionen klingt interessant, die Frage ist nur wer sich dafür opfert das für die verschiedenen DB-Typen zu implementieren :-)
Zitat von: rapster am 09 November 2016, 15:10:15
Das Ausmisten über DB eigene Funktionen klingt interessant, die Frage ist nur wer sich dafür opfert das für die verschiedenen DB-Typen zu implementieren :-)
Für mysql finden sich ja viele Beispiele wie z.B. ein 5 oder 15 Minuten Mittelwert errechnet wird.
Ich eine kleine Demo für sqlite3 und 15 Minuten Intervalle erstellt:
SQLITE Fiddle (15 Minuten Intervalle) (https://sqliteonline.com/#fiddle-582a35b9ccd3c6c5434a5da0eaf2189aad1a9340f58bb41131)
Das Feld EVENT. Da es sich um ein Textfeld handelt, lässt sich mithilfe von Replace aktualisieren.
Grüße Sidey
Ich habe noch ein bisschen weiter darüber nachgedacht.
Folgende Randbedingungen sind mir dabei aufgefallen:
Eine WHERE Abfrage sollte immer so gewählt sein, dass sie den Index nutzt.
Das sind DEVICE, READING und TIMESTAMP
Ablauf des Zusammenfassens
1: SELECT auf die Werte, Gruppieren und Liefern des Mittelwertes
Ich habe meine Beispiel Abfrage dazu um group_concat(VALUE) erweitert. Dadurch werden alle Werte ausgegeben, welche als Mittelwert zusammen gefasst werden. Außerdem habe ich einen Filter auf Device, Reading und Timestamp gesetzt.
SELECT DEVICE,READING, min(strftime(TIMESTAMP)), avg(VALUE) as AVG_VALUE, replace(EVENT,VALUE, avg(VALUE)) as AVG_EVENT, group_concat(VALUE)
FROM history
WHERE DEVICE="MYSENSOR_106" and READING="wz.temperature" and TIMESTAMP>"2016-11-05 00:00:00"
GROUP BY strftime("%d",TIMESTAMP), strftime('%s', TIMESTAMP) / (15 * 60);
Das liefert dann so etwas wie:
MYSENSOR_106|wz.temperature|2016-11-05 20:17:41|20.7666666666667|wz.temperature: 20.7666666666667|20.6,20.9,20.8
2: INSERT der berechneten Werte
Zwecks einfacherer Analyse, habe ich die Werte in eine Tabelle mit dem Namen History2 geschrieben.
Kann man die Werte vielleicht auch einfach in die Tabelle current schreiben? Gibt es einen Prozess der Daten von current nach history verschiebt oder wie läuft das ab?
INSERT INTO history2 ( TIMESTAMP , DEVICE , TYPE , EVENT , READING , VALUE , UNIT )
SELECT min(strftime(TIMESTAMP)), DEVICE, TYPE, replace(EVENT,VALUE, printf("%.1f",avg(VALUE))) as AVG_EVENT, READING, printf("%.2f",avg(VALUE)) as AVG_VALUE, UNIT
FROM history
WHERE DEVICE="MYSENSOR_106" and READING="wz.temperature" and TIMESTAMP>"2016-11-05 00:00:00"
GROUP BY strftime("%d",TIMESTAMP), strftime('%s', TIMESTAMP) / (15 * 60);
3: Die alten Einträge müssen gelöscht werden. An diesem Punkt ist mir aufgefallen, dass wir keinen Primärschlüssel oder eine eindeutige ID haben, mit der wir die Einträge Identifizieren können. Anhand eines Flags können wir auch nicht ausschließen.
Passend zu meinem Beispiel würde das so funktionieren, da ich ja in history2 geschrieben habe:
DELETE FROM history
WHERE DEVICE="MYSENSOR_106" and READING="wz.temperature" and TIMESTAMP>"2016-11-05 00:00:00";
Mit temporären Tabellen bin ich unsicher, ob die nicht zu viel Speicher belegen könnten, der vielleicht nicht vorhanden ist.
Transactions helfen uns meiner Meinung nach auch nicht. Sämtliche Werte in perl zu speichern wollte ich eher vermeiden. Dann können wir es auch in eine Temp Tabelle stecken.
4: Damit die aggregierten Werte wieder in die normale History Tabelle gelangen, reicht ein einfacher Import:
INSERT INTO history ( TIMESTAMP , DEVICE , TYPE , EVENT , READING , VALUE , UNIT)
SELECT * FROM history2;
Grüße Sidey
so, nachdem ich jetzt die Ganzen 17 Seiten durchgelesen habe und keinen Hinweis auf mein Problem gefunden habe poste ich mal:
Wenn ich beispielsweise
set logdb reduceLog 200 average
durchführe, dann bekomme ich immer (egal bei welcher Zahl) zurück:
reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 0.76sec
Meine Datenbank ist mittlerweile rund 1GB groß und beinhaltet Daten von einem Jahr. Es ist eine sqlite3 Datenbank auf einem BananaPi M2+ mit Armbian.
Hat jemand eine Idee was ich falsch mache??
In deiner Datenbank sind keine so alten Daten drin.
Hast du eine Möglichkeit mal reinzuschauen?
Taste dich mal von 200 runter...
Bei 1 ging es dann...
Aber ich versteh nicht genau warum. Ich hatte zwar noch einen Fehler, weil ich alle Filelogs auf DBLogs umgestellt hatte. Also hatte ich rund 40 defines. Das hab ich am Wochenende geändert und nur noch eine logdb mit allen Einträgen definiert. Die Werte waren auch alle noch da. Ist ja auch irgendwie logisch, weil es gibt ja nur ein Datenbankfile und jedes Device schreibt seinen Eintrag dort rein, egal wie das define in FHEM heißt. Naja, jedenfalls hatte ich für die anderen alten defines auch mal den reduceLog Befehl ausgeführt und es hat auch nicht funktioniert. Und die Abfrage nach dem Min-Datum war 15.11.15, also mehr als 300 Tage.
Jetzt hatte ich jedenfalls die Ausgabe:
reduceLog executed. Rows processed: 235891, deleted: 118774, updated: 21459, time: 57.05sec
Also alles OK.
Ich habe bei mir inzwischen das Problem das ich mir keine Plots mehr anlegen kann da die Liste der Readings zu groß wird.
Bei über 7400 Readings kapituliert der Browser. Das sollte man mit zwei Abfragen machen vielleicht, zuerst die Devices und nach Auswahl dessen erst die Readings auslesen. Das sollte die Liste um einiges abspecken.
Eine kleine Änderung habe ich bei mir schon mal vorgenommen, das speckt die Liste auf ca. 500 readings ab.
93_DbLog.pm, Zeile 1995:
my $query = "select device,reading,value from current where device <> '' group by device, reading order by device,reading";
Schaue mir das noch ein wenig weiter an, vielleicht bekomme ich noch etwas optimiert.
Mit Perl hab ich noch nichts gemacht bisher, also mal schauen ;)
deaktiviere die current - tabelle, dann musst du das reading halt von hand eintragen, dafür gehts immernoch problemlos.
Im Script deaktivieren oder wie meinst du?
Sollte aber jetzt auch nicht umbedingt die Lösung sein. Wenn man die Dropdowns nutzen kann ist doch viel schöner ;)
Zitat von: McUles am 01 Dezember 2016, 16:25:25
Sollte aber jetzt auch nicht umbedingt die Lösung sein. Wenn man die Dropdowns nutzen kann ist doch viel schöner ;)
Bei 7400 Readings? Ich denke, da wird dir niemand helfen können ;-)
Ich nutze dafür:
attr DBLdevice DbLogType History
Mit der Änderung die ich oben geschrieben habe, sind es nur noch etwas über 500.
Da sind irgendwie ein paar Dubletten enthalten, warum auch immer.
Aus der Referenz zu reduceLog: "Reduziert historische Datensaetze, die aelter sind als <n> Tage auf einen Eintrag pro Stunde (den ersten) je device & reading."
Besteht auch die Möglichkeit die Datensätze auf 2 pro Tag zu reduzieren? Den Ersten und den Letzten Eintrag?
Gruß und Danke!
Du kannst noch das Schlüsselwort "average" dranhängen, dann wird der Durchschnitt aller numerischen Werte einer Stunde berechnet.
Erster und letzter Wert einer Stunde ergibt für mich nicht wirklich Sinn, was ist da der Hintergrund?
Zitat von: rapster am 08 Dezember 2016, 14:20:48
Erster und letzter Wert einer Stunde ergibt für mich nicht wirklich Sinn, was ist da der Hintergrund?
ganz einfach, die Differenzbildung. Oder im Fall von Zählerdaten die Berechnung des Tagesverbrauchs.
@DerFrickler
dich findet man doch auch überall oder? :D
sry
Zitat von: DerFrickler am 08 Dezember 2016, 14:35:41
ganz einfach, die Differenzbildung. Oder im Fall von Zählerdaten die Berechnung des Tagesverbrauchs.
Sry, evtl. bin ich in dem Thema nicht wirklich drin, aber verstehe den Sinn immer noch nicht :-)
Bsp. Logdaten nach reduLog mit 2 Werten je Stunde:
..
12:59:59 - 10000,00 kWh
13:00:01 - 10000,01 kWh
13:59:59 - 11000,00 kWh
14:00:01 - 11000,01 kWh
14:59:59 - 12000,00 kWh
Welchen Vorteil habe ich wenn der erste und der letzte Wert einer Stunde im Log ist?
Der Stundenverbrauch lässt sich auch nur durch den ersten Wert einer Stunde berechnen...
Zitat von: rapster am 08 Dezember 2016, 14:40:08
sry
Sry, evtl. bin ich in dem Thema nicht wirklich drin, aber verstehe den Sinn immer noch nicht :-)
Bsp. Logdaten nach reduLog mit 2 Werten je Stunde:
..
12:59:59 - 10000,00 kWh
13:00:01 - 10000,01 kWh
13:59:59 - 11000,00 kWh
14:00:01 - 11000,01 kWh
14:59:59 - 12000,00 kWh
Welchen Vorteil habe ich wenn der erste und der letzte Wert einer Stunde im Log ist?
Der Stundenverbrauch lässt sich auch nur durch den ersten Wert einer Stunde berechnen...
Es geht hier um den ersten und den letzten Wert des Tages. Anhand dieser beiden Daten kann man z.B. den Tagesverbrauch ermitteln. Die ganzen Zwischenwerte sind lediglich an dem Tag interessant an dem sie gemessen werden, am Folgetag aber nicht mehr.
Bleiben wir bei Deinem Beispiel:
..
12:59:59 - 10000,00 kWh
13:00:01 - 10000,01 kWh
13:59:59 - 11000,00 kWh
14:00:01 - 11000,01 kWh
14:59:59 - 12000,00 kWh
Bei diesen Daten mag es am selben Tag um 14:00:01 noch interessant sein dass der aktuell gemessene Wert 11000,01 kWh beträgt, am Tag danach sind aber nur die Werte 12:59:59 - 10000,00 kWh und 14:59:59 - 12000,00 kWh von Interesse. Diese ergeben dann den Tagesverbrauch von 12000,00 - 10000,00 = 2000,00 kWh. Wenn man das ganze über zwei Jahre verfolgt (die Vorjahresdaten als Vergleichswert nutzt), dann kommt da schon einiges an Daten zusammen. Und da ich für vergangene Tage lediglich an Tageswerten interessiert bin, reichen der erste und der letzte Wert am Tag.
Im Grunde könnte man jetzt auch weitergehen und den ersten und letzten Wert eines Monats beibehalten um dann den Vormonatsverbrauch zu bestimmen.
Zitat von: McUles am 08 Dezember 2016, 14:39:03
@DerFrickler
dich findet man doch auch überall oder? :D
oder eher nicht... ich bin nicht der von der-frickler.net
Okay, jetzt weiß ich was du vorhast :-)
Aber den Tagesverbrauch kannst du doch auch berechnen wenn du jeweils nur die ersten Werte hast, oder spielt da z.B. delta-d in SVG nicht mit?
07.12.2016 - 00:00:01 - erster Wert 07.12
08.12.2016 - 00:00:01 - erster Wert 08.12
08.12 - 07.12 = Tagesverbrauch.
Was genau ist der Mehrwert, wenn in der DB jetzt noch ein Eintrag am 07.12.2016 - 23:59:59 zu finden ist?
Ich kann es dann in Verbindung mir DbRep und diffValue nutzen.
OK schaue ich mir an, evlt. optional mit Parameter damit reduceLog nach Bedarf den letzten Wert der Stunde bzw. lezten Wert des Tages unangetastet lässt.
Nach Weihnachten aber :-)
eilt nicht, danke!
Hallo,
In meinem Datenhaufen gibt es einige Devices welche oft gleiche Werte haben um dann gelegentlich auf andere Werte wechseln. Z.B. Stromverbrauch ist für einige Zeit 0 und wechselt dann auf irgend einen Wert.
Ich suche eine verlustfreie Methode um die Daten zu reduzieren indem für ein bestimmtes Device alle Konstanten Werte, ausser der erste und letzte gelöscht werden. Noch schicker wäre, wenn bei langen konstanten Phasen, z.B. ein Wert pro Stunde erhalten bleibt.
Da gibt es sicher ein SQL Trick mit JOIN oder ähnlich, aber da bin ich nicht so fit.
Aktuelle Daten begrenze ich mit DbLogExclude und minInterval auf 3600 sec. Schick wäre das aber auf ältere Daten anwenden zu können. Kann mir da jemand auf die Sprünge helfen?
Gruss, Xcoder
Nachdem ich mich durch diesen Thread gekämpft hatte, war für eigentlich nur noch eins von Interesse:
Wie lange braucht denn mein RPI2?
Hier nun einen Anhaltspunkt:
4,4 Millionen Datensätze in 60 min:
Zitat2017.01.10 23:17:25 3: DbLog logdb: reduceLog executed. Rows processed: 4402660, deleted: 4371573, updated: 188917, time: 3289.00sec
Hoffe es hilft dem einen oder anderen :-)
Danke an alle die hierzu beigetragen haben, ein tolles Feature!
Hallo Frickler
Zitat von: DerFrickler am 08 Dezember 2016, 15:05:40
Und da ich für vergangene Tage lediglich an Tageswerten interessiert bin, reichen der erste und der letzte Wert am Tag.
Im Grunde könnte man jetzt auch weitergehen und den ersten und letzten Wert eines Monats beibehalten um dann den Vormonatsverbrauch zu bestimmen.
Hast Du dir schon mal das Modul "ElectricityCalculator" oder "GasCalculator" und dessen Readings angeschaut?
Gruß
Sailor
Hallo,
ein ähnlicher Usecase wie der Stromverbrauch: Meine Fritzbox meldet per TR064 die Internetnutzung (Volumen) in minütlichen Abständen. Aber nur als Tageswerte um Mitternacht wird resetted.
Hier wäre es toll, wenn ich per reduceLog den Max täglichen Wert oder aber stündlichen Wert behalten könnte.
Mein Verständnis ist das dies im Moment nicht geht, oder?
Grüsse
AB1970
set DBLOG reduceLog 10 include=FritzBoxDevice:FritzBoxReading
set DBLOG reduceLog 10 average=day exclude=FritzBoxDevice:FritzBoxReading
So würdest du dein Internetnutzungs Reading auf den ersten Wert jeder Stunde reduzieren und alle anderen Werte in der db auf den Tagesmittelwert. (Ältere Readings als 10 Tage)
Bei der Internetnutzung würdest du die Zeit (readings) seit dem ersten reading nach 23:00 Uhr bis Mitternacht verlieren.
EDIT: nur "average", nicht "average=day" reduziert auf den Mittelwert je Stunde, statt den Tagesmittelwert.
Ich habe mir das Thema Logaggregierung ohne Verarbeitung der Daten in Perl noch mal vorgenommen und das ganze in eine Funktion gepackt.
Vorüberlegungen dazu stehen in meinen Beitrag vom November:
https://forum.fhem.de/index.php/topic,41089.msg522330.html#msg522330
- Ich habe die Abfragen für SQLite erstellt. Die SQL Abfragen sind nicht mit MySQL oder Posrgress kompatibel. Für diese Datenbanken müsste noch etwas erweitert werden.
- 2. Ich habe eine eigene Funktion erstellt, da im DBLog Modul derzeit einige Änderungen laufen und das ganze noch eher in einer Testphase ist.
- 3. Bei mir hat die Funktion exakt das gemacht, was ich wollte. Dennoch solltet ihr das ganze nur an Testdaten ausprobieren.
- 4. Die Funktion avgDBlog erwartet die folgenden 4 Parameter:
- Die Definition des dblog Gerätes. Von hier wird der Datenbanktyp und die Anmeldedaten geholt
- Eine reguläre Expression um sowohl das Gerät und auch das Reading zu definieren, welches verarbeitet werden soll, gefolgt von einem : nachdem die Zeitspanne der Aggregation angegeben wird(1-59 Minuten derzeit möglich)
- Der Zeitstempel, ab dem aggregiert werden soll
- Der Zeitstempel, bis zu dem aggregiert werden soll
- Die Funktion schreibt ein paar Debug Meldungen in das globale FHEM Log
Beispiel eines Aufrufes um alle Geräte, die mit dem Namen
THN beginnen, für das Reading, welches mit
temp beginnt alle 15 Minuten einen Mittelwert bilden. Beim Aufruf müssen alle Parameter angegeben werden. Wird einer weg gelassen, wird das zu fehlern führen.
{ avgDBlog('LoggingDB','THN.*:temp.*:15','2017-01-15 00:00:00','2017-01-15 23:59:59') };
Anbei auch die Funktion:
# Test reload 99_myUtils; { avgDBlog('LoggingDB','THN.*:temp.*:10','2017-01-15 00:00:00','2017-01-15 23:59:59') };
sub avgDBlog
{
# <device-regexp>:<reading-regexp>:<aggregations zeitraum>
my ($dblogdevice,$arg,$tsmin,$tsmax) = @_;
my ($deviceregexp, $readingregexp, $aggregation) = split (":",$arg);
my @devices=devspec2array("$deviceregexp");
if ( InternalVal($dblogdevice,'DBMODEL','unknown') ne 'SQLITE')
{
Log3 "DB AVG:", 3, "Database model from device $dblogdevice is not supported now";
return NULL;
}
my $dbconn=InternalVal($dblogdevice,'dbconn','');
my $dbuser=InternalVal($dblogdevice,'dbuser','');
Log3 "DB AVG:", 3, "params: $deviceregexp, $readingregexp, $aggregation";
# my $dbh = DBI->connect_cached("dbi:SQLite:dbname=/opt/fhem/fhemtest.db", "", "", { PrintError => 0 });
my $dbh = DBI->connect_cached("dbi:$dbconn", $dbuser, '', { PrintError => 0 });
Log3 "DB AVG:", 3, "Connection to db $dbconn established for pid $$";
$dbh->do("CREATE TABLE IF NOT EXISTS history2 (TIMESTAMP TIMESTAMP, DEVICE varchar(64), TYPE varchar(64), EVENT varchar(512), READING varchar(64), VALUE varchar(128), UNIT varchar(32))");
# Schritt 1 - alle Devices abholen, welche $arg ensprechen
my $avg_get=$dbh->prepare(
"INSERT INTO history2 (TIMESTAMP , DEVICE , TYPE , EVENT , READING , VALUE , UNIT)"
." SELECT min(strftime(TIMESTAMP)) as newTS, DEVICE, TYPE, replace(EVENT,VALUE, printf('%.1f',avg(VALUE))) as AVG_EVENT, READING, printf('%.1f',avg(VALUE)) as AVG_VALUE, UNIT"
." FROM history WHERE DEVICE=? and READING=? and TIMESTAMP>=? and TIMESTAMP<=? "
." and NOT EXISTS (SELECT 1 FROM history2 WHERE DEVICE=? and READING=? and TIMESTAMP>=? and TIMESTAMP<=?)"
." GROUP BY strftime('%d',TIMESTAMP),strftime('%s', TIMESTAMP)/ (? * 60)"
);
my $hist_del=$dbh->prepare("DELETE from history WHERE DEVICE=? and READING=? and TIMESTAMP>=? and TIMESTAMP<=?");
my $hist_add=$dbh->prepare("INSERT INTO history SELECT * from history2 WHERE DEVICE=? and READING=? and TIMESTAMP>=? and TIMESTAMP<=? ");
my $hist2_del=$dbh->prepare("DELETE from history2 WHERE DEVICE=? and READING=? and TIMESTAMP>=? and TIMESTAMP<=?");
#my $tsmin='2017-01-15 00:00:00';
#my $tsmax='2017-01-15 23:59:59';
# Schleife über alle gefunden devices um readings zu finden
foreach my $device (@devices)
{
Debug "matched device : ".Dumper($device);
if (defined $defs{$device})
{
foreach my $dreading (keys %{$defs{$device}{READINGS}}) {
Debug "compairing readings for $device reading: $dreading";
if ($dreading =~ $readingregexp) {
Debug " readings $dreading matches";
# Valides Reading gefunden, Daten abfragen und in neue Tabelle einfügen
$avg_get->execute($device,$dreading,$tsmin,$tsmax,$device,$dreading,$tsmin,$tsmax,$aggregation);
Debug "rows added to history2:".$avg_get->rows;
# Datensätze in history löschen
$hist_del->execute($device,$dreading,$tsmin,$tsmax);
Debug "rows deleted from history:".$hist_del->rows;
# Aggregierte Datensätze aus history2 in history eintragen
$hist_add->execute($device,$dreading,$tsmin,$tsmax);
Debug "rows added to history:".$hist_add->rows;
# Datensätze aus history2 entfernen
$hist2_del->execute($device,$dreading,$tsmin,$tsmax);
Debug "rows removed from history2:".$hist2_del->rows;
}
}
}
}
}
Nun zum Unterschied zum aktuellen reduceLog:
1. Es können nur Einträge in der Datenbank zusammengefasst werden, die auch in FHEM existieren. Gleiches gilt für Readings.
Da ich die Geräte und Readings aus FHEM abfrage, benötigt die Funktion wesentlich weniger CPU und IO Ressourcen. Dafür entfällt jedoch die Möglichkeit Daten zu aggregieren, zu denen es keine Gerätedefinition in FHEM gibt.
2. Reducelog verarbeitet alle Datensätze von Begin bis -x Tagen. Es versucht also immer Daten zu aggregieren, die es bereits aggegiert hat.
In dieser Funktion, kann start und ende angegeben werden. Daten die man also schon mal aggregiert hat, braucht man erst gar nicht mehr einlesen.
3. Reducelog lädt alle Einträge von der Datenbank in Perl, verarbeitet die Daten dort, und schreibt diese einzeln wieder in die Datenbank. Die Beigefügte Funktion benötigt immer 4 Datenbank Aufrufe, egal wie viel Daten aggregiert werden. Die Aufrufe werden dann von der Datenbank ohne Perl Beteiligung verarbeitet.
4. Die Zeitspanne für die Aggregation kann von 1-59 Minuten angegeben werden
5. Die Funktion läuft wesentlich schneller ab und kann auch problemlos in einen eigenen Prozess verlagert werden, was FHEM dann nicht mehr blockiert.
Was haltet ihr von diesem Ansatz nun?
Finde ich sehr gut. Sollte nur auch mit MariaDB funktionieren :D
Das Vorgehen ist auch mit MariaDB kompatibel. Es sind nur Syntax Anpassungen der SQL Befehle notwendig.
Zitat
Code: [Auswählen]
set DBLOG reduceLog 10 include=FritzBoxDevice:FritzBoxReading
set DBLOG reduceLog 10 average=day exclude=FritzBoxDevice:FritzBoxReading
So würdest du dein Internetnutzungs Reading auf den ersten Wert jeder Stunde reduzieren und alle anderen Werte in der db auf den Tagesmittelwert. (Ältere Readings als 10 Tage)
Bei der Internetnutzung würdest du die Zeit (readings) seit dem ersten reading nach 23:00 Uhr bis Mitternacht verlieren.
EDIT: nur "average", nicht "average=day" reduziert auf den Mittelwert je Stunde, statt den Tagesmittelwert.
« Letzte Änderung: Gestern um 19:34:26 von rapster »
Hi , erstmal danke für dein Antwort!
Da der letzte Tageswert der Höchste vor dem Reset um 0:00 Uhr ist, darf ich ihn nicht verlieren, da ich ansonsten einen immer größer werdenen Fehler habe.
Allerdings überlege ich mir gerade, ob es vielleicht doch besser ist die Funktion unabhängig von reducelog zu implementieren.
Aber vielen Dank noch mal!
Hallo zusammen,
ich habe ein etwas komisches Problem. Ich habe jetzt seit ein paar Wochen die logDB am Laufen und diese ist mittlerweile knapp 300MB groß. Jetzt habe ich mit reduceLog ... und deleteOldDays 1 alle Daten bis auf die letzten 24h gelöscht. Komischerweise ist die Größe der Datenbank immer noch identisch groß ??? In den Plots sind aber alle Einträge bis auf die letzten 24h verschwunden. Falls in der Datenbank ein Fehler wäre, würde ich einfach eine neue erzeugen. Aber das würde ja das Problem nicht lösen, wenn reduceLog und deleteOldDays nicht richtig funktionieren würde :(
Hatte jemand schon mal das selbe Problem?
Edit: Das Reading countHistory zählt aktuell noch 146887 Einträge ???
Welche Datenbank? sqlite braucht noch ein "VACUUM" um physisch kleiner zu werden, delete alleine hinterlässt "leeren Raum", der mit Vacuum beseitigt wird.
Zitat von: KernSani am 02 Februar 2017, 22:06:22
Welche Datenbank?
SQLite :)
Zitat von: KernSani am 02 Februar 2017, 22:06:22
sqlite braucht noch ein "VACUUM" um physisch kleiner zu werden, delete alleine hinterlässt "leeren Raum", der mit Vacuum beseitigt wird.
Hallo,
danke für die Info. Wie kann ich das VACUUM denn füllen/leeren? Macht das denn sinn oder sollte die Datenbank so groß bleiben, um dann performanter gefüllt zu werden? Vielleicht sollte man die VACUUM-Funktion auch in das FHEM-Modul integrieren :-)
nach einem Vacuum wird die Datenbank physisch nicht kleiner.
Erklärung siehe hier
https://sqlite.org/faq.html#q12 (https://sqlite.org/faq.html#q12)
Nach einem vacuum wird die Datei kleiner - das meinte ich mit "physisch kleiner". In FHEM integriert is vacuum über Dblog userCommand ;-)
Zitat von: KernSani am 03 Februar 2017, 08:55:19
Nach einem vacuum wird die Datei kleiner - das meinte ich mit "physisch kleiner". In FHEM integriert is vacuum über Dblog userCommand ;-)
Also ich habe jetzt folgenden Befehl ausgeführt, aber keine Größenreduktion feststellen können :(
set sys_logdb userCommand VACUUM;
Ist der Befehl richtig?
Zitat von: KernSani am 03 Februar 2017, 08:55:19
Nach einem vacuum wird die Datei kleiner
Zitat von: kumue am 03 Februar 2017, 07:14:07
nach einem Vacuum wird die Datenbank physisch nicht kleiner.
Verstehe ich jetzt leider nicht. Laut deiner Referenz
Zitat von: kumue am 03 Februar 2017, 07:14:07
Erklärung siehe hier
https://sqlite.org/faq.html#q12 (https://sqlite.org/faq.html#q12)
würde ich es auch so verstehen, dass sie kleiner wird :o
Der freie Platz entsteht in der Datenbank. Auf der Platte bleibt die Größe vorerst gleich.
Neue Daten werden in den freien Bereich geschrieben, die DB wächst somit erstmal nicht weiter.
So mein Verständnis, zumal ich selbst feststellte, daß nach einem vacuum der Platz auf der Platte nicht kleiner wurde.
Gibt es denn eine Möglichkeit, die Größe wieder zu reduzieren? Ich bin mit den knapp 300MB noch recht zufrieden. Wenn aber durch einen Fehler die Größe mal auf 1GB oder so ansteigt, möchte ich diese auch wieder verkleinern können ::). Sonst ist irgendwann die SD-Karte voll ;D
Edit: Und noch etwas, dass ich leider nicht verstehe :'(
Ich habe nun auf die Datenbank ein
set sys_logdb reduceLog 14 average
durchgeführt. Dabei hat sich die Datenbankgröße überhaupt nicht geändert, obwohl ich folgende Readings habe:
countHistory: 1877864 (nachher <100 Einträge unterschied, beide male ein count ausgeführt)
lastReduceLogResult: Rows processed: 1556274, deleted: 1501897, updated: 41159, time: 241.00sec
Wenn er 1.5Mio Einträge gelöscht hat, müsste ich es ja auch in den Plots sehen. Aber die Plots, die älter als 14 Tage sind, haben keinen average erfahren. Es sind immer noch alle Punkte vorhanden. Das finde ich extrem komisch :o
Edit2: Irgendwie spinnen bei mir die Datenbanken. Irgendwann war die Datei doch kleiner und Datensätze wurden gelöscht. Einmal Backup einspielen und nochmal probieren. Vieleicht funktioniert es dann ::)
nochmal zum Thema Plattenplatz und Vacuum...
EDIT: Ich mache täglich
reduceLog 90 average=day
und
reduceLog 30 average
und wöchentlich ein VACUUM
Danke, funktioniert jetzt wie gewünscht ;)
Hallo zusammen,
meine "fhem.db" ist knapp 50 GB groß und wollte das nun mal aufräumen bzw. kleiner machen.
Habe
reduceLog 90 average=day
gemacht:
Im Log:
2017.02.07 08:32:18.742 3: DbLog dbLog: reduceLog requested with DAYS=90, AVERAGE=DAY
2017.02.07 08:37:52.222 3: DbLog dbLog: reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 334.00sec
und danach
reduceLog 30 average
Im Log:
2017.02.07 09:06:53.798 3: DbLog dbLog: reduceLog requested with DAYS=30, AVERAGE=HOUR
2017.02.07 09:23:16.028 3: DbLog dbLog: reduceLog executed. Rows processed: 0, deleted: 0, updated: 0, time: 983.00sec
Danach VACUUM. Da ist fhem runtergefahren und das wars.
DbLog nutze ich schon seit ca. 2 Jahren.
Warum steht im Log immer 0?
Wie kriege ich denn das File "fhem.db" kleiner?
Vielen Dank.
Gruß Daniel
Ich hatte die Tage das selbe Problem. Aus mir unbekannten Gründen musste ich mich langsam mit reduce und Tagen runter arbeiten. Das habe ich wie folgt gemacht:
1. Schauen, wann der letzte average Eintrag erstellt wurde, wenn überhaupt jemals erstellt.
Wenn jemals erstellt wie folgt weiter verfahren:
2a. Die Tage von heute bis zu diesem Tag zählen (Gibt gute Seiten im Internet, die das für dich machen)
Wenn noch nie ein reduceLog mit average durchgeführt wurde wie folgt verfahren:
2b. Den ersten Tag der Datenbank nehmen und von heute bis zu diesem Tag die Tage zählen
3. Den Befehl reduceLog mit deinem Wert aus 2a oder 2b - 10 beginnen.
4. Warten und schauen, ob es funktioniert hat (Sieht man, weil die Angaben was gemacht wurde nicht null sind)
Wenn es geklappt hat wie folgt weiter verfahren:
5a. Nun arbeitest du dich weiter runter mit dem Wert des Tages. Ich habe immer mal wieder variiert zwischen 10 - 20 Tagen. Machmal hat es geklappt mehr als 10 zu nehmen, manchmal hat es nicht geklappt.
Wenn es nicht geklappt hat wie folgt verfahren:
5b. Denn Wert aus 2a oder 2b - 5 ausrechnen und damit ein reduceLog und average ausführen. Danach wieder schauen, ob es geklappt hat. Wenn nicht den Wert 5 noch mehr verkleinern.
Der Grund warum es nur so geht erschließt sich mir überhaupt nicht. Aus irgendeinem Grund kann reduceLog scheinbar mit zu vielen Reihen nix anfangen und macht einfach nichts. Ich habe am Ende dann ein at aufgesetzt, welches mir alle 5 Minuten in reduceLog ausgeführt hat. In dem at befand sich eine Berechnung, welche den Wert für reduceLog um eins reduziert hat, bis es einen Stopwert erreichte. Ein Dummy dazu war auch noch nötig. Geht sicher auch besser, aber so sah es bei mir grob aus:
Beispiel:
define reduce_dummy dummy
set reduce_dummy <Wert aus 2a oder 2b>
define reduce_auto at +*00:05:00 {
my $wert = Value("reduce_dummy");
$neu = $wert - 10;
fhem("set reduce_dummy $neu");
if($neu > 50)
{fhem("set DBLog reduceLog $neu average");}
else {Log 1, "Reduce at beenden, ist fertig!"}
}
Der Code ist ungetestet und gerade nur grob aus der Erinnerung.
Hallo alle,
ich möchte meine logfiles auch "ausdünnen" weil mein Fhem ( auf Raspberry Pie ) in letzter Zeit des öfteren schon mal Wegstürzt.
Wenn Ich nun: set fhem-2017-03.log reduceLog 10
eingebe bekomme ich ein "Please define fhem-2017-03.log first" als Antwort.
Wenn ich ein "set Logfile reduceLog 10" eingebe bekomme ich ein
"Unknown argument reduceLog, choose one of absorb addRegexpPart removeRegexpPart reopen"
als Antwort. Was mache ich falsch ?
Leider sind in der Commandref dazu keine direkten Beispiele vergeben und da ich vieles in diesem Thread nicht verstehe,
ist es mir unmöglich die ganzen (gefühlten) 100 Seiten hier zu lesen.
Kann mir da bitte jemand weiter helfen ?
Bis denn dann
Sandman
der Befehl ist für DBLog.
Bei log FILES kannst einfach die alten Dateien löschen-
Jau, vielen Dank Frank.
Ich habe es mir gerade angesehen, DB-Log ist ja eine ganz andere Geschichte :-(
Sieht auf den ersten augenblich sehr kompliziert aus aber auch sinnvoll.
Bis jetzt habe ich die älteren Logfiles die über 40 - 50 MB waren manuell "ausgedünnt"
nun wird mir das aber zuviel arbeit und ich werde über kurz oder lang auf DBlog umstellen müssen.
Hoffentlich bekomme ich das hin.
Nochmals vielen Dank
Bis denn dann
Sandman
Zitat von: rapster am 22 September 2015, 15:58:44
Den benötigten INDEX kannst du mit diesem SQL-Befehl erstellen:
CREATE INDEX index_reduceLog ON history (TIMESTAMP,DEVICE,EVENT);
Hallo!
Mit welcher WHERE-Bedingung werden von der Funktion "reduceLog" die Datensätze selektiert, die gelöscht bzw. akkumuliert werden sollen?
THX
Ich würde gerne das reduce nur für ein Device verwenden. Gibt es eine einfache RegExp mit der ich alles außer einem Device bei reduce exclude angeben könnte? Also ohne alle Devices im exclude Attribut angeben zu müssen? Oder ein include?
Zitat von: Xcoder am 03 Januar 2017, 01:09:53
Hallo,
In meinem Datenhaufen gibt es einige Devices welche oft gleiche Werte haben um dann gelegentlich auf andere Werte wechseln. Z.B. Stromverbrauch ist für einige Zeit 0 und wechselt dann auf irgend einen Wert.
Ich suche eine verlustfreie Methode um die Daten zu reduzieren indem für ein bestimmtes Device alle Konstanten Werte, ausser der erste und letzte gelöscht werden. Noch schicker wäre, wenn bei langen konstanten Phasen, z.B. ein Wert pro Stunde erhalten bleibt.
Da gibt es sicher ein SQL Trick mit JOIN oder ähnlich, aber da bin ich nicht so fit.
Aktuelle Daten begrenze ich mit DbLogExclude und minInterval auf 3600 sec. Schick wäre das aber auf ältere Daten anwenden zu können. Kann mir da jemand auf die Sprünge helfen?
Gruss, Xcoder
Einen ähnlichen Gedanken hatte ich auch und bin bei der Suche auf diesen Thread gestoßen. Gefällt mir, da hier zB die Ventilpositionen und Batteriespannungen von Heizkörpern erhalten bleiben. Außer es gab einen Ausfall, der wäre dann nicht mehr zu erkennen... Sahnehäubchen wäre noch, wenn man diesen Ausfall irgendwie sichtbar machen könnte.
Wäre es möglich, das einzubauen?
Hallo Sandmann,
ZitatBis jetzt habe ich die älteren Logfiles die über 40 - 50 MB waren manuell "ausgedünnt"
hast Du bei FileLog attr nrarchive in Benutzung ?
Gruß
Hans-Jürgen
Hallo,
ich suche eine Möglichkeit den Startzeitpunkt beim reduceLog festzulegen. Also damit nicht alle Einträge vom Anfang der Datenbank täglich aufs neue überprüft werden müssen. Ich erhoffe mir davon eine schnellere Ausführung.
Habe ich die Möglichkeit dafür übersehen?
Vielen Dank.
Ich habe mittlerweile kanpp 15.000.000 einträge .. nachdem ich reducelog mit 90 tagen gemacht habe lief das kurz .. ist auf knapp 14.000.000 Einträge runter und ab da passiert leider nichts mehr .. im log steht dann nach dem befehl "set logdb reduceLog 90 average" folgendes "reduceLog executed. Rows processed: 7100, deleted: 0, updated: 0, time: 0.00sec" irgendwas kommt da nicht hin :D
Schaut euch alternativ mal delSeqDoublets im DbRep an um Sätze zu löschen. Die Funktion behandelt im Gegensatz zu reduceLog auch nichtnumerische Werte und ist einstellbar was den Behandlungszeitraum betrifft.
Commandref bitte vorher genau lesen und vestehen was da passiert !
Grüße
aber damit kann ich ja nur auf einander folgende nicht geänderte werte löschen. ich möchte aber ja genau das was reduceLog eigentlich macht allerdings tut es das bei mir aus unbekannten gründen nicht :/
Gibt es eine Möglichkeit die Zeitspanne zu ändern die reduziert wird? Also das nicht eine Stunde zu einem Wert gemacht wird sondern zb 10 Minuten zu einem Eintrag gemacht werden?
Hallo,
ich habe gerade reducelog ausprobiert, bekomme aber folgenden Fehler:
DBD::mysql::st execute failed: Error writing file '/tmp/MYFGCYoQ' (Errcode: 28) at ./FHEM/93_DbLog.pm line 4205.
Habe ich beim einrichten was falsch gemacht?
FHEM läuft auf einem rpi und die MySQL Datenbank auf einem Qnap Nas
Nein, hast nichts falsch gemacht. Die Lösung liest du hier :
https://forum.fhem.de/index.php/topic,90597.msg830653.html
Idt zwar für Synology, wird für dich aber ebenso zutreffen.
Grüsse,
Heiko
Daumen hoch, genau das wars! Vielen Dank
Hallo zusammen,
seit einigen Wochen habe ich das Problem dass in der Nacht auf Sonntag sich fhem verabschiedet.
Im Mai 3 mal und im Juni auch schon 4 mal.
Folgendes kommt im Log:
Log 13.06.2021
2021.06.13 04:02:13.859 1: SONOS0: Last Listener seems to be died and process started by fhem... stopping Threads and process...
2021.06.13 04:02:13.885 0: SONOS0: Das Lauschen auf der Schnittstelle wurde beendet. Prozess endet nun auch...
2021.06.13 04:02:13.966 1: SONOS4: Restore-Thread wurde beendet.
Ich vermute es hängt daran dass ich immer Sonntags um 4 Uhr ein set dbLog userCommand VACUUM
mache.
Im Device dbLog sehe ich im Reading "userCommand" dass ein VACUMM zuletzt am "2021-05-16 04:00:00" ausgeführt wurde und im Reading "userCommandResult" steht no result.
Folgendes DOIF habe ich:
defmod doif_dbLog DOIF ([02:00])\
(set dbLog reduceLogNbl 30:32 average)\
(configdb reorg 500)\
DOELSEIF ([03:00])\
(set dbLog reduceLogNbl 90:92 average=day)\
DOELSEIF ([04:00|0])\
(set dbLog userCommand VACUUM)
attr doif_dbLog DbLogExclude .*
attr doif_dbLog do always
attr doif_dbLog group Fhem
attr doif_dbLog room 9_09_Einstellungen
attr doif_dbLog wait 0,1800:0
Mache ich hier was falsch? Hat sich hier was geändert? Das lief nun ein paar Jahre ohne Probleme.
Vielen Dank.
Gruß Daniel
Hallo Daniel,
geändert hat sich in DbLog nichts an irgendwelchen Logiken.
Ein Fehlerhinweis diesbezüglich ist ja auch nicht zu sehen.
Führe VACUUM doch mal direkt im DbLog aus. Achte auch darauf dass auf deiner Festplatte/SD-Karte genügend Freiplatz ist und nicht volläuft.
Grüße,
Heiko
Zitat von: DS_Starter am 29 Juni 2021, 22:33:47
Hallo Daniel,
geändert hat sich in DbLog nichts an irgendwelchen Logiken.
Ein Fehlerhinweis diesbezüglich ist ja auch nicht zu sehen.
Führe VACUUM doch mal direkt im DbLog aus. Achte auch darauf dass auf deiner Festplatte/SD-Karte genügend Freiplatz ist und nicht volläuft.
Grüße,
Heiko
Moin Heiko,
habe gestern mal bei dblog das Attribut verbose auf 5 gestellt. Heute Nacht ist fhem wieder runter. Im Log habe ich folgendes:
2021.06.30 03:25:43.545 4: DbLog dbLog -> Number of cache entries reached cachelimit 500 - start database sync.
2021.06.30 03:25:59.730 4: DbLog dbLog -> Number of cache entries reached cachelimit 500 - start database sync.
2021.06.30 03:26:24.644 4: DbLog dbLog -> Number of cache entries reached cachelimit 500 - start database sync.
2021.06.30 03:26:38.075 1: Cannot fork: Cannot allocate memory
2021.06.30 03:26:38.076 1: Cannot fork: Cannot allocate memory
2021.06.30 03:26:38.156 1: Cannot fork: Cannot allocate memory
2021.06.30 03:26:38.157 1: Cannot fork: Cannot allocate memory
2021.06.30 03:26:40.723 4: DbLog dbLog -> Number of cache entries reached cachelimit 500 - start database sync.
2021.06.30 03:26:50.804 1: SONOS0: Last Listener seems to be died and process started by fhem... stopping Threads and process...
2021.06.30 03:26:50.814 0: SONOS0: Das Lauschen auf der Schnittstelle wurde beendet. Prozess endet nun auch...
Moin Daniel,
das ist das wesentliche:
2021.06.30 03:26:38.075 1: Cannot fork: Cannot allocate memory
2021.06.30 03:26:38.076 1: Cannot fork: Cannot allocate memory
2021.06.30 03:26:38.156 1: Cannot fork: Cannot allocate memory
2021.06.30 03:26:38.157 1: Cannot fork: Cannot allocate memory
Dein Hauptspeicher ist aufgebraucht. Hat nicht direkt was mit DbLog zu tun, aber es wird hier eine Kernfunktion von FHEM genutzt um non-blocking zu arbeiten. Dadurch wird aber mehr Hauptspeicher temporär benutzt.
Das kann dir mit anderen Modulen, die diese Funktion nutzen, ebenfalls passieren. Zu "Cannot fork: Cannot allocate memory" gibt es einen eigenen, sehr langen Thread.
Es kommt also darauf an Speicher zu sparen. Möglicherweise reicht es auf eine andere Uhrzeit zu schieben.
Ansonsten könnte helfen das Logging zuvor abzuschalten mit "set <> reopen 3600" und nach dem VACUUM wieder einzuschalten mit "set <> reopen" (nach 1 Stunde wird automatisch weiter geloggt). Während der Zeit bleiben die Daten im Cache und gehen nicht verloren.
LG
Ja, den Thread habe ich schon gefunden. Ich habe nun auch eine Vermutung woran das liegt. Werde ich mir genauer anschauen.
Seit kurzem habe ich eine neue Heizung und das Modul vitoconnect angebunden. Seit dem habe ich auch die Ausfälle.
Trotzdem vielen Dank für deine Unterstützung.
Hallo Heiko,
heute Nacht um 4 ist nach 'set dbLog userCommand VACUUM' fhem wieder weg gewesen. Und es gab kein Speicherproblem. Wenn ich in der Befehlszeile von fhem 'set dbLog userCommand VACUUM' direkt ausführe ist fhem auch weg. Da scheint sich irgendwas geändert zu haben. Vor Mai hatte ich da noch keine Probleme.
Wenn ich aber 'set dbRep vacuum' ausführe habe ich keine Probleme.
Vielen Dank.
Gruß Daniel
ZitatWenn ich aber 'set dbRep vacuum' ausführe habe ich keine Probleme.
Dann nimm DbRep dafür. Die userCommand Implementierung in DbLog ist ohnehin rudimentär. Am Liebsten würde ich sie entfernen, aber um nicht unnötig Unruhe zu erzeugen ist der Setter noch drin.
LG
Mahlzeit,
gibt es evtl. die Möglichkeit die Option average=day zu erweitern, z.B. average=month oder average=year, oder ist die Option sogar vorhanden?
Habe die Tagesdurchschnitte (average=day) der Außentemperatur/rH% der letzten 5 Jahre in der Datenbank.
Eigentlich total unnötig, aber jetzt sind die Daten nunmal da und einfach löschen mag ich die auch nicht :D
Zumindest die Monats- oder Jahresdurchschnittswerte wären noch einigermaßen interessant über die Jahre....
Danke & Gruß
Guten Abend,
Zitatgibt es evtl. die Möglichkeit die Option average=day zu erweitern, z.B. average=month oder average=year, oder ist die Option sogar vorhanden?
Im DbLog werde ich diese Funktion nicht weiterentwickeln. Auswertungen und DB-Pflege sind nach DbRep verlagert. Diese und andere Funktion die nichts mit dem eigentlichen Logging zu tun haben sind nur noch aus historischen Gründen enthalten.
Im DbRep gibt es unter Anderem die Funktion averageValue. Damit kannst du dir den Durchschnitt eines beliebigen Zeitraums berechnen lassen und auch mit einem anderen Ergebnisnamen in die DB reinschreiben lassen. Diesen neuen Namen kannst du dann z.B. in Plots oder DbRep-Auswertungen nutzen.
Die ursprünglich gespeicherten Readings kann man dann löschen (delEntries) wenn sie nicht mehr gebraucht werden.
Grüße,
Heiko
Danke für den Hinweis, werde ich mir anschauen!
Gruss
Beim löschen meiner Daten aus der SQLite db, älter als 6 Tage mit "set myDbLog deleteOldDays 6" erhalte ich folgende Fehlermeldung, dieses 'delEntries' cmd gibt es aber nicht:DbLog myDbLog - WARNING - "deleteOldDays" is deprecated. Please use DbRep "set <Name> delEntries" instead.
Ein 'set myDbLog delEntries 6' liefert Unknown argument, choose one of reduceLog reduceLogNbl reopen rereadcfg count configCheck countNbl deleteOldDays deleteOldDaysNbl userCommand clearReadings eraseReadings addLog listCache addCacheLine purgeCache commitCache exportCache importCachefile
Meine db ist wie folgt definiert:
Internals:
COLUMNS field length used for Device: 64, Type: 64, Event: 512, Reading: 64, Value: 128, Unit: 32
CONFIGURATION ./db.conf
DEF ./db.conf myAstroHome:(RelativerDachwinkel.*|SunAlt|SunAz):.*
FUUID 5c42ee3d-f33f-97bf-1c6f-e923873a5f26a5c8
FVERSION 93_DbLog.pm:v4.12.5-s25394/2021-12-31
MODE asynchronous
MODEL SQLITE
NAME myDbLog
NR 8
NTFY_ORDER 50-myDbLog
PID 14397
REGEXP myAstroHome:(RelativerDachwinkel.*|SunAlt|SunAz):.*
SQLITECACHESIZE 4000
SQLITEWALMODE on
STATE connected
TYPE DbLog
dbconn SQLite:dbname=/opt/fhem/fhem.db
dbuser
HELPER:
COLSET 1
DEVICECOL 64
EVENTCOL 512
OLDSTATE connected
PACKAGE main
READINGCOL 64
TC current
TH history
TYPECOL 64
UNITCOL 32
VALUECOL 128
VERSION 4.12.5
READINGS:
2022-01-03 11:42:10 CacheOverflowLastNum 0
2021-03-08 11:15:27 CacheOverflowLastState normal
2022-01-03 11:42:45 CacheUsage 4
2022-01-03 11:42:10 NextSync 2022-01-03 11:44:10 or if CacheUsage 500 reached
2021-02-21 20:07:36 countCurrent 162
2021-02-21 20:07:36 countHistory 69462
2022-01-03 03:30:00 lastRowsDeleted 0
2022-01-03 11:42:10 state connected
Attributes:
DbLogType Current/History
asyncMode 1
bulkInsert 1
comment SQLite:dbname=/media/usb0/fhem.db
event-on-change-reading none
group SERVER
room Favourites
stateFormat {my $state = ReadingsVal($name,'state','nA'); if ($state ne 'connected') {return '<font color="red"><b>'. $state .'</b></font>'} else {return $state}}
syncInterval 120
userReadings DbFileSize:reduceLogState.* { (split(' ',`du -m fhem.db`))[0] }
verbose 2
Was ist falsch?
Zitat
DbLog myDbLog - WARNING - "deleteOldDays" is deprecated. Please use DbRep "set <Name> delEntries" instead.
In einem DbRep Device ausführen.
LG
Hallo DS_Starter, danke, manchmal sieht man den Wald ja gar nicht.
Ich habe kein DbRep device, werde es also einfach erstmal bei ''set myDbLog delEntries 6'' belassen.
Danke und nachträglich ein frohes Neues auch noch!
Danke und ebenso :)
Zitat von: DS_Starter am 03 Januar 2022, 12:16:22
In einem DbRep Device ausführen.
Muss man denn wirklich jede Zusatzfunktion in ein separates device packen?
Seit 7 oder 8 Jahren funktioniert deleteOldDays bei mir in vielen FHEM Installationen völlig problemlos.
DbRep habe ich bis heute kein einziges Mal gebraucht, deshalb existiert so ein device bei mir nicht.
Warum werde ich jetzt - gefühlt - völlig willkürlich dazu gezwungen, noch ein zusätzliches device in meine Installation zu bringen, nur um die Log-Datenbank klein zu halten?
Zitat
Warum werde ich jetzt - gefühlt - völlig willkürlich dazu gezwungen, noch ein zusätzliches device in meine Installation zu bringen, nur um die Log-Datenbank klein zu halten?
Wirst du nicht. Funktioniert ja wie immer. Aber es gibt Funktionalitäten wie nur bestimmte Devices/Readings (whatever) regelmäßig zu löschen oder bestimmte reduceLog Funktionalitäten, deren Umfang nicht im DbLog weiterentwickelt wird sondern im DbRep. Der User wird darauf hingewiesen dass er diese Möglichkeit hat und nutzen _sollte_, aber natürlich nicht verpflichtet ist.
Wenn ich Dich richtig verstehe, soll deleteOldDays auch weiterhin funktionieren? Dann finde ich aber den Logeintrag komplett irreführend.
"deprecated" bedeutet für mich, dass es entweder sofort oder in absehbarer Zeit nicht mehr funktioniert.
Und das ist schon ein merkwürdiger readingName:
/--/----DELETED_ROWS_HISTORY--
Ja soll auch weiterhin funktionieren.
Es sollte als "veraltet" verstanden werden. Fällt dir eine bessere Wortschöpfung dafür ein ?
Zitat von: DS_Starter am 17 Januar 2022, 11:35:45
Fällt dir eine bessere Wortschöpfung dafür ein ?
outdated
DbLog fhemDbLog - WARNING - "deleteOldDays" is outdated. Please consider use of DbRep "set <Name> delEntries" instead.
Gefällt mir .... ändere ich so ab.
ZitatUnd das ist schon ein merkwürdiger readingName:
Zugegeben ...
Wenn man die Löschung mit den Attr device und reading eingrenzt, wird die Bedeutung eher plastisch, z.B.:
SMAEnergymeter--EinspeisungWirkleistung----DELETED_ROWS_HISTORY--
TYPE/SSCam--EinspeisungWirkleistung----DELETED_ROWS_HISTORY--
Damit erkennt man worauf sich die Löschung bezieht. User können mit einer nachfolgenden Verarbeitung wiederum auswerten
wieviel Datensätze einer bestimmten Device/Reading-Kombination gelöscht wurden etc.
So ist die Bedeutung dieser Zusammensetzung.
Mit dem Attr readingNameMap kann der User aber zum großen Teil auf den Readingsnamen Einfluß nehmen.
Schau Dir mal in der commandref die Beschreibung zu DbRep an.
Und dann bitte weitere Fragen bei Bedarf im richtigen Unterforum stellen, nicht in den Anfängerfragen. Danke.