Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

SQL Server : Bug sur les colonnes auto incrémentées dans SQL Server 2005 et 2008

Bug qui m'a particulièrement surpris, et qui a mon sens est très sévère pour les bases de données. En effet celui-ci affecte la valeur renvoyée par @@IDENTITY et SCOPE_IDENTITY().

Voir ici pour leur rôle : http://blogs.codes-sources.com/christian/archive/2007/02/23/sql-server-champs-compteur-identity-ou-scope-identity.aspx

Le problème survient quand SQL Server utilise un plan d'exécution parallélisé pour une requête d'insertion. Ce cas n'est heureusement pas le plus fréquent, mais si une requête mets à jour une table utilisée par une vue indexées ou insère une grande quantité de données ce cas devient très probable. Dans ce cas la valeur du dernier incrément renvoyé pour une colonne de type IDENTITY est fausse !

Le bug et les scripts permettant de le reproduire : https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

Ci-dessous un script permettant de reproduire le problème :

USE tempdb
GO

CREATE
FUNCTION dbo.fn_nums(@n AS bigint) RETURNS TABLE AS
RETURN
WITH
L0 AS(SELECT 1 AS c UNION ALL SELECT 1),
L1 AS(SELECT 1 AS c FROM L0 AS A, L0 AS B),
L2 AS(SELECT 1 AS c FROM L1 AS A, L1 AS B),
L3 AS(SELECT 1 AS c FROM L2 AS A, L2 AS B),
L4 AS(SELECT 1 AS c FROM L3 AS A, L3 AS B),
L5 AS(SELECT 1 AS c FROM L4 AS A, L4 AS B),
Nums AS(SELECT ROW_NUMBER() OVER(ORDER BY c) AS n FROM L5)
SELECT n FROM Nums WHERE n <= @n
GO

CREATE
TABLE alpha (ident int IDENTITY(1, 1) PRIMARY KEY, value int NOT NULL);
CREATE TABLE beta (Number int NOT NULL PRIMARY KEY);

INSERT beta(Number) SELECT n FROM fn_nums(200000);

DECLARE @var int;
SET @var = 4;

INSERT INTO alpha (value)
SELECT Number FROM beta
WHERE Number BETWEEN 1 AND @var

SELECT scope_identity() AS [scope_identity] ,
        @@identity AS [@@identity],
        @@rowcount AS [@@rowcount],
        ident_current('alpha') AS [ident_current]

SELECT * FROM alpha
GO

DROP
TABLE alpha
DROP TABLE beta
DROP FUNCTION fn_nums
DROP FUNCTION fn_nums

GO

Dans mon cas j'obtiens :

@@rowcount

scope_identity

@@identity

ident_current

4

NULL

NULL

4

Ou 256 à la place de NULL suivant les cas.

Ce problème ne se produit que quand un plan parallèle est utilisé par le moteur, donc ne peut se produire sur SQL Server édition Express. Une manière d'éviter ce bug est de limiter le nombre de processeur avec lesquels travaille SQL Server :

INSERT INTO alpha (value)
SELECT Number FROM beta
WHERE Number BETWEEN 1 AND @var
OPTION(MAXDOP 1)

Pour un correctif plus global sur le serveur :

-- Toutes les requêtes seront executées sur un seul processeur

EXEC sp_configure 'max degree of parallelism', 1
reconfigure

-- On vide le cache des plan d'execution pour que le paramètre définie ci-dessus d'applique à toutes

DBCC freeproccache

Attention à cette méthode vous risquez d'avoir des requêtes s'executant en lecture qui prendront enormement plus de temps !

A vous de mesurer l'impact du bug sur vos applications, s'il y a un par rapport aux corrections qui pourraient éventuellement apportées pour y palier.

En attendant un correctif…

Bonne lecture…

Ce post vous a plu ? Ajoutez le dans vos favoris pour ne pas perdre de temps à le retrouver le jour où vous en aurez besoin :
Publié vendredi 26 décembre 2008 22:07 par christian
Classé sous : ,

Commentaires

Pas de commentaires
Les commentaires anonymes sont désactivés

Les 10 derniers blogs postés

- Merci par Blog de Jérémy Jeanson le 10-01-2019, 20:47

- Office 365: Script PowerShell pour auditer l’usage des Office Groups de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 11:02

- Office 365: Script PowerShell pour auditer l’usage de Microsoft Teams de votre tenant par Blog Technique de Romelard Fabrice le 04-26-2019, 10:39

- Office 365: Script PowerShell pour auditer l’usage de OneDrive for Business de votre tenant par Blog Technique de Romelard Fabrice le 04-25-2019, 15:13

- Office 365: Script PowerShell pour auditer l’usage de SharePoint Online de votre tenant par Blog Technique de Romelard Fabrice le 02-27-2019, 13:39

- Office 365: Script PowerShell pour auditer l’usage d’Exchange Online de votre tenant par Blog Technique de Romelard Fabrice le 02-25-2019, 15:07

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Stream Portal par Blog Technique de Romelard Fabrice le 02-21-2019, 17:56

- Office 365: Script PowerShell pour auditer le contenu de son Office 365 Video Portal par Blog Technique de Romelard Fabrice le 02-18-2019, 18:56

- Office 365: Script PowerShell pour extraire les Audit Log basés sur des filtres fournis par Blog Technique de Romelard Fabrice le 01-28-2019, 16:13

- SharePoint Online: Script PowerShell pour désactiver l’Option IRM des sites SPO non autorisés par Blog Technique de Romelard Fabrice le 12-14-2018, 13:01