La secuencia se está reutilizando


11

Tengo una secuencia que genera números de seguimiento para objetos en mi sistema. Había estado funcionando bien durante bastante tiempo.

La semana pasada notamos que estaba empezando a reutilizar valores.

Lo que parece suceder es que en diferentes momentos de la noche, retrocederá a un valor que tenía el día anterior. Luego continuará generando valores desde ese punto.

Entonces, por ejemplo, podría obtener algo como esto:

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

No parece haber ningún patrón cuando ocurre, la duración entre el primer uso y el segundo uso (tan solo 10 minutos o varias horas) o cuántos se revierten (tan solo 1 y hasta varios cientos).

Pensé en ejecutar un seguimiento (y aún puede), pero no creo que el objeto de secuencia se esté modificando directamente. La razón por la que creo que esto es porque la fecha de modificación tiene varios días de antigüedad y señala un momento en el que aumentamos manualmente el valor para tratar de eliminar duplicados. (Y el problema ha ocurrido varias veces desde entonces).

¿Alguien tiene una idea de lo que podría causar una reversión de secuencia y reutilizar valores cada noche?

ACTUALIZACIÓN: Para responder algunas preguntas en los comentarios:

  • @@Version:

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

  • Crear secuencia de comandos:

    CREATE SEQUENCE [schemaName].[SequenceName] 
      AS [bigint]
      START WITH 410014104
      INCREMENT BY 1
      MINVALUE 410000000
      MAXVALUE 419999999
      CYCLE 
      CACHE 
    GO
    
  • No tengo una restricción única (pero planeo poner una). Sin embargo, eso solo me ayudará a saber cuándo he reutilizado un valor. No es lo que causó el restablecimiento de los valores. Puse un trabajo que obtendría un nuevo valor cada 5 minutos y lo guardaría. Los saltos de tiempo y valor no siguen un patrón.

  • He revisado los registros de eventos para ver si hay un error. Lo único que está sucediendo es esto: http://support.microsoft.com/kb/2793634 Estamos aplicando la solución hoy. No creo que estén relacionados, pero podría estarlo.

1
¿Por qué no hay una restricción PK o única en esta columna? Con eso en su lugar, esta reutilización quedará atrapada, y no tiene que intentar adivinar de dónde viene, a menos que el código de su aplicación se trague todos los errores ...
Aaron Bertrand


¿Puedes mostrar la definición de tu secuencia? ¿También puede verificar el registro de errores para ver si ocurrieron eventos significativos durante la noche (por ejemplo, conmutación por error, reinicio del servicio, problemas de memoria, etc.)?
Aaron Bertrand

2
¿Qué es @@VERSION? ¿También ha cambiado algo sobre el medio ambiente? Hay un elemento de conexión que informa algo similar. El OP allí reconoce que estaba asociado11.0.3000.0
Martin Smith

2
Bueno, CYCLE esencialmente le dice a SQL Server que está de acuerdo con la reutilización de valores. No tengo ni idea de por qué está teniendo este problema, y ​​no sé si descubrirá por qué (¿cuánto tiempo pasa investigando por qué le pinchó una llanta antes de reemplazarla?). Todavía creo que su mejor opción es tener una restricción allí para evitar duplicados y desactivar el almacenamiento en caché con la esperanza de evitar la reutilización.
Aaron Bertrand

Respuestas:


11

Primero, si no desea duplicados en esta columna, dígalo explícitamente .

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

(O puede querer que esa sea la clave principal, o cambiar el índice agrupado, o lo que sea ...)

En cualquier caso, generar un error cuando genera un duplicado es mucho mejor que simplemente insertar a ciegas un duplicado con el que tendrá que lidiar más tarde.

Luego, considere que una SECUENCIA es solo un generador de números, y por defecto tiene un caché de 50 valores. Dependiendo de cómo estén configuradas sus transacciones y qué otros eventos críticos suceden en un servidor, es posible que SQL Server pueda "olvidar" que generó ciertos valores para usted. Lo siento, pero no sé exactamente qué criterios influyen en la reproducción de este error. La forma de evitar esto (hasta que se solucione / explique el error ) es cambiar la secuencia a usar NO CYCLEy NO CACHE, por ejemplo:

ALTER SEQUENCE dbo.mysequence NO CYCLE NO CACHE; 

Tenga en cuenta que NO CACHEpuede afectar el rendimiento y la concurrencia, pero ayudará a eliminar las brechas, los bloques perdidos y, quién sabe, quizás también su problema.

También es posible que desee verificar que está en el Service Pack y CU más recientes. En este punto, recomiendo SP1 y CU10 con 3437 ; SP2 está fuera pero todavía hay un problema crítico con las reconstrucciones en línea que pueden afectarlo .


Bueno, no puedo tener una copia de seguridad. Entonces, si NO CACHE lo arreglará, entonces eso es lo que haré.
Vaccano

Pensé que puede haber transacciones que causen esto. Pero la página Secuencia en MSDN dice "Los números de secuencia se generan fuera del alcance de la transacción actual. Se consumen si la transacción que usa el número de secuencia se confirma o se revierte". Así que descarté mi teoría de la transacción. Estoy de acuerdo en que debe haber algo más.
Vaccano

Resulta que con solo configurarlo NO CYCLEfue suficiente. (Al menos no sucedió anoche). ¡Gracias por la ayuda!
Vaccano

1
REVISIÓN: El objeto de secuencia genera valores de secuencia duplicados cuando SQL Server 2012 o SQL Server 2014 está bajo presión de memoria. Suponga que crea un objeto de secuencia que tiene la opción CACHE habilitada en Microsoft SQL Server 2012 o SQL Server 2014. Cuando la instancia está bajo presión de memoria y múltiples conexiones concurrentes solicitan valores de secuencia del mismo objeto de secuencia, se pueden generar valores de secuencia duplicados. Además, se produce un error de violación de clave única o primaria (PK) cuando el valor de secuencia duplicada se inserta en una tabla.
Andomar
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.