How to fix DBCC CHECKDB inconsistency errors in MS SQL Server caused by upgrading from ntext to nvarchar(max)

TL;DR

we were facing database inconsistency issues detected by DBCC CHECKDB / DBCC CHECKTABLE that we’re running in nightly jobs. The cause of this was a as far as we’ve investigated a change from “ntext” / “text” column types to “nvarchar(max)” / “varchar(max)”, and an optimization to a component that stores large strings. this resulted in smaller nvarchar(max) values and somehow caused the inconsistencies.

dont worry, we’ve tested and found a solution that does not corrupt your data, but nothing guaranteed, you do this on your own risk!

  1. take a backup, just in case
  2. remove or disable constraints
  3. rename the old table (e.g. MyTable -> MyTable_TEMP)
  4. create the table structure again directly with nvarchar(max) column types
  5. insert the complete data of the old temp table into the new one
  6. drop the old temp table
  7. restore the constraints.

we’ve since then never faced this issue again.
to learn more, read the long version below 😉

the complete story

some day i had some alarming emails in my inbox from our sql server. somehow some “offrow data” was incorrecly referenced.

Error Message:

Table error: Object ID 1234567, index ID 1, partition ID 987654321, alloc unit ID 123123123123 (type LOB data). The off-row data node at page (1:12345678), slot 0, text ID 7766554433 does not match its reference from page (1:978563412), slot 1.

after some googling i found some posts suggesting me to use “DBCC CHECKDB(‘MyDB’, REPAIR_ALLOW_DATA_LOSS). yeah great start of the day… “allow data loss” sound really great 😀 i will not go into details on how to fix these errors, googling dbcc checkdb should be enough to find infos on that topic, though i was not out final solution. we’ve come up with a “trick” to maintain all data and fix the corruption without data loss, but more on that later (or in TL;DR).

everything on the internet on how that happened blamed the storage subsystem. HDD broken, bit rot, etc. but we’re using ZFS as a storage subsystem and it would have telled me (weekly scrub) if there were any data losses etc. checked the logs, but found noting that pointed to a storage issue. ok. i resolved the issue correcting the database with the dbcc tool, this is strange, but i dont have much time now to chase this issue. it’s resolved, so what. only happend once, right?

no… certainly not right. next week it happened again…

the first try and the MS Support incident

i noticed the second time the error happened, that i got an error message from sql server of “severity 20” some time the day before (or 2 days before) saying:

DESCRIPTION: A read operation on a large object failed while sending data to the client. A common cause for this is if the application is running in READ UNCOMMITTED isolation level. This connection will be terminated.

so we began to investigate further knowing we’re using this isolation level in our software the database belongs to.

long story short, we’ve investigated, talked to MS Support, they said ReadUncommitted is the issue, we changed out codebase to not use ReadUncommitted anymore (instead we used snapshot as adviced by MS), weeks pass by, and… oh look the same inconsistency error. contacted MS Support again, they said, they cannot help us, we have to open up a root case analysis support case, that IMHO costs too much money. so back to the beginning. 🙁

investigating on our own

in the meantime some of our customers contacted us, they also have inconsistencies and are worried about their data. so back at the beginning, i thought what we have changed the past 3 versions in our software since this problem first appeared.

after some research i found these 2 points:

  1. We’ve improved how to store large strings, they now consume much less space in the ntext / nvarchar(max) field of our database [due to compression]
  2. We’ve changed the database layout of our tables to move away from “ntext” and instead use “nvarchar(max)” as suggested by MS.

so what if we saved a large string when the column type was ntext and then updated the field with our new logic, that compresses the content and save it back to the field that now has the column type nvarchar(max) and something with the linking went wrong internally in SQL Server? Remember:

The off-row data node at page [...] does not match its reference from page [...]

hmmm, so i decided to verify my claim.

i played around a little bit with DBCC PAGE, to look at pages and their content in sql server, and found the row that was reported as currupted by DBCC CHECKDB:

Table error: Object ID 1234567, index ID 1, partition ID 987654321, alloc unit ID 123123123123 (type LOB data). The off-row data node at page (1:12345678), slot 0, text ID 7766554433 does not match its reference from page (1:978563412), slot 1.

ok, so the off row data (data that was pushed off the row because it was too big) has a pointer back to the row it belongs to, and this pointer was referencing something wrong. to i looked at the referenced page (marked red above):

dbcc traceon(3604)
dbcc page(MyDB, 1, 978563412, 1) with tableresults

and got the primary key of the row that was affected. ok, now we’ve decyphered the message and are able to play around with this data! yay!

playing around until a solution emerges

