ja... Hier habe ich den Zeichensatz bei der Exportfunktion nicht korrekt gewählt.
Ankündigung
Einklappen
Keine Ankündigung bisher.
AI - Spalte ändert sich bei UPDATE
Einklappen
Neue Werbung 2019
Einklappen
X
-
Zitat von olruebe Beitrag anzeigen@chorn: Ich habe keine 441 Datensätze! Es bleiben 15 Stück. Nur die ID steigt auf 441 an, wobei 441 nur ein Beispiel ist. Je länger ich warte, desto höher steigt die ID.
Kommentar
-
Zitat von chorn Beitrag anzeigenPerry Staltic die Anzahl und Zusammensetzung der Keys hat er doch schon längst revidiert:
Erschliesst sich mir nicht, warum er einen davon ignorieren sollte.
Ja er hat 2 (unique) Keys, hab ich was anderes geschrieben?
Ich spreche davon, dass sein Konstrukt laut Doku genau das macht, was dokumentiert ist.
Gemäß Doku verhält sich mysql so, wie der TE es beschreibt. Die AI werden hochgezählt, obwohl "nur ein Update " durchgeführt wird.
Es ist also aus mysql Perspektive alles so, wie es sein soll. Leider ist es nicht das, was der TE möchte.
Deswegen habe ich ihm empfohlen, sein Datenmodell zu ändern und seinen Insertprozess anzupassen.
Vielleicht muss nicht beides sein, mir erschließt sich aber nicht, warum er 2 eindeutige Keys braucht. Daher kann ich da keine Empfehlung abgeben. Durch die Aussage, dass er Innodb einsetzt, ist immerhin klar, dass alles nach Vorgabe läuft.
Probehalber kann olruebe ja die Engine tauschen, dann sollte es ja so laufen wie er es will. Aber damit handelt er sich vielleicht andere Dinge ein, die nicht empfehlenswert sind.
Engine, Datenmodell, Insertprozess, eins davon muss minimal angefasst werden.
Kommentar
-
@erc: Die ID ändert sich. Wenn ich die Tabelle leere und dann meine Scanner starte, bekomme ich zunächst 15 Datensätze mit den IDs 1-15. Nach 3 Minuten habe ich dann immernoch 15 Datensätze, jedoch mit IDs zwischen 1 und 441.
@ Perry Staltic: Ich sehe das anders. Es macht eben gerade NICHT, was die Doku sagt.
The effects are not identical for an InnoDB table where a is an auto-increment column. With an auto-increment column, an INSERT statement increases the auto-increment value but UPDATE does not.but UPDATE does not.
Gegen Deine Theorie, dass alles so korrekt ist, spricht auch die Tatsache, dass die ID nicht bei jedem Update hochzählt. JEDER Datensatz wird bei mir sekündlich aktualisiert. Ich kann mir das auch ansehen. Der Timestamp und einige andere Werte ändern sich ständig, die ID aber nur ab und an. Manchmal läft es 3 Minuten sauber. Dann ändert sich die eine oder ander ID aber wieder. Wenn das Doku-Konform wäre, müsste es ja auch bei jedem Update so laufen...
Wenn ich das in 2 Aufrufe zerlege (erst abfragen ob Datensatz existert und dann in zweitem Aufruf entweder INSERT oder UPDATE), würde ich, wenn ich richtig informiert bin, die MySQL-Last verdoppeln. Da ich etwa 100 BT-Geräte und 20-30 Scanner habe (wobei nicht jedes BT-Gerät in der Richweite aller Scanner ist) komme ich schnell auf etwa 600 - 700 Aufrufe pro Sekunde, die ich verdoppeln würde. Ich glaube bei dieser Zahl macht es schon sinn auf Performance zu achten, oder seht Ihr das anders?
Es scheint aber so zu sein, dass ein reines UPDATE-Statement den "Fehler" nicht herbeiführt. Ich habe jetzt mal alle Datensätze eingetragen und nun das Statment auf ein UPDATE geändert und seit etwa 7 Minuten läuft es ohne dass die ID sich ändert.
Wie wäre folgender Ansatz aus Perfomance-Sicht:
Ich mache erst einen Update und frage dann die effected Rows ab. Wenn >0, beende ich das Skript. So hatte ich nur einen MySQL-Aufruf.
Wenn 0, schiebe ich noch einen INSERT hinterher. So dürfte ich bei der jeder Scanner-BT-Kombination nur Einmalig einen doppelten Aufruf haben.
Meiner Meinung nach, ist mein ursprünglicher Weg immernoch der Richtige. Dass das Verhalten Regelkonform ist, bezweifle ich. Der beschrieben Bug ist aber irgendwie auch was anderes. Wenn ich es richtig verstehe geht es in dem Bug darum, dass fälschlich der AI-Wert hochzählt und beim nächsten Insert dann zu hoch ist. Bei mir ist es ja aber so, dass sich die IDs bereits bestehender Datensätze ändern.
Hmm...?!?
Kommentar
-
Zitat von olruebe Beitrag anzeigen@erc: Die ID ändert sich. Wenn ich die Tabelle leere und dann meine Scanner starte, bekomme ich zunächst 15 Datensätze mit den IDs 1-15. Nach 3 Minuten habe ich dann immernoch 15 Datensätze, jedoch mit IDs zwischen 1 und 441.
Zitat von olruebe Beitrag anzeigenWenn ich das in 2 Aufrufe zerlege (erst abfragen ob Datensatz existert und dann in zweitem Aufruf entweder INSERT oder UPDATE), würde ich, wenn ich richtig informiert bin, die MySQL-Last verdoppeln.
Kommentar
-
Ich bin mir jetzt sicher und habe auch mit nachlesen nur Infos bei msdn gefunden, aber wenn ich das richtig sehe, dann erstellt deine Tabelle erst eine ID als primary key und dann noch einen unique Index für ID. Das ist wohl dein Problem.
Schmeiss den unique Index für id raus raus und lasse ihn nur als PK.
Teile mit ob es das gewesen ist.
Kommentar
-
@erc: Dieses...
$sql =" INSERT INTO ma_location ( `scanner_id`, `beacon_major`, `beacon_minor`, `distance`, `TX`, `RSSI`, `timestamp`) VALUES ('".$ReveiverID."', '".$_POST["Major/Instance"]."', '".$_POST["Minor"]."', '".$dist."', '".$_POST["TX"]."','".$_POST["RSSI"]."', now())
ON DUPLICATE KEY UPDATE `distance` = '".$dist."', `TX` = '".$_POST["TX"]."', `RSSI` = '".$_POST["RSSI"]."';" ;
Erkennt Ihr in dem SQL einen Fehler, der mein Problem hervorrufen könnte?
Und Dnke für den Hinweis "5-Stellig". Das beruhigt mich! Und ja: Insert sind nur sehr wenige, Update die Hauptaufgabe.
@potestix: Ich habe den Unique von der ID entfernt. Die ID ist jetzt ein Primary-Key. Trotzdem tritt es noch auf.
ALTER TABLE `ma_location`
ADD PRIMARY KEY (`ID`),
ADD UNIQUE KEY `One_Scanner_Beacon` (`scanner_id`,`beacon_major`,`beacon_minor`) USING BTREE;
Kommentar
-
Hier haut was nicht hin. Ein derartigen Bug halte ich für praktisch ausgeschlossen. Angenommen es stimmt, dass es nur diesen einen Query auf diese Tabelle gibt und es kein Bug ist. Dann muss das Falsch sein:
Die ID ändert sich. Wenn ich die Tabelle leere und dann meine Scanner starte, bekomme ich zunächst 15 Datensätze mit den IDs 1-15. Nach 3 Minuten habe ich dann immernoch 15 Datensätze, jedoch mit IDs zwischen 1 und 441.
Kommentar
-
Zitat von olruebe Beitrag anzeigen@erc: Die ID ändert sich. Wenn ich die Tabelle leere und dann meine Scanner starte, bekomme ich zunächst 15 Datensätze mit den IDs 1-15. Nach 3 Minuten habe ich dann immernoch 15 Datensätze, jedoch mit IDs zwischen 1 und 441.
@ Perry Staltic: Ich sehe das anders. Es macht eben gerade NICHT, was die Doku sagt.
So wie ich die Doku verstehe, zählt der AI hoch, nachdem ein Insert durchgeführt wurde. Das macht ja auch sinn. Wird aber kein Insert durchgeführt, sondern ein UPDATE (auf Grund der Tatsache, dass es diesen Unique-Key schon gibt), sollte der AI unverändert bleiben.
Auch wenn mein Statement mit "INSERT" beginnt, wird ja durch den sonst doppelten Key ein UPDATE durchgeführt.
...
Hmm...?!?
Ich finde die Formulierung in der Doku auch nicht gelunden aber seis drum, hier ist das komplette Statement:
14.2.5.3 INSERT ... ON DUPLICATE KEY UPDATE Syntax
If you specify ON DUPLICATE KEY UPDATE, and a row is inserted that would cause a duplicate value in a UNIQUE index or PRIMARY KEY, MySQL performs an UPDATE of the old row. For example, if column a is declared as UNIQUE and contains the value 1, the following two statements have similar effect*1:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1; UPDATE table SET c=c+1 WHERE a=1;
(The effects are not identical for an InnoDB table where a is an auto-increment column. With an auto-increment column, an INSERT*3 statement increases the auto-increment value but UPDATE*2 does not.)
*2 Unter innodb: Das oben aufgeführte Statement allein führt nicht zu einem AI Increase (natürlich nicht ist ja ein Update), das Insert statement tut es aber.
Das ist für mich die Aussage, die genau durch Deinen Fall wiedergespiegelt wird.
Und ich sehe das wie erc, so einen massiven Bug sollte es eigentlich nicht geben. Es ist (missverständlich) dokumentiertes Verhalten der InnoDB Engine.
Viel besser Deine Ideen ohne den Mist zu arbeiten, mach ein Update und wenn es leer läuft das Insert. Das wird keine viel größere Last produzieren, weil technisch eigentlich das fast gleiche abläuft, nur nicht so bequem gecodet.
Es hat den Vorteil, dass jedem der es ließt und anpackt, klar ist, was passiert.
Was die Ausfallerscheinungen angeht (manchmal geht es, manchmal nicht), dazu 2 Dinge:
1. Ich kann von hier aus nicht Deinen gesamten Code überblicken und ich muss aus Erfahrung sagen, dass oft Seiteneffekte aus anderen Richtungen übersehen werden. Du kannst natürlich sagen, alles ist wasserdicht, aber das glaube ich erst, wenn ich den kompletten Code mit der Umgebung und den Clients hier habe und prüfen kann. (Was nicht geschehen wird) oder Du umgekehrt autonom laufenden Code lieferst, der das Fehlerverhalten zeigt. (sqlFiddle oder entsprechende DDL, DML Scripte hier postest)
2. Wahrscheinlich werde ich dafür gesteinigt, aber: bei mysql würde es mich nicht wundern, wenn doch unter bestimmten Prämissen was schief läuft. Ich fasse diese Datenbank nicht ernsthaft an. Sie ist traditionell nicht so robust, wie man sich das vorstellt bbei einem Produktivsystem und hat ein paar lausige Ecken (andere würden das drastischer ausdrücken). Wenn man sie dennoch einsetzt (und sogar solche Dinge geschehen), dann jedenfalls das gesamte System auf bekannte mysql Probleme prüfen-sollte man sowieso. Alles was per Conf abstellbar ist und das System "sauberer" macht, hochdrehen. Funktionen wie diese hier meiden, usw, usf.
Kommentar
-
Zitat von Perry Staltic Beitrag anzeigen2. Wahrscheinlich werde ich dafür gesteinigt, aber: bei mysql würde es mich nicht wundern, wenn doch unter bestimmten Prämissen was schief läuft.
Stimme dir aber ansonsten zu, was die Lösung angeht um das Problem zu umschiffen.
Kommentar
-
Zitat von protestix Beitrag anzeigenNö, warum, ist doch bekannt das das DBMS von Oracle stiefmütterlich behandelt wird und die lieber Geld verdienen. Aber solange das, die meist genutzte DB ist, muss man sich halt mit den Unzulänglichkeiten auseinandersetzen.
andere DB wie z.B: Postgresql für lau. Hier wird schon länger rasant entwickelt und die Features muss man teilweise fast als Genuss bezeichnen. Ja und robust ist es.
Kommentar
Kommentar