DBLog - Historische Werte ausdünnen

Begonnen von C0mmanda, 14 September 2015, 18:38:21

Vorheriges Thema - Nächstes Thema

rapster

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

franky08

#136
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
Debian Bookworm auf HUNSN / Debian Bullseye auf 2.ter HUNSN F2F an 2x RaspiB
mit FHEM aktuell
22Zoll ViewSonic als Infodislay (WVC)
3xHMLAN mit vccu, raspmatic_rpi3, HMIP-HCU1

stromer-12

Das sind mehrere Befehle

Gesendet von meinem GT-I9295

FHEM (SVN) auf RPi1B mit HMser | ESPLink
FHEM (SVN) virtuell mit HMLAN | HMUSB | CUL

rapster

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

rapster

#139
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 :)

franky08

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
Debian Bookworm auf HUNSN / Debian Bullseye auf 2.ter HUNSN F2F an 2x RaspiB
mit FHEM aktuell
22Zoll ViewSonic als Infodislay (WVC)
3xHMLAN mit vccu, raspmatic_rpi3, HMIP-HCU1

JoeALLb

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.
FHEM-Server auf IntelAtom+Debian (8.1 Watt), KNX,
RasPi-2 Sonos-FHEM per FHEM2FHEM,RasPi-3 Versuchs-RasPi für WLAN-Tests
Gateways: DuoFern Stick, CUL866 PCA301, CUL HM, HMLan, JeeLink, LaCrosse,VCO2
Synology. Ardurino UNO für 1-Wire Tests, FB7270

gero

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
Odroid C1 - CULV3-868, JeeLink
16 x TX 29 DTH
MAX!: 15x Heizkörperthermostat+, 2x Wandthermostat, 14x Fenserkontakt, 1x Ecotaster
FS20 S4A, FS20IRF, BSB-Heizungssteuerung über Atmega2560
Z-Wave: ZME_UZB1, Fibaro Wall Plug + Motion Sensor

rapster

#143
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

gero

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
Odroid C1 - CULV3-868, JeeLink
16 x TX 29 DTH
MAX!: 15x Heizkörperthermostat+, 2x Wandthermostat, 14x Fenserkontakt, 1x Ecotaster
FS20 S4A, FS20IRF, BSB-Heizungssteuerung über Atmega2560
Z-Wave: ZME_UZB1, Fibaro Wall Plug + Motion Sensor

rapster

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

gero

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
Odroid C1 - CULV3-868, JeeLink
16 x TX 29 DTH
MAX!: 15x Heizkörperthermostat+, 2x Wandthermostat, 14x Fenserkontakt, 1x Ecotaster
FS20 S4A, FS20IRF, BSB-Heizungssteuerung über Atmega2560
Z-Wave: ZME_UZB1, Fibaro Wall Plug + Motion Sensor

rapster

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

gero

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
Odroid C1 - CULV3-868, JeeLink
16 x TX 29 DTH
MAX!: 15x Heizkörperthermostat+, 2x Wandthermostat, 14x Fenserkontakt, 1x Ecotaster
FS20 S4A, FS20IRF, BSB-Heizungssteuerung über Atmega2560
Z-Wave: ZME_UZB1, Fibaro Wall Plug + Motion Sensor

rapster

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