L'incrément d'identité saute dans la base de données du serveur SQL

dans une de mes tables Fee dans la colonne" ReceiptNo " dans SQL Server 2012 l'incrément d'identité de base de données a soudainement commencé à sauter à 100s au lieu de 1 selon les deux choses suivantes.

  1. s'il est 1205446 il est saute à 1206306, s'il est 1206321, il saute à 1207306 et s'il est 1207314, il saute à 1208306. Ce que je veux vous faire remarquer est que les trois derniers chiffres restent constants I. e 306 chaque fois que le saut se produit comme indiqué dans l'image suivante.

  2. ce problème survient lorsque je redémarre mon ordinateur

enter image description here

101
demandé sur DhruvJoshi 2013-01-03 23:52:31

6 réponses

vous rencontrez probablement le problème ici (wayback machine).

SQL Server 2012 utilise maintenant une taille de cache de 1.000 lors de l'attribution des valeurs IDENTITY dans une colonne int et redémarrer le service peut "perdre" les valeurs inutilisées (la taille de cache est de 10.000 pour bigint / numeric ).

des données que vous avez montré il semble que cela s'est produit après la saisie de données pour le 22 décembre puis quand il serveur SQL redémarré réservé les valeurs 1206306 - 1207305 . Après la saisie des données pour 24-25 décembre a été fait un autre redémarrage et SQL Serveur réservé la gamme suivante 1207306 - 1208305 visible dans les entrées pour le 28.

sauf si vous redémarrez le service avec une fréquence inhabituelle, les valeurs" perdues " sont peu susceptibles de faire une entaille significative dans la gamme de valeurs autorisées par le type de données, de sorte que la meilleure politique n'est pas de s'inquiéter à ce sujet.

Si c'est pour une raison un vrai problème pour vous voir les solutions de rechange sur le fil D'article de connexion liée.

  1. vous pouvez utiliser un SEQUENCE au lieu d'une colonne d'identité et définir une taille de cache plus petite par exemple et utiliser NEXT VALUE FOR dans une colonne par défaut.
  2. ou appliquer trace flag 272 qui rend l'allocation IDENTITY enregistrée comme dans les versions précédentes.

vous devriez sachez qu'aucune de ces solutions de rechange ne présente de lacunes. Cela n'a jamais été garanti par IDENTITY car cela ne serait possible qu'en sérialisant les inserts à la table. Si vous avez besoin d'une colonne sans Gap, vous devrez utiliser une solution différente de IDENTITY ou SEQUENCE

"
132
répondu Martin Smith 2018-02-20 21:47:10

ces problèmes se produisent après le redémarrage du serveur SQL.

la solution est:

  • Exécuter Gestionnaire de Configuration SQL Server .

  • , Sélectionnez les Services SQL Server .

    SQL Server Configuration Manager

  • clic droit SQL Server et sélectionnez propriétés .

  • dans la fenêtre d'ouverture sous paramètres de démarrage , tapez -T272 et cliquez sur ajouter , puis appuyez sur appliquer bouton et redémarrer.

    SQL Server startup parameters

43
répondu Harun ERGUL 2015-06-19 09:22:15

je sais que ma réponse pourrait être en retard à la fête. Mais j'ai résolu d'une autre manière en ajoutant une procédure de démarrage stockée dans SQL Server 2012.

créer une procédure stockée suivante dans 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

puis l'Ajouter pour démarrer en utilisant la syntaxe suivante.

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

C'est une bonne idée si vous avez quelques tables. mais si vous devez le faire pour de nombreuses tables, cette méthode fonctionne toujours, mais pas une bonne idée.

22
répondu Jeyara 2018-02-27 23:45:53

From SQL Server 2017+ you could use ALTER DATABASE SCOPED CONFIGURATION :

IDENTITY_CACHE = {ON | OFF }

