Pi speichert ab ca 450 Messwerten keine Daten in Datenbank

  • Hallo,

    ich habe ein recht merkwürdiges Phänomen:

    Ich habe ein Programm geschrieben, dass die Sensordaten von einem DS1820 w1 Sensor ausliest,
    und diese in eine Datenbank abspeichert. Zwischen auslesen und abspeichern ist noch eine Methode, die überprüft ob der Messwert innerhalb eines Messwertbereiches ist.

    Nun ist es so, dass nach ca. 450 Messwertdaten die in der sqlite Datenbank liegen, einfach keine neuen mehr dazukommen. Das Messwertprogramm ist nach Pseudocode folgendermaßen aufgebaut

    Messen()
    {

    while (1)
    {
    double Temperatur = Temp(); // Funktion für Sensoransteuerung

    if (Temperatur <= 15)
    cout << "Es ist kalt draußen" <<endl;
    else
    speichern(Temperatur); // Funktion zum Speichern des Messwerts

    usleep (ca. 150 Sekunden)

    }
    }

    Kann man diese Funktion irgendwie sinnvollerweise überprüfen und in .log Dateien speichern?
    Weiß nicht genau wo es nach 450 Messungen scheitert.

    Gruß
    Julian

  • Pi speichert ab ca 450 Messwerten keine Daten in Datenbank? Schau mal ob du hier fündig wirst!

  • Hallo Julian,

    vor zwei oder drei Tagen hat jemand das gleiche Problem bereits schon einmal geschildert.

    Da kamen wir zu dem Ergebnis, dass die Datenbank jedes Mal neu geöffnet wird, wenn etwas hineingeschrieben werden soll. Die Datenbank wird aber nie geschlossen. Und irgendwann ist dann das Limit offener Filehandle erreicht.

    Sag' mal: Schreibt Ihr eigentlich alle von der gleichen Quelle ab - und macht Euch keine Gedanken über den Code? :s Sowas kann schnell ins Auge gehen, wenn Ihr da irgendwelche Libraries nutzt, die dann doch Schad-Code verbreiten... =(


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (10. Januar 2015 um 21:00)

  • Hallo,
    vielen Dank für Eure Antworten.

    Ich habe nach jedem SQLStatement aus dem externen Libary ein FreeQuery(); Aufruf.
    Ich dachte damit inbegriffen sei automatisch ein close(); Befehl.

    Habe nochmal RTFM gemacht und gesehen, dass es eine seperate close() Methode gibt.
    Hab sie nu mal eingebaut und schaue, ob das Phänomen wieder auftritt.

    Besten Dank!

    Gruß
    Julian

  • Das Phänomen trat doch leider wieder auf :stumm:

    Hier etwas Programmquellcode:

    Methode SaveData erhält von Methode Measure die ID, Messwerte sowie Zeitangaben und speichert diese ab.
    Genutzt wird für die Datenbankanbindung das Sqlite3 Wrapper Kompex

    Methode Measure erhält nur eine ID.
    Es existiert eine dauerhafte while Schleife die für einen benutzerdefinierten Zeitraum pausiert wird.
    Die Methode Measure bezieht Sensordaten direkt aus den Auslesemethoden und prüft einige Messwerte mittels der Methode CheckValues, ob diese in einem bestimmten Intervall liegen. Anschließend werden die Daten mittels SaveData in die Methode übergeben und dort abgespeichert.

    Die Datenbankstruktur sieht so aus:

    Code
    -- Describe MESSWERTE
    CREATE TABLE messwerte (ID INTEGER NOT NULL PRIMARY KEY, tempout REAL NOT NULL, tempin REAL NOT NULL, humidity REAL NOT NULL, time TEXT NOT NULL, date TEXT NOT NULL, datetime TEXT NOT NULL)


    Bin über jeden Hinweis dankbar!

  • Kriegen wir ein SQL-Dump mit Daten? Kannst du sagen wieviele Datensätze drinnen sind und was die höchste ID-Nummer ist. Ich glaub, dass das Limit sei durch vieles Inserten und Deleten ausgeschöpft wurde und ein BigInt helfen kann.

  • Hallo Julian,

    also, ich bleibe bei meiner Behauptung: Problem durch unzählige offene Filehandles.

    Schau mal:

    Wenn FreeQuery() und Close() innerhalb try stattfinden würde, dann wäre max. ein einziger Filehandle offen. In der von Dir geschriebenen Form bin ich mir gar nicht sicher, was passieren müsste, dass es überhaupt einmal (= ein einziges Mal) zu einem FreeQuery und / oder Close() kommen könnte.

    Bewege den Leuchtbalken ganz nach links vor die beiden Zeilen und drücke jeweils ein paar mal auf die Tabulator-Taste - bis der Cursor linksbündig mit pStmt positioniert wird.

    Dann teste nochmal.

    Wenn Du die Delay-Zeit reduziert, dann bekommst Du ein schnelleres Resultat als erst nach zwei Tagen. Fürs Testen ist das ganz positiv...


    Beste Grüße

    Andreas

    P.S.: Anzahl der von mir programmierten Python-Zeilen: 0

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (12. Januar 2015 um 17:30)

  • Hallo Andreas,

    vielen Dank für Deine Rückmeldung.
    Aus Deiner Antwort werde ich leider nicht so ganz schlau, was das zu bedeuten hat?
    Leider ist dein zitierter Quellcode auch bisschen verschoben (bei meinem auch ja).
    Soll ich den FreeQuery() und Close() Befehl ausserhalb von try ausführen?

    Gruß
    Julian

  • Hallo Julian,

    so wie der Quellcode aussieht, werden FreeQuery() und Close() außerhalb jeglicher Prozedur durchgeführt (Haupt-Ebene?). Die beiden Befehle müssen zusammen mit den anderen pStmt->... ausgeführt werden, also so:

    Code
    ...
            pStmt->ExecuteAndFree();
            pStmt->FreeQuery(); //
            pDatabase->Close(); //
    ...

    Die Programmiersprache Püdhong scheint sehr empfindlich darauf zu reagieren, in welcher Spalte eine Zeile das erste Zeichen hat, das kein Leerzeichen oder Tabulator-Zeichen ist.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

  • Hallo Julian,


    Aber hier handelt es sich nicht um Python, sondern um c++ :)

    :) sag ich doch: Püdhong! :cool:

    Aber bei c++ dürfte es solche Effekte nicht geben.

    Dann berichte mal, was dann dabei herauskommt.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (12. Januar 2015 um 18:38)

  • Habe es mal mit dem Einrücken probiert. Jedoch wie erwartet bliebt die Lösung aus.

    Habe Messwerte mit 2 Sekunden Pause genommen.
    Erste Durchführung ging bis Messwert 508
    Zweite Durchführung (basierend auf bisheriger Datenbank) ging bis 1017 (also 509 im zweiten Durchgang)

    Aber habe mal das Terminal offen gelassen und folgende Fehlermeldung erhalten:

    Code
    Exception Occured
    file: src/KompexSQLiteStatement.cpp
    line number: 87
    error: unable to open database file
    SQLite result code: 14
    Fehler beim Oeffnen der Datei
    wiringPiSetup: Unable to open /dev/mem: Too many open files

    Einmal editiert, zuletzt von julianpe (12. Januar 2015 um 20:36)


  • Ich bin kein Fan von OO. Aber gehört nicht zu jedem <new> ein <delete>?

    Beziehst du dich auf ?

    Code
    // Öffnet vorhandene Datenbank "wetterstation.db"
            Kompex::SQLiteDatabase *pDatabase = new Kompex::SQLiteDatabase("/home/pi/wetterstation/wetterstation.db", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0);
            // Erstellt statement Zeiger
            Kompex::SQLiteStatement *pStmt = new Kompex::SQLiteStatement(pDatabase);

    Dachte dies würde über die close() Funktion gelöscht. Aber wie Du sagtest, sollte theoretisch ein delete pDatabase und delete pStmt kommen.

    Werde es mal testen. Vielen Dank!

  • New erstellt normalerweise ein Objektz. Dabei wird der Objekt Konstruktor ausgeführt: z.b initialisieren von variablen, reservieren von Speicher, öffnen von files.

    Der Destruktur, ausgeführt beim Löschen des Objekts, räumt alles wieder weg. ...

    OO ist OK wenn er moderat eingesetzt wird. Außerdem kann/sollte man sich bei OO deutlich besser einlesen/einlernen [/code]Meine Meinung;)

  • Halo Julian,

    Code
    Too many open files

    na, was sage ich denn die ganze Zeit. Jede Datei, die geöffnet wird, muss auch geschlossen werden, sonst bricht jedes Programm früher oder später ab.

    Aber das Programm hat Dir ja glücklicherweise die Zeilennummer der fehlerhaften Zeile mitgeteilt. Daran kannst Du erkennen, welche Datei denn da geöffnet werden sollte. Wenn diese Datei bereits vorher geöffnet, aber nicht geschlossen wurde, dass hast Du den Übeltäter...


    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (14. Januar 2015 um 22:37)

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!