it-swarm.com.de

Das Identitätsinkrement springt in die SQL Server-Datenbank

In einer meiner Tabellen Fee in der Spalte "ReceiptNo" in SQL Server 2012 begann das Inkrement der Datenbankidentität plötzlich auf 100 statt auf 1 zu springen, abhängig von den folgenden beiden Dingen.

  1. wenn es 1205446 ist, springt es zu 1206306, wenn es 1206321 ist, springt es zu 1207306 und wenn es 1207314 ist, springt es zu 1208306 tritt wie im folgenden Bild gezeigt auf.

  2. dieses Problem tritt auf, wenn ich meinen Computer neu starte

enter image description here

113
kashif

Wahrscheinlich stoßen Sie hier auf das Problem (Wayback-Maschine).

SQL Server 2012 verwendet jetzt eine Cache-Größe von 1.000, wenn IDENTITY - Werte in einer int - Spalte zugewiesen werden und wenn der Dienst neu gestartet wird, können nicht verwendete Werte "verloren" werden (die Cache-Größe beträgt 10.000 für bigint/numeric).

Aus den Daten, die Sie gezeigt haben, sieht es so aus, als ob dies nach der Dateneingabe für den 22. Dezember passiert ist. Als SQL Server neu gestartet wurde, wurden die Werte 1206306 - 1207305. Nach der Dateneingabe für den 24. bis 25. Dezember wurde ein weiterer Neustart durchgeführt und SQL Server reservierte den nächsten Bereich 1207306 - 1208305 sichtbar in den Einträgen zum 28.

Sofern Sie den Dienst nicht mit ungewöhnlicher Häufigkeit neu starten, ist es unwahrscheinlich, dass "verlorene" Werte den Wertebereich des Datentyps erheblich einschränken, sodass Sie sich am besten keine Sorgen machen.

Wenn dies aus irgendeinem Grund ein echtes Problem für Sie ist, sehen Sie sich die Problemumgehungen im verknüpften Connect Item-Thread an.

  1. Sie können ein SEQUENCE anstelle einer Identitätsspalte verwenden und beispielsweise eine kleinere Cache-Größe definieren und NEXT VALUE FOR in einer Standardspalte.
  2. Oder wenden Sie das Ablaufverfolgungsflag 272 an, wodurch die Zuweisung IDENTITY wie in früheren Versionen protokolliert wird.

Sie sollten wissen, dass keine dieser Problemumgehungen Lücken schließt. Dies wurde von IDENTITY nie garantiert, da dies nur durch Serialisierung der Einfügungen in die Tabelle möglich wäre. Wenn Sie eine lückenlose Spalte benötigen, müssen Sie eine andere Lösung als IDENTITY oder SEQUENCE verwenden.

143
Martin Smith

Dieses Problem tritt nach dem Neustart des SQL Servers auf.

Die Lösung ist:

  • Führen Sie SQL Server Configuration Manager aus.

  • Wählen Sie SQL Server Services.

    SQL Server Configuration Manager

  • Klicken Sie mit der rechten Maustaste auf SQL Server und wählen Sie Eigenschaften.

  • Geben Sie im sich öffnenden Fenster unter Startup Parameters-T272 Ein und klicken Sie auf Add, drücken Sie Apply und starten Sie neu.

    SQL Server startup parameters

53
Harun ERGUL

Ich weiß, dass meine Antwort auf die Party zu spät sein könnte. Aber ich habe auf andere Weise gelöst, indem ich eine gespeicherte Startprozedur in SQL Server 2012 hinzufügte.

Erstellen Sie eine folgende gespeicherte Prozedur in der Master-DB.

USE [master]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[ResetTableNameIdentityAfterRestart]
AS
BEGIN

begin TRAN
    declare @id int = 0
    SELECT @id =  MAX(id) FROM [DatabaseName].dbo.[TableName]
    --print @id
    DBCC CHECKIDENT ('[DatabaseName].dbo.[TableName]', reseed, @id)
Commit

END

Fügen Sie es dann unter Verwendung der folgenden Syntax zu Start hinzu.

EXEC sp_procoption 'ResetOrderIdentityAfterRestart', 'startup', 'on';

Dies ist eine gute Idee, wenn Sie nur wenige Tische haben. aber wenn Sie für viele Tabellen tun müssen, funktioniert diese Methode immer noch, aber keine gute Idee.

24
Jeyara

Von SQL Server 2017+ Sie könnten ALTER DATABASE SCOPED CONFIGURATION verwenden:

IDENTITY_CACHE = {ON | AUS}