active ou désactive le cache d'identité au niveau de la base de données. Défaut est SUR. La mise en cache d'identité est utilisée pour améliorer les performances D'INSERT sur tableaux avec colonnes D'identité. pour éviter des écarts dans les valeurs de Identité colonne dans les cas où le serveur redémarre inopinément ou échoue sur un serveur secondaire, désactivez L'option IDENTITY_CACHE. Cette option est similaire à L'option Trace flag 272 du serveur SQL existant., sauf qu'il peut être mis au niveau base de données, plutôt que seulement niveau du serveur.

(...)

G. Set IDENTITY_CACHE

cet exemple désactive le cache d'identité.

ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE=OFF ;
15
répondu Lukasz Szozda 2017-04-22 15:36:49

C'est encore un problème très commun parmi de nombreux développeurs et applications quelle que soit leur taille.

malheureusement, les suggestions ci-dessus ne corrigent pas tous les scénarios, c'est-à-dire l'hébergement partagé, vous ne pouvez pas vous fier à votre hôte pour définir le paramètre de démarrage-t272.

aussi, si vous avez des tables existantes qui utilisent ces colonnes d'identité pour les clés primaires, c'est un énorme effort pour laisser tomber ces colonnes et en recréer de nouvelles pour utiliser la solution de contournement de la séquence BS. Le La solution de contournement de séquence est seulement bonne si vous concevez les nouvelles tables à partir de zéro dans SQL 2012+

bref, si vous êtes sur Sql Server 2008R2, alors restez dessus. Sérieusement, reste dessus. Jusqu'à ce que Microsoft admette qu'ils ont introduit un énorme bogue, qui est toujours là même dans Sql Server 2016, alors nous ne devrions pas mettre à jour jusqu'à ce qu'ils possèdent et corriger.

Microsoft straight up a introduit un changement de rupture, c'est-à-dire qu'ils ont cassé une API qui ne fonctionne plus fonctionne comme prévu, en raison du fait que leur système oublie son identité en cours sur un redémarrage. Ou aucun Cache, ce qui est inacceptable, et le Microsoft développeur du nom de Bryan doit posséder, au lieu de dire au monde que c'est "by design" et une "fonction". Bien sûr, la mise en cache est une fonctionnalité, mais perdre la trace de ce que devrait être la prochaine identité n'est pas une fonctionnalité. C'est un fricken BUG!!!

je vais partager le contournement que j'ai utilisé, parce que mes DB sont sur partagé Héberger des serveurs, aussi, je ne laisse pas tomber et recréer mes colonnes de clés primaires, qui serait un énorme PITA.

au lieu de cela, c'est mon hack honteux (mais pas aussi honteux que ce bug POS que microsoft a introduit).

Hack/Corrigé:

avant vos commandes insert, il vous suffit de réenregistrer votre identité avant chaque insert. Cette correction n'est recommandée que si vous n'avez pas le contrôle d'administrateur sur L'instance de votre serveur Sql, sinon je suggère le réensemencement au redémarrage du serveur.

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)

juste ces 3 lignes juste avant votre insertion, et vous devriez être bon à aller. Cela n'affectera pas la performance à ce point, c'est-à-dire qu'elle sera inaperçue.

Goodluck.

10
répondu green_mystic_Orb 2017-03-07 16:22:29

il y a plusieurs raisons possibles pour sauter les valeurs d'identité. Ils vont du restaurée insère à la gestion de l'identité pour la réplication. Je ne peux pas dire ce qui cause cela dans votre cas sans passer un peu de temps dans votre système.

Vous devez savoir, cependant, que, en aucun cas, vous pouvez supposer une colonne d'identité pour être contiguos. Il y a trop de choses qui peuvent causer des lacunes.

Vous pouvez trouver un peu plus d'informations à ce sujet ici: http://sqlity.net/en/792/the-gap-in-the-identity-value-sequence /

7
répondu Sebastian Meine 2013-01-03 19:59:50