Sekwencja jest ponownie wykorzystywana

11

Mam sekwencję, która generuje numery śledzenia dla obiektów w moim systemie. Od dłuższego czasu działało dobrze.

W zeszłym tygodniu zauważyliśmy, że zaczyna ponownie wykorzystywać wartości.

Wydaje się, że w różnych momentach wieczorem nastąpi powrót do wartości, którą miał poprzedniego dnia. Następnie będzie kontynuował generowanie wartości od tego momentu.

Na przykład mogę dostać coś takiego:

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

Wydaje się, że nie ma żadnego wzorca, kiedy to się dzieje, czasu między pierwszym użyciem a drugim użyciem (zaledwie 10 minut lub kilku godzin) lub liczby cofniętych (zaledwie 1 i aż kilkaset).

Myślałem o uruchomieniu śledzenia (i nadal może), ale nie sądzę, aby obiekt sekwencji był bezpośrednio modyfikowany. Uważam, że powodem tego jest fakt, że data modyfikacji ma kilka dni i wskazuje na czas, kiedy ręcznie podnieśliśmy wartość, aby spróbować wyeliminować duplikaty. (Od tego czasu problem pojawiał się kilka razy).

Czy ktoś ma pojęcie o tym, co może spowodować wycofanie sekwencji i ponowne użycie wartości każdej nocy?

AKTUALIZACJA: Aby odpowiedzieć na kilka pytań w komentarzach:

  • @@Version:

    Microsoft SQL Server 2012 (SP1) - 11.0.3000.0 (X64) 19 października 2012 13:38:57

  • Utwórz skrypt:

    CREATE SEQUENCE [schemaName].[SequenceName] 
      AS [bigint]
      START WITH 410014104
      INCREMENT BY 1
      MINVALUE 410000000
      MAXVALUE 419999999
      CYCLE 
      CACHE 
    GO
  • Nie mam wyjątkowego ograniczenia (ale planuję je nałożyć). To jednak pomoże mi tylko wiedzieć, kiedy ponownie użyłem wartości. Nie to, co spowodowało zresetowanie wartości. Nakładam na to zadanie, które zyskuje nową wartość co 5 minut i oszczędza. Skoki czasu i wartości nie są zgodne ze wzorem.

  • Sprawdziłem Dzienniki zdarzeń, aby zobaczyć, czy wystąpił błąd. Jedyne, co się dzieje, to: http://support.microsoft.com/kb/2793634 Stosujemy poprawkę dzisiaj. Nie sądzę, że są ze sobą powiązane, ale może być.
Vaccano
źródło
1
Dlaczego w tej kolumnie nie ma ograniczenia PK ani unikatowego? Dzięki temu ponowne użycie zostanie złapane i nie będziesz musiał zgadywać, skąd pochodzi, chyba że kod aplikacji tylko połknie wszystkie błędy ...
Aaron Bertrand
Czy możesz pokazać definicję swojej sekwencji? Czy możesz również sprawdzić dziennik błędów, aby sprawdzić, czy jakieś znaczące zdarzenia wydarzyły się z dnia na dzień (np. Przełączenie awaryjne, ponowne uruchomienie usługi, problemy z pamięcią itp.)?
Aaron Bertrand
2
Co to jest @@VERSION? Czy coś się zmieniło w środowisku? Istnieje element Connect zgłaszający coś podobnego. OP uważa, że ​​był z tym związany11.0.3000.0
Martin Smith
2
Cóż, CYCLE zasadniczo mówi SQL Server, że jesteś w porządku z ponownym użyciem wartości. Nie mam pojęcia, dlaczego masz ten problem, i nie wiem, że dowiesz się, dlaczego (ile czasu poświęcasz na zbadanie przyczyny przebicia opony, zanim ją wymienisz?). Nadal uważam, że najlepszym rozwiązaniem jest ograniczenie dostępu w celu zapobiegania duplikacjom i wyłączenie buforowania w nadziei na zapobieganie ponownemu użyciu.
Aaron Bertrand

Odpowiedzi:

11

Po pierwsze, jeśli nie chcesz duplikatów w tej kolumnie, wyraźnie to zaznacz .

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

(Możesz też chcieć ustawić ten klucz podstawowy, zmienić indeks klastrowany lub co masz ...)

W każdym razie zgłoszenie błędu podczas generowania duplikatu jest znacznie lepsze niż zwykłe wstawienie duplikatu, z którym będziesz musiał sobie później poradzić.

Następnie zastanów się, że SEKWENCJA jest tylko generatorem liczb i domyślnie ma pamięć podręczną 50 wartości. W zależności od konfiguracji transakcji i innych krytycznych zdarzeń na serwerze SQL Server może „zapomnieć”, że wygenerował dla ciebie określone wartości. Przepraszam, ale nie wiem dokładnie, jakie kryteria wpływają na odtworzenie tego błędu. Sposobem na obejście tego (dopóki błąd nie zostanie rozwiązany / wyjaśniony ) jest zmiana sekwencji do użycia NO CYCLEi NO CACHEnp .:

ALTER SEQUENCE dbo.mysequence NO CYCLE NO CACHE; 

Pamiętaj, że NO CACHEmoże to wpłynąć na wydajność i współbieżność, ale pomoże wyeliminować luki, utracone bloki i, kto wie, może również twój problem.

Możesz także sprawdzić, czy korzystasz z najnowszego dodatku Service Pack i CU. W tym momencie polecam SP1 i CU10 z 3437 ; Dodatek SP2 został wydany, ale nadal istnieje krytyczny problem z odbudowaniami online, który może mieć na ciebie wpływ .

Aaron Bertrand
źródło
Cóż, nie mogę mieć kopii zapasowej. Więc jeśli ŻADNY DACH nie naprawi tego, to właśnie to zrobię.
Vaccano
Myślałem, że mogą to powodować transakcje. Ale strona Sekwencja w MSDN mówi: „Numery sekwencji są generowane poza zakresem bieżącej transakcji. Są one wykorzystywane, niezależnie od tego, czy transakcja wykorzystująca numer sekwencyjny została zatwierdzona, czy wycofana”. Odrzuciłem więc moją teorię transakcji. Zgadzam się, że musi być coś jeszcze.
Vaccano
Okazuje się, że wystarczyło samo ustawienie NO CYCLE. (Przynajmniej nie stało się to ostatniej nocy.) Dziękuję za pomoc!
Vaccano,
1
POPRAWKA: Obiekt sekwencji generuje zduplikowane wartości sekwencji, gdy SQL Server 2012 lub SQL Server 2014 znajduje się pod presją pamięci Załóżmy, że tworzysz obiekt sekwencji z włączoną opcją CACHE w Microsoft SQL Server 2012 lub SQL Server 2014. Gdy wystąpienie jest pod presją pamięci , a wiele równoczesnych połączeń żąda wartości sekwencji z tego samego obiektu sekwencji, można wygenerować duplikaty wartości sekwencji. Ponadto błąd naruszenia unikalnego lub klucza podstawowego (PK) występuje, gdy wartość zduplikowanej sekwencji jest wstawiana do tabeli.
Andomar