none
Identity pulando sequência no SQL SERVER 2012. Bug? RRS feed

  • Pergunta

  • Pessoal, migrei uma base do SQL Server Express do 2008 R2 para o 2012.

    Primeiro dia, funcionou bem. No segundo dia  os campos IDENTITY de mais de 30 tabelas pularam cerca de 950 numerações, em algumas tabelas mais, em outras menos.

    Exemplo:

    • Último no dia 23/03/2012: 2361;
    • Primeiro no dia 24/03/2012: 3354 (pulou 993, ao invés de 1 que é o incremento).

    Isso aconteceu com os IDENTITY's de todas as tabelas da base.

    Nunca vi isso antes. Gostaria de saber se isso é algum tipo de bug do SQL SERVER 2012 EXPRESS, ou se não, como faço para descobrir o que ocasionou isso é várias tabelas.

    domingo, 25 de março de 2012 11:42

Respostas

Todas as Respostas

  • Se você inserir um registro agora por exemplo, ele pula também?

    Por acaso não haveria pro engano um intervalo maior no identity?

    Transações podem ter ocorrido nestas tabelas (insert e depois delete) ?


    View Ricardo Muramatsu's profile on LinkedIn

    segunda-feira, 26 de março de 2012 13:02
  • Olá Bruno, todos os teus Identity pularam estes 993 exatamente?

    --
    Marcus Vinícius Bittencourt
    blog: isqlserver.wordpress.com
    www.sqlserverRS.com.br

    segunda-feira, 26 de março de 2012 18:52
  • Uns mais, outros menos, mas todos com cerca de 1.000.
    quinta-feira, 31 de maio de 2012 20:47
  • Se você inserir um registro agora por exemplo, ele pula também?

    Por acaso não haveria pro engano um intervalo maior no identity?

    Transações podem ter ocorrido nestas tabelas (insert e depois delete) ?


    View Ricardo Muramatsu's profile on LinkedIn

    Complementando o comentário do Ricardo, pode ter sido alguma tentativa de INSERT e que tenha dado ROLLBACK vai fazer o Identity "pular" os valores..

    Roberto Fonseca MCT / MCITP - Database Administrator 2008 MCITP - Database Developer 2008 MCITP - Business Intelligence 2008

    quinta-feira, 31 de maio de 2012 21:48
    Moderador
  • Não é nada disso pessoal.

    O bug que acontece a cada restart no serviço já foi admitido pela própria Microsoft.

    Vejam o post oficial nesse forum: http://connect.microsoft.com/SQLServer/feedback/details/739013/alwayson-failover-results-in-reseed-of-identity

    sexta-feira, 12 de outubro de 2012 13:32
  • Acontece somente se reiniciar o servidor.
    sexta-feira, 12 de outubro de 2012 13:33
  • Como falei lá em cima, o bug que acontece a cada restart no serviço já foi admitido pela própria Microsoft.

    Post oficial nesse forum: http://connect.microsoft.com/SQLServer/feedback/details/739013/alwayson-failover-results-in-reseed-of-identity

    sexta-feira, 12 de outubro de 2012 13:34
  • Caramba, Bruno, que vacilo hein. Acabei de fazer o teste aqui e o problema realmente ocorre.

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    sexta-feira, 12 de outubro de 2012 17:46
    Moderador
  • Pois é, e infelizmente a Microsoft já lançou o SP1 sem a correção para esse bug gritante. E além disso está demorando a se pronunciar.
    sexta-feira, 12 de outubro de 2012 17:52
  • Enquanto a Microsoft não aponta a solução, achei uma solução apresentada por um colaborador de outro fórum:

    USE master; 
    GO
    CREATE PROCEDURE sp_FixSeeds2012
    AS
    BEGIN
    
        --foreach database
        DECLARE @DatabaseName varchar(255)
        
        DECLARE DatabasesCursor CURSOR READ_ONLY
        FOR
            SELECT name
            FROM sys.databases
            where name not in ('master','tempdb','model','msdb') and sys.databases.state_desc = 'online'
    
        OPEN DatabasesCursor
    
        FETCH NEXT FROM DatabasesCursor
        INTO @DatabaseName
    
        WHILE @@FETCH_STATUS = 0
        BEGIN
        
            EXEC ('USE '+@DatabaseName + '
    
            --foreach identity column
            DECLARE @tableName varchar(255)
            DECLARE @columnName varchar(255)
            DECLARE @schemaName varchar(255)
        
            DECLARE IdentityColumnCursor CURSOR READ_ONLY
            FOR
            
                select TABLE_NAME , COLUMN_NAME, TABLE_SCHEMA 
                from INFORMATION_SCHEMA.COLUMNS 
                where COLUMNPROPERTY(object_id(TABLE_NAME), COLUMN_NAME, ''IsIdentity'') = 1 
            
    
            OPEN IdentityColumnCursor
    
            FETCH NEXT FROM IdentityColumnCursor
            INTO @tableName, @columnName, @schemaName
    
            WHILE @@FETCH_STATUS = 0
            BEGIN
            
                print ''['+@DatabaseName+'].[''+@tableName+''].[''+@schemaName+''].[''+@columnName+'']'' 
                EXEC (''declare @MAX int = 0
                        select @MAX = max(''+@columnName+'') from ['+@DatabaseName+'].[''+@schemaName+''].[''+@tableName+'']
                        if (@MAX IS NULL)
                        BEGIN
                            SET @MAX = 0
                        END
                        DBCC CHECKIDENT(['+@DatabaseName+'.''+@schemaName+''.''+@tableName+''],RESEED,@MAX)'')
    
                FETCH NEXT FROM IdentityColumnCursor
                INTO @tableName, @columnName, @schemaName
    
            END
    
            CLOSE IdentityColumnCursor
            DEALLOCATE IdentityColumnCursor')
    
    
    
            FETCH NEXT FROM DatabasesCursor
            INTO @DatabaseName
    
        END
    
        CLOSE DatabasesCursor
        DEALLOCATE DatabasesCursor
    END
    GO
    
    EXEC sp_configure 'show advanced options', 1 ;
    GO
    RECONFIGURE
    GO
    EXEC sp_configure 'scan for startup procs', 1 ;
    GO
    RECONFIGURE
    GO
    
    
    
    EXEC sp_procoption @ProcName = 'sp_FixSeeds2012' 
        , @OptionName = 'startup' 
        , @OptionValue = 'true' 
    GO

    Notem que no final ele seta a propriedade STARTUP para TRUE. Gostaria de saber dos mais experientes:

      • A SP é funcional e vai corrigir os seeds de todos o identitys da instancia?
      • Essa SP será executada a cada start do serviço?
      • É aplicável para a versão EXPRESS, visto que a mesma não tem Agent? (A opção STARTUP = TRUE vai iniciar sem o Agent?)

    Aquele abraço.

    • Sugerido como Resposta antero mendes sexta-feira, 20 de dezembro de 2019 20:20
    sexta-feira, 12 de outubro de 2012 18:20
  • Bruno, duas coisas:

    1) Esta procedure está contemplada no link de Soluções Alternativas da página que você mencionou (http://connect.microsoft.com/SQLServer/feedback/details/739013/alwayson-failover-results-in-reseed-of-identity);

    2) Pela definição do BOL esta procedure não tem ligação com o Agent e sim, será executada a cada reinicialização do serviço. Veja a explicação do BOL em relação à sp_procoption:

    "sp_procoption (Transact-SQL)

    Define ou limpa um procedimento armazenado para execução automática. Um procedimento armazenado que está definido para execução automática será executado toda vez que uma instância do SQL Server for iniciada."

    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    sexta-feira, 12 de outubro de 2012 19:32
    Moderador
  • Roberson,

    Que bom que ela vai rodar independente do Agent. A gambiarra funciona e corrige o problema enquanto uma solução definitiva sai.

    Boura Microsoft... tá demorando a se pronunciar.

    sábado, 20 de outubro de 2012 14:18
  • Por favor,

    Na mesma instância do SQL eu tenho 4 bancos colo a SP em Nova SP e salvo ou crio um xxx.sql e mando rodar?

    Daniel

    quinta-feira, 15 de maio de 2014 13:47
  • Parceiro, veja se assim o codigo fica melhor.

    ==

    USE [master]
    GO
    /****** Object:  StoredProcedure [dbo].[sp_FixSeeds2012]    Script Date: 20/12/2019 17:12:20 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[sp_FixSeeds2012]
    AS
    BEGIN
        DECLARE @txQUERY VARCHAR(MAX) = NULL
        SET @txQUERY = CONCAT('USE [master];', CHAR(13), CHAR(10),'DECLARE @varTOTAL INT = 0;')

        ;WITH tmpDATABASE AS (
            SELECT
            [NAME] AS 'db_NAME'
            FROM [sys].[databases]
            WHERE name not in ('master','tempdb','model','msdb')
            AND [sys].[databases].[state_desc] = 'online'
        ), tmpTABELA AS (
            SELECT
            a.TABLE_NAME AS 'tab_NAME',
            a.COLUMN_NAME AS 'tab_COLUNA',
            a.TABLE_SCHEMA AS 'tab_SCHEMA',
            a.TABLE_CATALOG AS 'tab_DATABASE'    
            FROM [INFORMATION_SCHEMA].[COLUMNS] a
                 JOIN [SYSOBJECTS] b ON a.TABLE_NAME = b.NAME
            WHERE (COLUMNPROPERTY(object_id(a.TABLE_NAME), a.COLUMN_NAME, 'IsIdentity') = 1)
            AND b.TYPE = 'U'
        )
        SELECT
        @txQUERY = CONCAT(
            @txQUERY,
            CHAR(13), CHAR(10), CHAR(13), CHAR(10),
            'USE ', [db_NAME], ';',
            CHAR(13), CHAR(10),
            'SET @varTOTAL = ISNULL((SELECT MAX([',
            [tab_COLUNA],
            ']) FROM [',
            [tab_SCHEMA],
            '].[',
            [tab_NAME],
            ']), 0);',
            CHAR(13), CHAR(10),
            'PRINT ''++++++++++++++++++''',
            CHAR(13), CHAR(10),
            'PRINT ''[', [db_NAME],'].[', [tab_SCHEMA], '].[', [tab_NAME], ']''',
            CHAR(13), CHAR(10),
            'IF (@varTOTAL > 0) DBCC CHECKIDENT(''[',
            [db_NAME],
            '].[',
            [tab_SCHEMA],
            '].[',
            [tab_NAME],
            ']'',''RESEED'', @varTOTAL);'    
        )
        FROM tmpDATABASE a
             JOIN tmpTABELA b ON a.db_NAME = b.tab_DATABASE
        ORDER BY [db_NAME], [tab_NAME]

        --    SELECT @txQUERY AS '@txQUERY'
        --    PRINT '@txQUERY=' + @txQUERY
        EXEC(@txQUERY)
        --
        RETURN
    END

    GO

    sexta-feira, 20 de dezembro de 2019 20:21