Aktiviert oder deaktiviert den Identitätscache auf Datenbankebene. Die Standardeinstellung ist ON. Das Identitätscaching wird verwendet, um die INSERT-Leistung für Tabellen mit Identitätsspalten zu verbessern. Deaktivieren Sie die Option IDENTITY_CACHE, um Lücken in den Werten der Spalte Identität zu vermeiden, wenn der Server unerwartet neu gestartet wird oder ein Failover auf einen sekundären Server erfolgt. Diese Option ist dem vorhandenen SQL Server-Ablaufverfolgungsflag 272 ähnlich, mit der Ausnahme, dass es auf Datenbankebene und nicht nur auf Serverebene festgelegt werden kann.

(...)

G. IDENTITY_CACHE setzen

In diesem Beispiel wird der Identitätscache deaktiviert.

ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE=OFF ;
24
Lukasz Szozda

Dies ist immer noch ein weit verbreitetes Problem bei vielen Entwicklern und Anwendungen, unabhängig von deren Größe.

Leider beheben die obigen Vorschläge nicht alle Szenarien, d. H. Shared Hosting. Sie können sich nicht darauf verlassen, dass Ihr Host den Startparameter -t272 festlegt.

Wenn Sie über vorhandene Tabellen verfügen, die diese Identitätsspalten für Primärschlüssel verwenden, ist es ein GROSSER Aufwand, diese Spalten zu löschen und neue zu erstellen, um die BS-Sequenz-Problemumgehung zu verwenden. Die Abhilfemaßnahme für Sequences ist nur dann sinnvoll, wenn Sie die Tabellen in SQL 2012+ von Grund auf neu entwerfen

Fazit ist, wenn Sie auf SQL Server 2008R2 sind, dann bleiben Sie auf dem Laufenden. Im Ernst, bleib dran. Bis Microsoft zugibt, dass sie einen RIESIGEN Bug eingeführt haben, der auch in SQL Server 2016 noch vorhanden ist, sollten wir nicht upgraden, bis sie es besitzen und es reparieren.

Microsoft hat eine bahnbrechende Änderung eingeführt, d. H., Sie haben eine funktionsfähige API beschädigt, die nicht mehr wie geplant funktioniert, da ihr System bei einem Neustart die aktuelle Identität vergisst. Cache oder kein Cache, das ist inakzeptabel, und der Microsoft-Entwickler namens Bryan muss es besitzen, anstatt der Welt mitzuteilen, dass es sich um "by design" und ein "Feature" handelt. Sicher, das Zwischenspeichern ist eine Funktion, aber den Überblick darüber zu verlieren, wie die nächste Identität aussehen soll, IS NOT A FEATURE. Es ist ein verdammter BUG !!!

Ich werde die von mir verwendete Problemumgehung weitergeben, da sich meine DBs auf Shared Hosting-Servern befinden. Außerdem lösche ich meine Primärschlüsselspalten nicht und erstelle sie neu. Das wäre eine riesige PITA.

Stattdessen ist dies mein beschämender Hack (aber nicht so beschämend wie dieser POS-Fehler, den Microsoft eingeführt hat).

Hack/Fix:

Bevor Sie Ihre Einfügebefehle eingeben, müssen Sie Ihre Identität vor jedem Einfügen erneut überprüfen. Dieses Update wird nur empfohlen, wenn Sie keine Administratorsteuerung über Ihre SQL Server-Instanz haben. Andernfalls empfehle ich, beim Neustart des Servers eine erneute Einteilung vorzunehmen.

declare @newId int -- where int is the datatype of your PKey or Id column
select @newId = max(YourBuggedIdColumn) from YOUR_TABLE_NAME
DBCC CheckIdent('YOUR_TABLE_NAME', RESEED, @newId)

Nur diese 3 Zeilen unmittelbar vor Ihrer Einfügung, und Sie sollten bereit sein, zu gehen. Dies beeinträchtigt die Leistung nicht so sehr, d. H., Es ist nicht zu bemerken.

Viel Glück.

14

Es gibt viele mögliche Gründe für das Springen von Identitätswerten. Sie reichen von Rollback-Einfügungen bis hin zur Identitätsverwaltung für die Replikation. Was dies in Ihrem Fall verursacht, kann ich nicht sagen, ohne einige Zeit in Ihrem System zu verbringen.

Sie sollten jedoch wissen, dass Sie in keinem Fall davon ausgehen können, dass eine Identitätsspalte zusammenhängend ist. Es gibt einfach zu viele Dinge, die Lücken verursachen können.

Weitere Informationen hierzu finden Sie hier: http://sqlity.net/de/792/the-gap-in-the-identity-value-sequence/

7
Sebastian Meine