Podczas pracy z C # Entity Framework zauważyłem awarię mojej instancji SQL Server.
Byłem w stanie wyśledzić to do tego stwierdzenia:
SELECT * FROM dbo.[TestTable]
where mpnr in (1099059904,
1038139906,
1048119902,
1045119902,
1002109903,
1117109910,
1111149902,
1063149902,
1117159902,
1116109904,
1105079905,
1012079906,
1129129904,
1103059905,
1065059905,
1091059906,
1110149904,
1129149903,
1083029905,
1080139904,
1076109903,
1010019902,
1058019902,
1060019903,
1053019902,
1030089902,
1018149902,
1077149902,
1010109901,
1011109901,
1000119902,
1023049903,
1107119909,
1108119909,
1106119909)
Tabela wygląda następująco:
CREATE TABLE dbo.[TestTable]([MPNR] [numeric](9, 0) NOT NULL)
Awaria występuje przy każdym uruchomieniu zapytania. Jeśli zmniejszę liczbę wartości w IN
klauzuli, to zadziała. (Oczywiście nie zwraca wierszy.)
Wiem, że wartości w IN
klauzuli są liczbami 10-cyfrowymi, a kolumna ma tylko 9 cyfr, ale nie powinno to prowadzić do awarii całej instancji SQL Server.
Moja wersja SQL Servera to 2008 R2 w 32-bitowym systemie Windows Server 2003.
Czy to znany błąd? Czy istnieje łatka dla programu SQL Server?
sql-server
sql-server-2008-r2
crash
SteLoe
źródło
źródło
Odpowiedzi:
Byłem w stanie zreperować na 2008 R1 SP3 10.00.5512, ale zainstalowałem najnowszą CU (14).
Przeglądając błędy naprawione w interweniujących wersjach, wygląda na to, że musisz uaktualnić do wersji zawierającej następującą poprawkę.
Naruszenie zasad dostępu po uruchomieniu zapytania zawierającego wiele stałych wartości w klauzuli IN w SQL Server 2008 lub SQL Server 2012
W 2008 R2 potrzebujesz co najmniej 9 CU dla SP1 lub CU 5 dla SP2.
Opis objawów jest dość krótki, ale wspomina o niedopasowanych typach danych
Nie definiuje „wielu”. Z testów, które zrobiłem, podejrzewam, że może to oznaczać „20 lub więcej”, ponieważ wydaje się, że jest to punkt odcięcia między dwiema różnymi metodami szacowania liczności.
Katastrofa miała miejsce w ramach kilku metod wywoływanych przy
CScaOp_In::FCalcSelectivity()
użyciu nazw takich jakLoadHistogramFromXVariantArray()
iCInMemHistogram::FJoin() -> WalkHistograms()
.W przypadku 19 lub mniej różnych pozycji na liście metody te w ogóle nie były wywoływane. Podobny SQL Sever 2000 bug wspomina również ten punkt odcięcia jako znaczące.
Wypełnianie tabeli testowej 100 000 wierszy losowych danych testowych wartościami od 0 do 1047 i histogramem rozpoczynającym się w następujący sposób
Zapytanie
Pokazuje szacunkowe wiersze z 1856 r.
Jest to dokładnie to, czego można się spodziewać po uzyskaniu szacunkowych wierszy dla 19 predykatów równości indywidualnie i zsumowaniu ich.
Formuła przestaje działać, gdy
20
zostanie dodana do listy w ( wygenerowane zostaną szacunkowe wiersze,1902.75
a nie1952
dodanie tego96
do sumy).BETWEEN
wydaje się używać jeszcze jednej metody obliczania szacunków liczności.where mpnr BETWEEN 1 AND 20
szacuje tylko 1829,6 wierszy. Nie mam pojęcia, jak to wynika z pokazanego histogramu.źródło