Die Sequenz wird wiederverwendet

11

Ich habe eine Sequenz, die Tracking-Nummern für Objekte in meinem System generiert. Es hatte schon seit einiger Zeit gut funktioniert.

Letzte Woche haben wir festgestellt, dass die Werte wieder verwendet werden.

Was zu passieren scheint, ist, dass es zu verschiedenen Zeitpunkten am Abend auf einen Wert zurückgesetzt wird, den es am Vortag hatte. Ab diesem Punkt werden dann weiterhin Werte generiert.

So könnte ich zum Beispiel so etwas bekommen:

10112
10113
10114
10115
10116
10117
10118
10113
10114
10115
10116
...

Es scheint kein Muster zu geben, wann es passiert, wie lange es zwischen der ersten und der zweiten Verwendung dauert (nur 10 Minuten oder mehrere Stunden) oder wie viele zurückgesetzt werden (nur 1 und mehrere hundert).

Ich habe darüber nachgedacht, einen Trace auszuführen (und kann es immer noch), aber ich glaube nicht, dass das Sequenzobjekt direkt geändert wird. Der Grund, warum ich glaube, ist, dass das Änderungsdatum mehrere Tage alt ist und auf eine Zeit verweist, in der wir den Wert manuell erhöht haben, um zu versuchen, Duplikate zu entfernen. (Und das Problem ist seitdem mehrmals aufgetreten.)

Hat jemand eine Vorstellung davon, was jeden Abend zu einem Rollback und einer Wiederverwendung von Sequenzwerten führen kann?

UPDATE: Um einige Fragen in den Kommentaren zu beantworten:

  • @@Version::

    Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64) 19. Oktober 2012, 13:38:57 Uhr

  • Skript erstellen:

    CREATE SEQUENCE [schemaName].[SequenceName] 
      AS [bigint]
      START WITH 410014104
      INCREMENT BY 1
      MINVALUE 410000000
      MAXVALUE 419999999
      CYCLE 
      CACHE 
    GO
  • Ich habe keine eindeutige Einschränkung (aber ich habe vor, eine anzuziehen). Dies hilft mir jedoch nur zu wissen, wann ich einen Wert wiederverwendet habe. Nicht, was dazu führte, dass die Werte zurückgesetzt wurden. Ich habe einen Job vergeben, der alle 5 Minuten einen neuen Wert erhält und ihn spart. Die Zeiten und Wertsprünge folgen keinem Muster.

  • Ich habe die Ereignisprotokolle überprüft, um festzustellen, ob ein Fehler vorliegt. Der einzige Gedanke, der passiert, ist folgender: http://support.microsoft.com/kb/2793634 Wir wenden das Update heute an. Ich denke nicht, dass diese verwandt sind, aber es könnte sein.
Vaccano
quelle
1
Warum gibt es für diese Spalte keine PK- oder eindeutige Einschränkung? Wenn dies geschehen ist, wird diese Wiederverwendung abgefangen, und Sie müssen nicht raten, woher sie kommt, es sei denn, Ihr Anwendungscode verschluckt nur alle Fehler ...
Aaron Bertrand
Können Sie die Definition Ihrer Sequenz zeigen? Können Sie auch das Fehlerprotokoll überprüfen, um festzustellen, ob über Nacht wichtige Ereignisse aufgetreten sind (z. B. Failover, Neustart des Dienstes, Speicherprobleme usw.)?
Aaron Bertrand
2
Was ist @@VERSION? Hat sich auch etwas an der Umwelt geändert? Es gibt ein Verbindungselement, das etwas Ähnliches meldet. Das OP dort rechnet damit, dass es in Verbindung gebracht wurde11.0.3000.0
Martin Smith
2
Nun, CYCLE teilt SQL Server im Wesentlichen mit, dass Sie mit der Wiederverwendung von Werten einverstanden sind. Ich habe absolut keine Ahnung, warum Sie dieses Problem haben, und weiß nicht, warum Sie herausfinden werden, warum (wie viel Zeit verbringen Sie damit, zu untersuchen, warum Sie einen platten Reifen haben, bevor Sie ihn einfach ersetzen?). Ich denke immer noch, dass Ihre beste Wette darin besteht, dort eine Einschränkung zu haben, um Duplikate zu verhindern, und das Caching zu deaktivieren, in der Hoffnung, eine Wiederverwendung zu verhindern.
Aaron Bertrand

