Error 7105 – konkurrencia érdekesen

A konkurrencia margójára egy érdekes hiba és megoldása:
Error: 7105, Severity: 22, State: 6
Page (1:42521), slot 14 for text, ntext, or image node does not exist.

Ilyet is tud mondani esetenként az SQL Server, és ez elég rosszul néz ki elsőre. Pár perc guglizás után sokkal rosszabbnak tűnik, mert az értelmezés szerint valószínűleg van egy corrupt page (vagy legalábbis referencia) az adatbázisban, de ha futtatunk egy DBCC CHECKDB-t, akkor semmi hiba nem derül ki (ha kiderül, akkor az a B ág, lehet restore-olni :). Aztán pár nap múlva megint előjön, majd semmi hetekig, megint előjön, és az ember kezdi furcsán érezni magát.
A leggyakoribb előidézője ennek az esetnek a csodálatos read uncommitted tranzakciós szint, megoldása pedig a dirty read elkerülése. Mi is történik? A read uncommitted szintről már tudjuk, hogy ő olvas mindent pillanatnyi állapot szerint, függetlenül attól, hogy az a tranzakció, ami előidézte a jelenlegi állapotot, befejeződött-e vagy még nem. A másik fő jellemzőjét a locking hintként elérhető művészneve adja: NOLOCK. Azaz ő nem lockol semmit. Ennek akkor van jelentősége, maikor valaki töröl vagy módosít, mert ilyenkor a “normál” read committed query a shared lockjával nem engedi, hogy kihúzzák alóla a rekordot, de az uncommitted queryvel mindent meg lehet tenni, ezt is. És aztán amikor eljut egy BLOB-hoz a query, ami a rekordban csak egy 16 byte-os pointer képében tárolódik, és valójában egyéb lapokra van “kitéve” az adatbázis fájlban, akkor még az is megeshet, hogy éppen volt valami módosítás a BLOB-ok háza táján, és amit mi a fenti példában a 42521-es lap 14. rekeszében keresünk, az már átugrott valahova máshova, vagy egyszerűen törölve lett. A pointer persze update-elődik a rekordban, de aki uncommitted módon olvas, az pont be tud esni két szék közé ilyenkor.
Az igazi megoldás a snapshot izolációs szint bekapcsolása és használata az alkalmazásból való nolock-os kérdezések helyett.

Leave a comment