Sequência está reutilizando

11

Eu tenho uma sequência que gera números de rastreamento para objetos no meu sistema. Ele estava funcionando bem há algum tempo.

Na semana passada, percebemos que estava começando a reutilizar valores.

O que parece acontecer é que, em diferentes momentos da noite, ele reverterá para um valor que tinha no dia anterior. Ele continuará gerando valores a partir desse ponto.

Então, por exemplo, eu poderia obter algo parecido com isto:

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

Não parece haver nenhum padrão em que isso aconteça, a duração entre o primeiro uso e o segundo uso (apenas 10 minutos ou várias horas) ou quantas são revertidas (apenas 1 e várias centenas).

Pensei em executar um rastreamento (e ainda pode), mas não acho que o objeto de sequência esteja sendo modificado diretamente. A razão pela qual acredito que isso é que a data de modificação tem vários dias e aponta para um momento em que aumentamos manualmente o valor para tentar eliminar duplicatas. (E o problema ocorreu várias vezes desde então.)

Alguém tem uma idéia do que poderia causar uma reversão de seqüência e reutilizar valores a cada noite?

ATUALIZAÇÃO: Para responder a algumas perguntas nos comentários:

  • @@Version:

    Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64) 19 de outubro de 2012 13:38:57

  • Criar script:

    CREATE SEQUENCE [schemaName].[SequenceName] 
      AS [bigint]
      START WITH 410014104
      INCREMENT BY 1
      MINVALUE 410000000
      MAXVALUE 419999999
      CYCLE 
      CACHE 
    GO
    
  • Não tenho uma restrição única (mas pretendo colocar uma). No entanto, isso só me ajudará a saber quando reutilizei um valor. Não foi o que causou a redefinição dos valores. Eu coloquei um trabalho que iria obter um novo valor a cada 5 minutos e salvá-lo. Os tempos e os saltos de valor não seguem um padrão.

  • Eu verifiquei os logs de eventos para ver se há algum erro. O único pensamento que está acontecendo é o seguinte: http://support.microsoft.com/kb/2793634 Estamos aplicando a correção hoje. Eu não acho que isso esteja relacionado, mas poderia ser.
Vaccano
fonte
1
Por que não há uma restrição PK ou Exclusiva nesta coluna? Com isso, essa reutilização será capturada e você não precisará adivinhar de onde vem, a menos que o código do aplicativo apenas engula todos os erros ...
Aaron Bertrand
Você pode mostrar a definição da sua sequência? Além disso, você pode verificar o log de erros para ver se algum evento significativo ocorreu durante a noite (por exemplo, failover, reinício do serviço, problemas de memória etc.)?
Aaron Bertrand
2
O que é @@VERSION? Também mudou alguma coisa sobre o meio ambiente? Há um item de conexão relatando algo semelhante. O OP lá acha que foi associado11.0.3000.0
Martin Smith
2
Bem, o CYCLE basicamente diz ao SQL Server que você está bem com a reutilização de valores. Não tenho absolutamente nenhuma idéia do motivo pelo qual você está enfrentando esse problema e não sei se o descobrirá (por quanto tempo você gasta investigando por que ficou com um pneu furado antes de substituí-lo?). Ainda acho que sua melhor aposta é ter uma restrição para impedir duplicatas e desativar o cache na esperança de impedir a reutilização.
Aaron Bertrand

Respostas:

11

Primeiro, se você não deseja duplicatas nesta coluna, indique isso explicitamente .

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

(Ou você pode tornar essa a chave primária ou alterar o índice em cluster ou o que você tem ...)

De qualquer forma, gerar um erro ao gerar uma duplicata é muito melhor do que apenas inserir cegamente uma duplicata com a qual você precisará lidar mais tarde.

Em seguida, considere que uma SEQUENCE é apenas um gerador de números e, por padrão, possui um cache de 50 valores. Dependendo de como suas transações são configuradas e de quais outros eventos críticos acontecem em um servidor, é possível que o SQL Server possa "esquecer" que gerou certos valores para você. Desculpe, mas não sei exatamente qual o fator de critério para reproduzir esse bug. A maneira de contornar isso (até que o bug seja resolvido / explicado ) é alterar a sequência a ser usada NO CYCLEe NO CACHE, por exemplo:

ALTER SEQUENCE dbo.mysequence NO CYCLE NO CACHE; 

Observe que isso NO CACHEpode afetar o desempenho e a simultaneidade, mas ajudará a eliminar lacunas, blocos perdidos e, quem sabe, talvez também o seu problema.

Você também pode verificar se está no service pack e na CU mais recentes. Neste ponto, recomendo o SP1 e o CU10 com 3437 ; O SP2 está fora, mas ainda existe um problema crítico nas reconstruções online que podem afetá-lo .

Aaron Bertrand
fonte
Bem, não posso fazer backup. Portanto, se o NO CACHE não resolver isso, é o que farei.
Vaccano
Eu pensei que pode haver transações causando isso. Mas a página Sequência no MSDN diz "Os números de sequência são gerados fora do escopo da transação atual. Eles são consumidos se a transação usando o número de sequência for confirmada ou revertida". Então, descartei minha teoria de transações. Eu concordo que deve haver algo mais acontecendo.
Vaccano
Acontece que apenas defini-lo com NO CYCLEfoi suficiente. (Pelo menos, não aconteceu ontem à noite.) Obrigado pela ajuda!
Vaccano 19/06/2014
1
CORRECÇÃO: O objeto de sequência gera valores de sequência duplicados quando o SQL Server 2012 ou SQL Server 2014 está sob pressão de memória Suponha que você crie um objeto de sequência que tenha a opção CACHE ativada no Microsoft SQL Server 2012 ou SQL Server 2014. Quando a instância estiver sob pressão de memória , e várias conexões simultâneas solicitam valores de sequência do mesmo objeto de sequência, valores de sequência duplicados podem ser gerados. Além disso, um erro de violação de chave única ou primária (PK) ocorre quando o valor da sequência duplicada é inserido em uma tabela.
Andomar 2/09/2015