i tried to change the nvarchar(max) field data to the same content via an update statement, no changes. ive copied the row: the new row was clean, no new inconsistencies. hm. ok, so i deleted that row. inconsistency gone. yeah, thats what my friend DBCC CHECKDB Repair Allow Data Loss does, but we dont want that. we want to keep our data. luckily i have some more rows that are affected. so on to the next row!

but this time i copied the row out to a temporary table, deleted it and inserted it back into its original table. tadaaa, consistency restored, but without data loss. this is the solution we came up with. in general we wrote a script that copies the complete table to another table, drop the old one and renamed the new one. since then we’ve not faced an inconsistency in this table again. so we think it has to be related to updating the columns from ntext to navarchar(max).

these are the steps our “repair” script does for the table we’ve faced the issue. i know this solution is far from perfect. your partly have doubled the data for this table (copy, rename and then drop) but its the only solution we’ve come up with.

  1. take a backup, just in case
  2. remove or disable constraints
  3. rename the old table (e.g. MyTable -> MyTable_TEMP)
  4. create the table structure again directly with nvarchar(max) column types
  5. insert the complete data of the old temp table into the new one
  6. drop the old temp table
  7. restore the constraints.

finally here are some sql statements i found useful, maybe they’re helpful to somebody. 🙂

all these scipts may be used for any purpose, but at your own risk! nothing guaranteed. DBCC PAGE is an undocumented feature, so be careful, take a backup before and try to test this stuff on a temporary/testing database before you go ahead and try to fix this on a production database!

check contents of page and get primary key of affected row:

dbcc traceon(3604)
dbcc page(MyDB, 1, PageId, Slot) with tableresults

find all inconsistent rows and get their primary key

CREATE TABLE #dbcc_tableresults
([Error] int, [Level] int, [State] int,
[MessageText] varchar(7000), [RepairLevel] varchar(7000), [Status] int,
[DbId] int, [DbFragId] int,[ObjectID] int, [IndexId] int, [PartitionId] bigint,
[AllocUnitId] bigint,
     [RidDbId] int,
     [RidPruId] int,
     [File] int, [Page] int, [Slot] int,
     [RefDbId] int,
     [RefPruId] int,
[RefFile] int, [RefPage] int, [RefSlot] int, [Allocation] int);

-- Execute CheckDB and insert result to temp table

INSERT INTO #dbcc_tableresults
([Error], [Level], [State], [MessageText], [RepairLevel],
[Status], [DbId], [DbFragId] ,[ObjectID], [IndexId], [PartitionId],
[AllocUnitId],
     [RidDbId],[RidPruId],[File], [Page], [Slot], [RefPruId], [RefDbId],[RefFile],
[RefPage], [RefSlot], [Allocation])
EXEC ('DBCC CHECKTABLE(MyCurruptTableName) WITH TABLERESULTS')
with the above script you are able to create a script that only fixes your inconsistent rows, but in our case it was just a matter of time until the next inconsistency occurs, so we’ve decided to copy the whole table.
i’ve omitted the script that copies the rows and re-inserts them because its heavily tied to our DB-Schema and wouldn’t be of gread use to others.
maybe this helps other people in my position to find a solution sooner than i did… 🙂

how to install windows 8(.1) on a thinkpad t430s

das muss kurz raus, damit andere leute ggf. nicht so lange brauchen wie ich.
eigentlich bin ich nur zu dumm zum googlen, weil man genau hier die Info bekommt, woran es liegt dass während des setups das notebook einfriert / freezed.

Also einfach im BIOS “USB UEFI Support” auf “Disabled” setzen dann sollte es gehen.

good luck 🙂

Samsung Series 7 700Z3C S01 Review

lang lang ists her. also, dass ich hardware bestellt hab, meinen blog würde ich ja nie vernachlässigen! -.-

ich hab mir aber gerade nach langem suchen ein neues Notebook besorgt und muss sagen, ich bin extrem glücklich damit.
ich habs jetzt ca. ne woche testen können und war anfangs skeptisch.
Samsung gehört nämlich nicht zu den marken, die sonst notebooktechnisch bei mir auf dem zettel stehen, da ich vorher sehr zufrieden war mit dell und in der firma ausschließlich think pads nutze. (mit denen ich auch sehr zufrieden bin!)
meine suche gestaltete sich recht schwierig, als ich meine “Anforderungen” mal “definiert” hatte. (wow ich arbeite zu viel, meine formulierungen gehn gar nicht… oO)
– 14″ Display (leicht und doch eine displaydiagonale, mit der sich gut coden lässt)
– 1600×900 Pixel (gerade noch nicht zu klein und doch genug platz, erschien mir optimal als ich es auf meinem firmen notebook gesehen habe)
– am besten nicht spiegelnd
– akkulaufzeit über 6h
– sollte (kleinere) games spielbar darstellen, wobei mir der detailgrad da rel. egal ist (z.b. SC2, Humble Indie Bundle, der kram für zwischendurch wenn man sich mal wieder in einem kreativen coding loch befindet), bestenfalls mit optimus (o.ä.) technologie
– sehr gute tastatur (anschlag, kein klappern, beleuchtet)
– ein gutes und großes touchpad (ja, apple kann das gut, so hätt ichs gern, nein kein macbook… 😉 )
– windows und linux sollten gut laufen (also linux treiber wären super)
– die Pos1, Ende, Pg Up, Pg Down tasten dürfen keine Fn/doppelbelegung haben (nervt ungemein beim coden/schreiben)
– umso leichter umso besser
– wenns gut aussieht, ists auch nicht verkehrt, man will sich ja damit auch mal auf der straße zeigen (nein, kein macbook)
tja, das wars dann auch (schon)!