Antworten:

11

Wenn Sie in dieser Spalte keine Duplikate möchten, geben Sie dies zunächst explizit an .

ALTER TABLE dbo.whatever ADD CONSTRAINT uq_that_column UNIQUE (that_column);

(Oder Sie möchten dies möglicherweise zum Primärschlüssel machen oder den Clustered-Index ändern oder was haben Sie ...)

In jedem Fall ist es weitaus besser, beim Generieren eines Duplikats einen Fehler auszulösen, als nur blind ein Duplikat einzufügen, mit dem Sie sich später nur noch befassen müssen.

Stellen Sie sich als Nächstes vor, dass eine SEQUENCE nur ein Zahlengenerator ist und standardmäßig einen Cache mit 50 Werten hat. Abhängig davon, wie Ihre Transaktionen eingerichtet sind und welche anderen kritischen Ereignisse auf einem Server auftreten, kann SQL Server möglicherweise "vergessen", dass bestimmte Werte für Sie generiert wurden. Entschuldigung, aber ich weiß nicht genau, welche Kriterien bei der Reproduktion dieses Fehlers eine Rolle spielen. Der Weg, dies zu umgehen (bis der Fehler behoben / erklärt ist ), besteht darin, die zu verwendende Reihenfolge zu ändern NO CYCLEund NO CACHEz.

ALTER SEQUENCE dbo.mysequence NO CYCLE NO CACHE; 

Beachten Sie, dass NO CACHEdies die Leistung und Parallelität beeinträchtigen kann, aber dazu beiträgt, Lücken, verlorene Blöcke und, wer weiß, möglicherweise auch Ihr Problem zu beseitigen.

Möglicherweise möchten Sie auch überprüfen, ob Sie das neueste Service Pack und die neueste CU verwenden. An dieser Stelle empfehle ich SP1 und CU10 mit 3437 ; SP2 ist nicht verfügbar , aber es gibt immer noch ein kritisches Problem mit Online-Neuerstellungen, das Sie betreffen kann .

Aaron Bertrand
quelle
Nun, ich kann es nicht sichern lassen. Also, wenn NO CACHE es reparieren wird, dann werde ich das tun.
Vaccano
Ich dachte, dass es Transaktionen geben könnte, die dies verursachen. Auf der Sequenzseite in MSDN heißt es jedoch: "Sequenznummern werden außerhalb des Bereichs der aktuellen Transaktion generiert. Sie werden unabhängig davon verbraucht, ob die Transaktion mit der Sequenznummer festgeschrieben oder zurückgesetzt wird." Also habe ich meine Transaktionstheorie verworfen. Ich bin damit einverstanden, dass noch etwas los sein muss.
Vaccano
Es stellte sich heraus, dass es NO CYCLEausreichte , es nur mit einzustellen. (Zumindest ist es letzte Nacht nicht passiert.) Danke für die Hilfe!
Vaccano
1
UPDATE: Das Sequenzobjekt generiert doppelte Sequenzwerte, wenn SQL Server 2012 oder SQL Server 2014 unter Speicherdruck stehen. Angenommen, Sie erstellen ein Sequenzobjekt, für das die Option CACHE in Microsoft SQL Server 2012 oder SQL Server 2014 aktiviert ist. Wenn die Instanz unter Speicherdruck steht Wenn mehrere gleichzeitige Verbindungen Sequenzwerte von demselben Sequenzobjekt anfordern, können doppelte Sequenzwerte generiert werden. Außerdem tritt ein Fehler bei der Verletzung eines eindeutigen oder Primärschlüssels (PK) auf, wenn der doppelte Sequenzwert in eine Tabelle eingefügt wird.
Andomar