Autor Thema: DBLog -- DBD::mysql::st execute failed: Duplicate entry  (Gelesen 277 mal)

Offline kadettilac89

  • Hero Member
  • *****
  • Beiträge: 1147
Hallo Heiko,

Beim Import stört das nicht wenn du in der DB history einen primary key gesetzt hast, sodass keine doppelten Datensätze entstehen. (Ich glaube den hast du wenn ich mich nicht irre.)

Auf diese Diskussion hin hatte ich nun Zeit und wollte mir mein Setup nochmal ansehen.

Ich hatte mal einen Index drauf, der ist aber durch Migrationen oder Neuinstallation scheinbar verschwunden. Ich habe dann versucht, den Standard-Index "Search_Idx" auf "unique" zu setzen. Dann ist es nicht möglich Sätze einzufügen obwohl diese schon vorhanden sind. Soweit der Plan. Es gab etliche Dubletten. Nach aufräumen habe ich nun dem Index ein Unique aufgezwungen.

Nun erhalte ich aber bei regelmäßig Probleme wegen doppelten Einträgen. Wenn ich den Cache mit den Sätzen nach dem Fehler ansehe sind da Sätze drin die auch schon auf der DB sind. Sollte nicht sein oder? List des Devices s. unten, und 4 Fälle sowie Log im Verbose-Level 5 sind im angehängten Archiv. History.csv ist jeweils was vom Cache schon auf der DB ist. Auffällig ist, dass es bei den 4 Fällen die ich näher angesehen habe immer mit addLog-Einträgen ist. Addlog mach ich stündlich.

Solange der Cache einen doppelten Satz enthält wird auch später nichts mehr auf die DB geschrieben, der Cache wächst und wächst.

Ich kann sicher mit der Comitsteuerung die als Attibut vorliegt das Problem sicher lösen, aber mich würde die Ursache interessieren, dich sicher auch.

Was mit auch noch aufgefallen ist, wenn ich "set myDbLog exportCache" per "at" einplane dann funktioniert es, wenn ich das aber im Timer-Modul (88_Timer.pm) einplane dann ist die Date zwar vorhanden, jedoch 0-KB groß, trotz Cache > 0. Idee? Wenn nicht mach ich ggf. einen eigenen Post dazu.

Internals:
   COLUMNS    field length used for Device: 64, Type: 64, Event: 512, Reading: 64, Value: 128, Unit: 32
   CONFIGURATION ./db.conf
   DEF        ./db.conf .*:.*
   FUUID      5c575e13-f33f-4fe4-58eb-90f49cbf9c65024a
   FVERSION   93_DbLog.pm:v4.9.10-s21087/2020-01-31
   MODE       asynchronous
   MODEL      MYSQL
   NAME       myDbLog
   NR         35
   NTFY_ORDER 50-myDbLog
   PID        3654
   REGEXP     .*:.*
   STATE      connected
   TYPE       DbLog
   UTF8       1
   dbconn     mysql:database=fhem;host=mysql;port=3306
   dbuser     fhem
   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.9.10
   Helper:
     DBLOG:
       countHistory:
         myDbLog:
           TIME       1584866460.17094
           VALUE      943201
         myDbLogRemote:
           TIME       1584866460.1715
           VALUE      943201
   READINGS:
     2020-03-22 10:20:44   CacheUsage      2
     2020-03-22 10:20:25   NextSync        2020-03-22 10:23:55 or if CacheUsage 500 reached
     2020-03-21 20:53:02   countCurrent    0
     2020-03-22 09:41:00   countHistory    943201
     2020-03-22 10:07:59   lastCachefile   /opt/fhem/backup/db/cache_myDbLog_2020-03-22_10-07-59 (13 cache rows exported)
     2020-03-22 10:20:25   state           connected
Attributes:
   DbLogInclude countHistory
   DbLogSelectionMode Include
   asyncMode  1
   bulkInsert 1
   cacheEvents 1
   comment    valuefn { if ($DEVICETYPE eq 'speedtest' && $READING eq 'ping' && not $VALUE =~ /^-?\d+(?:\.\d+)?$/) { $VALUE = 0; } }
event-on-change-reading
countHistory,state,CacheUsage,background_processing_time
   event-on-change-reading countHistory,state,CacheUsage
   expimpdir  /opt/fhem/backup/db/
   group      DB-Log
   room       Server
   showNotifyTime 0
   showproctime 0
   syncInterval 210
   valueFn    {  if ($DEVICE eq 'speedtest' && $READING eq 'ping' && not $VALUE =~ /^-?\d+(?:\.\d+)?$/) { $VALUE = 999; } }
   verbose    5
« Letzte Änderung: 22 März 2020, 12:33:07 von kadettilac89 »