ich habe relativ lange gesucht, u.a. nach ultrabooks und war zuerst bei dem u410 von lenovo, allerdings ist (m.E. entgegen div. testberichte) die verarbeitung (bei mediamarkt mal getestet) unglaublich schlecht. alles aus plastik und wenn man die tastaur in der mitte runterdrückt, dann kann mit mit etwas festerem drücken sogar einen mausklick erzeugen (hoppla…), zudem sind einige tasten die ich für visual studio bzw eclipse oder generell fürd coden benötige über Fn belegt. für mich also ein “no go”.

Wer noch ein bisschen testberichte lesen möchte kann hier (vom vorgnger ohne neueste intel prozessor version)
http://www.notebookcheck.com/Test-Samsung-Series-7-700Z3A-S03DE-Notebook.69137.0.html

und dann zusätzlich hier im update mit dem neuen prozessor und einer nvidia grafikkarte nochmal nachlesen
http://www.notebookcheck.com/Test-Update-Samsung-Serie-7-700Z3C-S01-Notebook.77437.0.html

update:
nach längerem benutzen kann ich sagen, dass der wlan chip bzw die verbindung manchmal probleme macht.
teilweise fühlt es sich so an, als würde der adapter “einschlafen” und dann nach kurzer zeit wieder online kommen.
Das nervt, wenn man z.b. musik hört oder dateien kopiert. auch beim buffern von videos habe ich schon probleme gehabt.
Ich habe mal die neuesten intel treiber installiert und hatte kurzzeitig (gefühlte) besserung. allerdings ist das problem immernoch present. ich werde mal weiter forschen und hier updaten bzw einen neuen post schreiben, wenn ich was dazu raus gefunden habe.

asp.net mvc 4 und visual studio 11 beta

momentan bin ich arbeitsmäßig ziemlich eingespannt, das suckt manchmal schon son bisschen, da bleibt wenig zeit für die privaten sachen, wie z.b. alkohol und xbox, kiez und freunde…

nichtdestotrotz gibts ja auch gute seiten! z.b. ist das neue visual studio in version 11 als beta erschienen und damit dann auch gleich mal die mvc4 beta. darauf applikationen aufsetzen macht mir, umso mehr ich mich damit beschäftige, immer mehr spaß!

heute habe ich eine möglichkeit gesucht, eizelne controller aktionen mit einem “CheckPrivilege” attribut zu versehen. da ich eine recht simple lösung mit eigener validierung benötigte, entschied ich mich für einen selbst gebauten custom filter.

die implementation ist denkbar einfach (danke an stackoverflow an dieser stelle, welches ich übrigens auch komplett liebe!):

public interface IPrivilegeCheckProvider
{
  bool CheckPrivilege(string privilege);
}

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class CheckPrivilegeAttribute : FilterAttribute, IAuthorizationFilter
{
  public string Privilege { get; set; }

  public CheckPrivilegeAttribute()
  {
  }

  public CheckPrivilegeAttribute(string privilegeKey)
  {
    Privilege = privilegeKey;
  }

  public CheckPrivilegeAttribute(object enumValue)
  {
    if (enumValue is Enum)
    {
      Privilege = SecurityHelper.GetPrivilegeKey((Enum)enumValue);
    }
    else
    {
      Privilege = enumValue.ToString();
    }
  }

  public void OnAuthorization(AuthorizationContext filterContext)
  {
    if (filterContext == null) throw new ArgumentNullException("filterContext");
    if (filterContext.Controller == null) throw new ArgumentException("no controller found");

    var checker = filterContext.Controller as IPrivilegeCheckProvider;

    if (checker == null)
      throw new ArgumentException(filterContext.Controller.GetType().Name + " does not implement " + typeof(IPrivilegeCheckProvider).Name);

    bool granted = checker.CheckPrivilege(Privilege);
    if (!granted)
    {
      filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Forbidden, "Privilege '" + Privilege + "' needed to access this page.");
    }
  }
}

