W jednej z moich tabel Fee
w kolumnie „ReceiptNo” w SQL Server 2012 przyrost tożsamości bazy danych nagle zaczął skakać do 100 zamiast 1, w zależności od następujących dwóch rzeczy.
jeśli jest to 1205446, to skacze do 1206306, jeśli to 1206321, to skacze do 1207306, a jeśli jest to 1207314, to przeskakuje do 1208306. Chcę zauważyć, że ostatnie trzy cyfry pozostają stałe, tj. 306 za każdym razem, gdy skoki występuje, jak pokazano na poniższym rysunku.
ten problem występuje po ponownym uruchomieniu komputera
order by ReceiptNo
do zapytania, czy naprawdę nie ma tych rekordów? Czy na pewno podczas wstawiania rekordów nie ma błędów? Jeśli rekord próbuje się wstawić i nie powiedzie się, tożsamość będzie się zwiększać, to samo, jeśli rekordy zostaną usunięte. Usunięcie rekordówReceiptNo
nie powoduje zresetowania. Czy możesz opublikować tworzenie tabeli dlaFee
stołu?1206306
,1207306
,1207806
) oznacza, że wyjaśnienie w Connect poz wątek dotyczy prawie na pewno.Odpowiedzi:
Takie zachowanie występuje z powodu poprawy wydajności od czasu programu SQL Server 2012.
Teraz domyślnie używa rozmiaru pamięci podręcznej 1000, gdy przydzielanie
IDENTITY
wartości dlaint
kolumny i ponowne uruchomienie usługi może „utracić” nieużywane wartości (rozmiar pamięci podręcznej wynosi 10 000 dlabigint
/numeric
).Jest to wspomniane w dokumentacji
Z przedstawionych danych wynika, że miało to miejsce po wprowadzeniu danych z 22 grudnia, a następnie po ponownym uruchomieniu SQL Server zarezerwował wartości
1206306 - 1207305
. Po wprowadzeniu danych z 24 - 25 grudnia nastąpił kolejny restart i SQL Server zarezerwował następny zakres1207306 - 1208305
widoczny we wpisach na 28 grudnia .O ile nie restartujesz usługi z nietypową częstotliwością, jest mało prawdopodobne, aby jakiekolwiek „utracone” wartości spowodowały jakiekolwiek znaczące obniżenie zakresu wartości dozwolonych przez typ danych, więc najlepszą zasadą jest nie martwić się o to.
Jeśli z jakiegoś powodu jest to dla Ciebie prawdziwy problem, niektóre możliwe obejścia to ...
SEQUENCE
kolumny tożsamości zamiast kolumny tożsamości i zdefiniować na przykład mniejszy rozmiar pamięci podręcznej i użyćNEXT VALUE FOR
w kolumnie domyślnej.IDENTITY
alokacja jest rejestrowana tak, jak w wersjach do 2008 R2. Dotyczy to wszystkich baz danych na całym świecie.ALTER DATABASE SCOPED CONFIGURATION SET IDENTITY_CACHE = OFF
aby wyłączyć buforowanie tożsamości dla określonej bazy danych.Należy mieć świadomość, że żadne z tych obejść nie gwarantuje braku luk. Nigdy nie zostało to zagwarantowane,
IDENTITY
ponieważ byłoby to możliwe tylko przez serializację wstawek do tabeli. Jeśli potrzebujesz kolumny bez przerw, będziesz musiał użyć innego rozwiązania niż jednoIDENTITY
lub drugieSEQUENCE
źródło
SEQUENCE
zamiast aIDENTITY
i ustawić Sekwencję tak, aby rozmiar pamięci podręcznej wynosił0
.CREATE TABLE
widzę, że używasznumeric(7)
i zacząłeś numerować od1200001
tego, co oznacza, że skończysz się po8,799
dniach (24 latach), jeśli używasz 1000 dziennie.big int
kolumna zwykle „przeskakuje” o 10 000 przy każdym ponownym uruchomieniu.Ten problem występuje po ponownym uruchomieniu programu SQL Server.
Rozwiązaniem jest:
Uruchom Menedżera konfiguracji programu SQL Server .
Wybierz usługi SQL Server .
Kliknij prawym przyciskiem myszy SQL Server i wybierz Właściwości .
W oknie otwierającym w sekcji Parametry startowe wpisz
-T272
i kliknij Dodaj , a następnie naciśnij przycisk Zastosuj i uruchom ponownie.źródło
Od
SQL Server 2017+
można użyć instrukcji ALTER DATABASE scoped KONFIGURACJA :źródło
Wiem, że moja odpowiedź może się spóźnić na przyjęcie. Ale rozwiązałem to w inny sposób, dodając startową procedurę składowaną w SQL Server 2012.
Utwórz następującą procedurę składowaną w głównej bazie danych.
Następnie dodaj go do Start up, używając następującej składni.
To dobry pomysł, jeśli masz kilka stołów. ale jeśli musisz to zrobić dla wielu tabel, ta metoda nadal działa, ale nie jest dobrym pomysłem.
źródło
Jest to nadal bardzo częsty problem wśród wielu programistów i aplikacji, niezależnie od rozmiaru.
Niestety powyższe sugestie nie rozwiązują wszystkich scenariuszy, np. Hosting współdzielony, nie możesz polegać na swoim hoście, aby ustawić parametr uruchamiania -t272.
Ponadto, jeśli masz istniejące tabele, które używają tych kolumn tożsamości jako kluczy podstawowych, OGROMNY wysiłek jest porzucenie tych kolumn i odtworzenie nowych, aby użyć obejścia sekwencji BS. Obejście sekwencyjne jest dobre tylko wtedy, gdy projektujesz tabele od podstaw w SQL 2012+
Najważniejsze jest to, że jeśli korzystasz z Sql Server 2008R2, POZOSTAŃ ON IT. Poważnie, trzymaj się tego. Dopóki Microsoft nie przyzna, że wprowadził OGROMNY błąd, który nadal występuje nawet w Sql Server 2016, nie powinniśmy aktualizować, dopóki nie są właścicielami i NAPRAWIĆ.
Microsoft od razu wprowadził przełomową zmianę, tj. Złamał działające API, które nie działa już zgodnie z założeniami, ponieważ ich system zapomina o swojej aktualnej tożsamości przy ponownym uruchomieniu. Pamięć podręczna lub brak pamięci podręcznej, jest to niedopuszczalne, a deweloper firmy Microsoft o nazwisku Bryan musi ją posiadać, zamiast mówić światu, że jest to „zgodne z projektem” i „funkcją”. Jasne, buforowanie jest funkcją, ale utrata świadomości, jaka powinna być następna tożsamość, NIE JEST FUNKCJĄ. To niezły BŁĄD !!!
Podzielę się obejściem, którego użyłem, ponieważ moje bazy danych znajdują się na serwerach Shared Hosting, a także nie upuszczam i nie odtwarzam moich kolumn klucza podstawowego, to byłby ogromny PITA.
Zamiast tego jest to mój haniebny hack (ale nie tak haniebny, jak ten błąd POS, który wprowadził Microsoft).
Hack / Fix:
Przed wykonaniem poleceń wstawiania po prostu ponownie ustaw swoją tożsamość przed każdym wstawieniem. Ta poprawka jest zalecana tylko wtedy, gdy nie masz kontroli administratora nad instancją Sql Server, w przeciwnym razie sugeruję ponowne wprowadzenie po ponownym uruchomieniu serwera.
Tylko te 3 wiersze bezpośrednio przed wstawką i powinno być dobrze. Naprawdę nie wpłynie to tak bardzo na wydajność, tj. Będzie niezauważalne.
Powodzenia.
źródło
Istnieje wiele możliwych powodów przeskakiwania wartości tożsamości. Obejmują one od wycofanych wstawek po zarządzanie tożsamością na potrzeby replikacji. Co jest tego przyczyną w twoim przypadku, nie mogę powiedzieć bez spędzenia czasu w twoim systemie.
Powinieneś jednak wiedzieć, że w żadnym wypadku nie możesz założyć, że kolumna tożsamości jest ciągła. Jest po prostu zbyt wiele rzeczy, które mogą powodować luki.
Więcej informacji na ten temat można znaleźć tutaj: http://sqlity.net/en/792/the-gap-in-the-identity-value-sequence/
źródło