Offline DS_Starter

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5766
Antw:DBLog -- DBD::mysql::st execute failed: Duplicate entry
« Antwort #1 am: 22 März 2020, 12:21:43 »
Moin,

Zitat
Nun erhalte ich aber bei regelmäßig Probleme wegen doppelten Einträgen. Wenn ich den Cache mit den Sätzen nach dem Fehler ansehe sind da Sätze drin die auch schon auf der DB sind. Sollte nicht sein oder?

und

Zitat
Solange der Cache einen doppelten Satz enthält wird auch später nichts mehr auf die DB geschrieben, der Cache wächst und wächst.
Ich kann sicher mit der Comitsteuerung die als Attibut vorliegt das Problem sicher lösen, aber mich würde die Ursache interessieren, dich sicher auch.

Ja, ich kenne auch schon den Grund bzw. Lösung.  :)
Das Modul unterstützt einen primary Key, nicht den unique Key.
Wird der Key nicht erkannt, verwendet DbLog den "normalen" Schreibmodus.
Man sieht es auch schön im Log:

2020.03.22 08:30:10.510 4: DbLog myDbLog -> ################################################################
2020.03.22 08:30:10.510 4: DbLog myDbLog -> ###      New database processing cycle - asynchronous        ###
2020.03.22 08:30:10.510 4: DbLog myDbLog -> ################################################################
....
2020.03.22 08:30:10.526 4: DbLog myDbLog -> Primary Key used in history: none
2020.03.22 08:30:10.526 4: DbLog myDbLog -> Primary Key used in current: none
....

Der Cache wächst weil die Daten im Normalfall als Transaktion behandelt werden, alle oder keine. Mit dem commitMode -Attribut kann man das steuern, kennst du ja schon.

Du müsstest also einen PK anlegen, dann passt das.

Zitat
Was mit auch noch aufgefallen ist, wenn ich "set myDbLog exportCache" per "at" einplane dann funktioniert es, wenn ich das aber im Timer-Modul (88_Timer.pm) einplane dann ist die Date zwar vorhanden, jedoch 0-KB groß, trotz Cache > 0. Idee? Wenn nicht mach ich ggf. einen eigenen Post dazu.
Nee, keine Idee. Würde mich aber auch interessieren weil ich mir das neue Timer-Modul auch mal anschauen wollte.
Wenn du einen neuen Thread aufmachst sehe ich das ja.

LG,
Heiko
ESXi 6.5 @NUC6i5SYH mit FHEM auf Debian 10, DbLog/DbRep mit MariaDB auf Synology 415+
Maintainer: SSCam, SSChatBot, SSCal, DbLog/DbRep, Log2Syslog, SMAPortal, Watches, Dashboard
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Offline kadettilac89

  • Hero Member
  • *****
  • Beiträge: 1147
Antw:DBLog -- DBD::mysql::st execute failed: Duplicate entry
« Antwort #2 am: 22 März 2020, 12:33:59 »
werde ich testen ... dachte mit dem unique sollte es auch funktionieren. Zum anderen Thema mache ich einen eigenen Post ..

danke dir

Offline DS_Starter

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5766
Antw:DBLog -- DBD::mysql::st execute failed: Duplicate entry
« Antwort #3 am: 22 März 2020, 12:37:08 »
Zitat
dachte mit dem unique sollte es auch funktionieren
Solltest du Statements kennen, die eine Unique key sowohl bei MySQL, als auch bei SQLite und PostgreSQL sicher erkennen, kann ich auch dafür eine Unterstützung einbauen. Momentan nur PK.
ESXi 6.5 @NUC6i5SYH mit FHEM auf Debian 10, DbLog/DbRep mit MariaDB auf Synology 415+
Maintainer: SSCam, SSChatBot, SSCal, DbLog/DbRep, Log2Syslog, SMAPortal, Watches, Dashboard
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Offline kadettilac89

  • Hero Member
  • *****
  • Beiträge: 1147
Antw:DBLog -- DBD::mysql::st execute failed: Duplicate entry
« Antwort #4 am: 22 März 2020, 15:03:12 »
Solltest du Statements kennen, die eine Unique key sowohl bei MySQL, als auch bei SQLite und PostgreSQL sicher erkennen, kann ich auch dafür eine Unterstützung einbauen. Momentan nur PK.

Mit meiner Antwort "mit dem unique sollte es auch funktionieren" meinte ich auf der DB die dubletten zu verhindern. Ich hatte deinen Code nicht angesehen wie du prüfst.

Meinst du sowas s. u.? Müsste reichen um zu prüfen ob ein unique-Index über die 3 Felder existiert. Ob zuverlässig weiß ich nicht, könnte releaseabhängig sein. Ist aber mehr als nur ein einfacher Select, du müsstest prüfen ob die Felder mit unique vorkommen. Und bei allen 3 DB-Typen unterschiedlich. Ob es lohnt musst du entscheiden :)