Damit ist man dann in der lage den aktionen im controller dieses attribut zu verpassen und im basiscontroller die “CheckPrivilege” methode zu implementieren. wenn diese “false” zurück gibt, wird vom Server eine “403 – Forbidden” response gesendet. in dem fall schlank und genau was ich brauchte 😉

bin dann mal wieder am coden (zu fischmob [was meinen aktuelle geisteszustand relativ gut beschreiben sollte…])

greetz

lars

was kann man eigentlich an deutschem hiphop noch hoeren

tja, das frag ich mich wirklich oft in letzter zeit…
samys album schwarz weiß… ja er kanns es immernoch, aber er rockt einfach nicht mehr… da kann er noch so lange der super mc sein…
vielleicht  deichkind? achne, die machen ja keinen hiphop mehr…

hoffung geben aber bands wie herr von grau, die ich letztens gerade wieder live als vorband von PrinzPi sehen durfte, und auch der prinz macht immernoch musik die sich durchaus gut hören lässt, allerdings fühle ich mich beim konzertpublikum manchmal doch recht alt, aber das liegt wohl auch n bisschen an meinem alter… bin ich jetzt zu alt für hiphop? muss ich jetzt bach oder mozart hören um mit meinesgleichen in einem raum zu stehen.. äh sitzen?!

hmm, fragen über fragen… während ich darüber nachdenke sollte ich mir ein bisschen musik anhören:

http://negundo.de/

oder download: Negundo – 2011 – A Remix Odyssey

http://herrvongrau.de/

da möchte ich euch auch die Tour im Herbst 2012 ans herz legen, in hamburg im fundbüro, wird garantiert extrem super! 😉

oder

oder auch ganz wichtig:

ihr seht schon… fanboy! 🙂

zudem höre ich momentan wieder

Team Avantgarde
eou
und ganz viel von the streets, von den wir aber leider nicht mehr allzu viel erwarten dürfen nach dem mike den /closed-post machte… 🙁
Audio88 u Yassin
Tufu

und wo ich das ganze jetzt hier so sehe.. es gibt doch noch ein bisschen hoffnung und ich bin der letzte der sich zu schade dafür ist, mit 15 jährigen schulter an hüfte abzugehen, hihi 😉

in diesem sinne… rap on! 🙂

mittwoch, zeit fuer musik

damit man ein bisschen besser durch die woche kommt und weil man die werbung auf di.fm langsam schon satt

http://soundcloud.com/segyou/metronomy-the-look-fred-falke

bzw eigentlich alles von dem typen

sowie das hier http://soundcloud.com/jokers-of-the-scene/daniel-avery-rmx

quelle: http://soundcloud.com/jokers-of-the-scene

zwischen durch mal wieder M83 http://vimeo.com/30741456 und http://vimeo.com/6540668

und wenn dann wirklich alles aus ist, dann hilft nur noch thats life…

doctor who, torchwood und andere youtube links

alter ich steh ja auch auf sone scheiße 😉

und andere leute mögen doctor who anscheinend auch ganz gern 😉

http://www.youtube.com/watch?v=f1d21C3fBuo

immer wieder schön, ich freu mich auf jeden fall wieder wahnsinning auf die neuen folgen!
leider schweigt sich tv.com noch aus…

so lange hier nochmal die quelle all dieser nerd-interviews/musik und co geschichten:
http://www.bbcamerica.com/anglophenia/2012/01/doctor-whos-day-roundup-big-bang-theory/

audiolith, bondage fairies und ne schnitzeljagdt mit belohnung

Gerade den Audiolith Newsletter (übrigens einer der wenigen die ich noch lese und nicht direkt lösche) bekommen.
Darin enthalten ist ein kleiner Text zu den Bondage Fairies, ihrem neuen Album und es wird ein Hinweis auf ein “Spiel” gegeben, mit dem man einen neuen Track freigeben kann. So heisst es im Newsletter:

In 17 Städten weltweit wurden USB-Sticks im öffentlichen Raum in Wänden einzementiert auf denen Dateien zum freien Tausch angeboten werden. Die Puzzleteile können dann auf der dafür eingerichteten „Dead Drop Zone“  auf www.bondagefairies.se hochgeladen werden. Jedes Puzzleteil schaltet ein Teilstück eines neuen unveröffentlichten Songs frei, welcher dann nach und nach zu hören ist. Wurden alle Puzzleteile gefunden und hochgeladen, wird der Song zum kostenlosen Download freigegeben.  Das finden wir super!

Auch meiner Meinung nach total Super!

Also mal http://www.bondagefairies.se/ checken und uploaden!

achso und BTW: neuer Frittenbude Track sollte auch nicht unerwähnt bleiben, da er gefällt!