MySQL

show index from history

Im Ergebnis gibt es eine Spalte "Non_Unique" die besagt ob der Index "Unique" ist. Ich denke damit wird alles zurückgeliefert, Name, Felder, Sequence ...

Postgresql

feld "indexdef" in Tabelle "pg_indexes". Da ist die Information als Text in dem einen Feld. String "unique" und felder sind auch drin. Link s. u. ...
https://www.postgresqltutorial.com/postgresql-indexes/postgresql-list-indexes/

SQlite

Ähnlich MySQL

Select * FROM sqlite_master AS o,
       pragma_index_list(o.name) AS p,
       pragma_index_info(p.name)
 WHERE o.type = 'table'
 ORDER BY tbl_name, seqno;
https://www.sqlite.org/pragma.html#pragma_index_list


Btw.: das Problem mit dem Timer-Modul habe ich gelöst. Ich mache commitCache und im Anschluss direkt ein export_Cache, da ist scheinbar der erste Befehl noch nicht ganz abgearbeitet bevor ich exportieren will. Mit einem Sleep 1 zwischen beiden Befehlen funktioniert es. Hat nichts mit Timer-Modul zu tun.

Offline DS_Starter

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5766
Antw:DBLog -- DBD::mysql::st execute failed: Duplicate entry
« Antwort #5 am: 22 März 2020, 15:13:56 »
Ja danke, ich schau mal. Ist eben die krux, gibt nichts einheitliches.  :(
Hatte auch schonmal geforscht, war aber irgendwie stecken geblieben. Vielleicht hatte ich damals einfach keine Lust mehr.  ::)

LG,
Heiko
ESXi 6.5 @NUC6i5SYH mit FHEM auf Debian 10, DbLog/DbRep mit MariaDB auf Synology 415+
Maintainer: SSCam, SSChatBot, SSCal, DbLog/DbRep, Log2Syslog, SMAPortal, Watches, Dashboard
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter

Offline kadettilac89

  • Hero Member
  • *****
  • Beiträge: 1147
Antw:DBLog -- DBD::mysql::st execute failed: Duplicate entry
« Antwort #6 am: 22 März 2020, 15:55:31 »
Wird jetzt etwas OT aber ... was spricht dagegen per Default
- den Suchindex immer als Primary-Key anzulegen? Schon im Script beim anlegen der DB?
- den Insert immer mit Zusatz "ignore" zu machen?

Doppelte Sätze mit gleichem TS kann Fhem sowieso nicht korrekt verarbeiten. Zumindest nicht in Plots. Und auch so ... wie soll ein Reading zum selben Zeitpunkt unterschiedliche Werte besitzen ... "Schrödingers Katze" :)

Dadurch wäre die Datenqualität sichergestellt und der Sourcecode einfacher.

Offline DS_Starter

  • Developer
  • Hero Member
  • ****
  • Beiträge: 5766
Antw:DBLog -- DBD::mysql::st execute failed: Duplicate entry
« Antwort #7 am: 22 März 2020, 16:24:37 »
Zitat
Wird jetzt etwas OT aber ... was spricht dagegen per Default
- den Suchindex immer als Primary-Key anzulegen? Schon im Script beim anlegen der DB?
- den Insert immer mit Zusatz "ignore" zu machen?
Nichts denke ich. Dann würde auch automatisch ignore greifen, muss man sonst nichts ändern.
Müsste man nochmal durchdenken ...
Mit verbose 3 (Standard) gibt es dann immer Warnungen. Ist nicht schlimm -> verbose 2 einstellen, aber gerade Anfänger sind dann mit Sicherheit irritiert und glauben etwas falsch gemacht zu haben. Das erhöht vermutlich wieder die Frequenz der Meldungen hier und den Supportaufwand.

Zitat
Und auch so ... wie soll ein Reading zum selben Zeitpunkt unterschiedliche Werte besitzen
Naja, ist nicht ganz richtig. Wir haben ja als kleinste Zeiteinheit 1 Sekunde. Änderungen die unter einer Sekunde liegen sind somit "gleich", wobei nciht wirklich korrekt wenn man Millisekunden berücksichtigen würde.
Aber das wohl eher eine theoretische Betrachtung ...

 
ESXi 6.5 @NUC6i5SYH mit FHEM auf Debian 10, DbLog/DbRep mit MariaDB auf Synology 415+
Maintainer: SSCam, SSChatBot, SSCal, DbLog/DbRep, Log2Syslog, SMAPortal, Watches, Dashboard
Kaffeekasse: https://www.paypal.me/HMaaz
Contrib: https://svn.fhem.de/trac/browser/trunk/fhem/contrib/DS_Starter