Glorf.it

Glorf IT

Bedenkliches aus dem IT-Alltag

12. Juli 2006 um 18:50

Ursachen für Datenbank-Defekte (Teil 1)

Wenn ich im Kopf so die Liste der Dinge durchgehe, die wir schon als Ursachen für Datenbank-Defekte ausmachen konnten, dann gibt es so viele potentielle Ursachen, dass ich wohl eine Reihe daraus machen muss. Irgendwie drängt es mich mit den Hauptursachen anzufangen, aber die kennt Ihr ja bestimmt schon. Deswegen fange ich mit den verrückten Sachen an.

Wetter
Das Wetter habe ich ja schon genannt… 😉

Zipper
Als ich 1993 in meiner Firma anfing, hatten wir gerade eine Serie von Datenbank-Problemen. Wie sich zeigte arbeitete der von uns damals (noch unter OS/2 eingesetzte) PKZIP nicht korrekt. Es betraf komischerweise fast ausschließich Datenbank-Devices. Der Test war zum Glück einfach: Datei zippen, entzippen und binär mit dem Original vergleichen. Die Trefferquote war so hoch, das wir sogar eine neue Version bekamen.
Ich meine mich zu erinnern, dass wir vor gar nicht allzulanger Zeit ähnliche Probleme mit dem Entpacken von ZIPs hatten, die größer als eine bestimmte Grenze waren (war es 2 GBytes oder 4 GBytes?). Das betraf die letzte FreeWare-Version des PowerArchivers. Dann musste die kostenpflichtige angescaft werden. Allerdings traf uns das im Zusammenhang mit VMWare-Images.

Mails
Kollegen kommen immer wieder auf die Idee mir Datenbank-Dateien per Mail zu schicken. Ende der 90er kam es da häufiger vor, dass die Datenbank defekt in meinem Outlook ankam, obwohl die Datei beim Absender OK war. Komischerweise machen das einige Kollegen immer noch, aber dabei ist schon länger keine DB mehr rübergerudert.

CD/DVD-Brennprogramme
Immer wieder senden Kunden Ihre Daten zu uns ein, damit die Kollegen in den Fachabteilungen bestimmte Probleme oder Effekte nachvollziehen können. Dabei kommen unregelmäßig nur schrottige Datenbanken bei uns an. Neben den ganz normalen CRC-Fehlern (hat Kunde nicht bemerkt, weil beim Brennen kein Verify durchgeführt wurde) kommen auch ganz leere Dateien bei uns an. Sie haben die richtige Größe, bestehen von vorne bis hinten aber aus Hex00.
Immer wieder schaffen es Kunden die Datenbank-Dateien zu brennen ohne den SQL-Server-Dienst zu beenden. Bei bisher ungeklärten Umständen stehen dann "leere" Dateien auf der DVD/CD. Fast alle Betroffenen hatten Nero im Einsatz, aber ich konnte es noch nicht reproduzieren.
Daher schaue ich mir die Datenbank-Dateien immer als erstes mal im Hex-Editor an. Das geht mit dem Programm XVI32 ganz prima. Es arbeitet auch mit sehr großen Dateien noch gut.

Nur mal als Randnotiz: Wir hatten auch mal einen Kunden, der eine Datenbank gebrannt hat, dabei den SQL Server nicht stoppte und dessen Datenbank danach so richtig im Eimer war. Er behauptet sie sei vorher völlig in Ordnung gewesen. Das konnte mein Kollege natürlich nicht kontrollieren, wir wissen nur, dass sie hinterher so kaputt war, dass sie sich nicht mehr reparieren ließ.

WordPad
Ein Kunde hatte mal Netz-Probleme und konte sich mit der Anwendung nicht zum Datenbank-Server verbinden. Weil er nicht auf den Kopf gefallen war, hat er erst mal in der Datenbank nachgeschaut und die Sybase-SQL-Anywhere-Datebank mit dem Notepad aufgemacht. Natürlich sah er nur Nonsense und komische Zeichen. Daraufhin rief er an und beschwerte sich. Es stellte sich heraus, dass die Datenbank wirklich defekt war. Aber nur, weil die Datei für den Notepad zu groß war und deswegen im WordPad geöffnet wurde. Als er das Programm schloss wurde er gefragt, ob er speichern will. Er schaute sich den Dialog nicht groß an, sondern drückte nur auf die Leertaste. Beim Speichern wurde die Datei um ein paar WordPad-Stuerzeichen ergänzt, z.B. ein schöner langer Datei-Header, ein paar Hex00 wurden entfernt und Sonderzeichen ersetzt.
Im Ergebnis war die Datenbank nur noch Schrott.
Habe ich schon erwähnt, dass der Anwendersupport die Kunden nur zu uns durchgestellt, wenn es keine Datensicherung gibt und wir die letzte Hoffnung sind? Das war eine bittere Pille für den Mann…

Bald kommt noch mehr zum gleichen Thema.

11. Juli 2006 um 00:27

Einfluss des Wetters auf die Häufigkeit von Datenbankdefekten

Wir haben festgestellt, dass das Wetter eindeutig Einfluss auf die Häufigkeit von Datenbank-Defekten hat. Bei jeder der "Hitzewellen" der letzten Wochen bekamen wir von Kunden täglich eine oder manchmal zwei defekte Datenbanken eingeschickt. In den gemäßigten Phasen mit normalen Temperaturen bekommen wir pro Woche eine oder mal auch gar keine. Am Montag bekamen wir zum Beispiel vier (wenn man das auf Sa/So/Mo rechnet sind es 4/3tel DBs pro Tag).

An den heißen Tagen ist in der Regel klar ein Versagen der Festplatten die Ursache, an den anderen ist die Ursache normalerweise schwer festzustellen. Wir haben punktuell schon ein paar Ursachen rausgefunden, die ich irgendwann ja mal posten kann. Aber die Ursachenanalyse aus der Ferne ist immer schwierig und auch ein wenig Glücksache.

Ich habe den Verdacht, dass bei etliche Kunden der Server in einem kleinen nicht-klimatisierten und deswegen überhitzen Raum steht. Am besten noch unter dem Dach, so wie bei meinem ersten Arbeitgeber. Da war es im Serverraum schier nicht auszuhalten. Und wenn dann auch noch von draußen Hitze kommt, dann rudern Festplatten eben schneller rüber. Ich meine in einer der CTs vom Anfang des Jahres hätte auch ein Artikel potentielle Ursachen für Festplatten-Defekte thematisiert und dort stand auch etwas über überhitzen. Leider finde ich den Artikel nicht mehr. 🙁

8. Juli 2006 um 00:31

Ein Median mit SQL Server 2000

Ich habe heute entdeckt, dass bei head.WriteLine(): Das Median-Problem, Teil 2 diskutiert wird, wie man mit SQL den Median berechnen kann. Die folgende Formulierung reizte meinen Spieltrieb:

Dank der neuen Rankingfunktionen des SQL Server 2005, ist die Ermittlung jedoch wesentlich einfacher als mit den Vorgängerversionen. Hier hätte ich den Median nämlich in zeitaufwendigen Cursor- oder Schleifendurchläufen ermitteln müssen.

Generell stimmt es, die neuen Ranking-Funktionen sind wirklich großartig. Ich hatte sie schon sooo lange vermisst. Aber die Geschichte mit den Cursors oder Schleifen möchte ich gerne widerlegen.
Eine simple Median-Berechnung würde mit SQL Server 2000 so aussehen:

select top 1 Quantity as "Fast Median (1)"
     from (    SELECT TOP 50 percent Quantity
                      FROM #bla
                      order by Quantity) as d
     order by Quantity desc

Ein Blick auf den Query Plan zeigt, dass hier noch leichter Spielraum für Verbesserungen besteht:

select max(Quantity) as "Fast Median (2)"
     from (    SELECT TOP 50 percent Quantity
                      FROM #bla
                      order by Quantity) as d

Nun leider ist das Leben nicht immer so einfach. Obige Berechnungen klappen nur bei einer ungeraden Anzahl an Werten. Aber wie man in der Wikipedia nachlesen kann, muss man bei einer geraden Anzahl den Durchschnitt der mittleren Werte ausgeben. Das sieht dann schon komplizierter aus.

select ((select max(Quantity)
                   from (    SELECT TOP 50 percent Quantity
                                    FROM #bla
                                    order by Quantity asc) as d)
          +(select min(Quantity)
                   from (    SELECT TOP 50 percent Quantity
                                    FROM #bla
                                    order by Quantity desc) as d)
          )/2 as "richtiger Median"

Wenn jetzt zu allen Übel die Werte noch ganzzahlig sind, dann muss man vor der Division den Typ in Numeric konvertieren:

select cast(
          (select max(Quantity)
                from (    SELECT TOP 50 percent Quantity
                                   FROM #bla
                            order by Quantity asc) as d)
        +(select min(Quantity)
                from (    SELECT TOP 50 percent Quantity
                                   FROM #bla
                            order by Quantity desc) as d)
        as numeric(12,2))/2 as "richtiger Median bei ganzen Zahlen"

Natürlich ist diese Lösung nicht blitzschnell, aber durch einen geeigneten Index kann man das Ganze doch schön beschleunigen.

Zuletzt noch der Code, um die Beispieltabelle anzulegen und zu bestücken:

if object_id(N'tempdb..#bla') is not null drop table #bla
create table #bla (quantity numeric(12,2))

insert into #bla(quantity) values (1)
insert into #bla(quantity) values (2)
insert into #bla(quantity) values (3)
insert into #bla(quantity) values (4)
insert into #bla(quantity) values (5)
insert into #bla(quantity) values (105)
5. Juli 2006 um 19:23

SQL Server Everywhere Edition

Die SQL Server Everywhere Edition, die als Ablösung für die SQL Server Mobile Edition angekündigt wurde, soll nun auch auf den anderen Windows-Plattformen laufen. Derzeit steht ein CTP zum Download bereit.

Wenn das stimmt, dann schließt Microsoft damit eine Lücke, die wir schon 2002 beängelt haben: Man kann seine Software auch völlig ohne Installation laufen lassen. Das ist bspw. sinnvoll, wenn man seine Datenbanken auf der CD hat. Ich bin schon gespannt, ob es tatsächlich so klappt.

Mein Kollege Markus machte ich auf folgenden Artikel von Microsoft aufmerksam, der ein paar Hintergründe beleuchtet: An introduction to SQL Server 2005 Everywhere Edition Community Technology Preview

Microsoft SQL Server 2005 Everywhere Edition (SQL Server Everywhere) is the rebranding of Microsoft SQL Server 2005 Mobile Edition (SQL Server Mobile) 3.0 without the desktop restriction. SQL Server Mobile 3.0 was released in 2005 with Microsoft Visual Studio 2005 and SQL Server 2005. SQL Server Mobile 3.0 is supported on devices and Tablet PCs and is partially supported on desktop computers. On desktop computers, either Visual Studio 2005 or SQL Server 2005 had to be installed to use SQL Server Mobile 3.0. With SQL Server Everywhere, this restriction has been removed. In SQL Server Everywhere, users can develop and deploy applications independent of SQL Server 2005 and Visual Studio 2005.

Das klingt prima, ich bin schon ganz aufgeregt. Hoffentlich komme ich bald mal dazu das auszuprobieren… 🙂

Nachtrag:

In seinem Weblog beantwortet Steve Lasker eine Menge Fragen zum SQL Server Everywhere. Und Sitaram Raju aus dem SQL Mobile Team hat auch einen Weblog für das SQL Mobile Team bei Microsoft nur zu dem Thema SQL Server Everywhere aufgemacht.
Weblogs sind doch eine tolle Sache!

4. Juli 2006 um 17:22

Intellisense für SQL-Statements

Am Sonntag entdeckt und gleich installiert: Seit gestern habe ich echtes Intellisense für SQL-Statements im Query Analyser und im SQL Server Management Studio: SQL Prompt. Unglaublich, aber es funktioniert tatsächlich. Man muss dem Werkzeug lediglich nach und nach die verschiedenen Connectons beibringen, dann saugt es sich die kompletten Meta-Daten der aktuellen Datenbank rein und los gehts.

SQL Prompt

Leider klappt das bei unseren Standard-Datenbanken nicht. Wir haben so abgedrehte Namen wie "d:\firma\daten\anwendung\data\standard\ua" für unsere Datenbanken. (Das klingt schlimmer als es ist und hat für uns unbestreitbare Vorteile, sonst hätten wir das nicht gemacht.) Entweder ist er Name zu lang oder das Tool kommt mit den Sonderzeichen nicht zu recht… Es geht jedenfalls nur mit Datenbanken mit "normalen" Namen, wie "blabla" oder "Northwind".

In der einer Begrüßungsmail bekam ich (vom Absender "sales@…") die Info, dass sie für jedes Kundenfeedback dankbar sind. Ich bin ja mal gespannt, ob sie auf den Hinweis mit den Datenbanknamen tatsächlich dankbar reagieren… 😉

Ich sehe gerade, dass das Werkzeug nur bis zum 1.9.2006 kostenlos erhältlich ist (man muss sich registrieren und bekommt dann eine Begrüßungsmail). Also dann mal ran…

4. Juli 2006 um 17:18

explicit collations in cross database statements

Gestern hatten wir wieder den Fall, dass ein Lieferant in die Collation-Falle getappt ist. Sie legen eine temporäre Tabelle an und verjoinen sie mit einer Tabelle in deren Datenbank. Weil aber die TempDB (in der die temporäre Tabelle liegt) unter Umständen eine andere Default Collation hat als die Anwendungsdatenbank und bei den Create Table-Statement nichts weiter angegeben wurde, haben die Varchar-Felder der Tabellen potentiell unterschiedliche Collations.

Das führt zu dem bekannten Fehler:

Konflikt der Sortierung für die concatenation-Operation kann nicht aufgelöst werden.

Die Lösung ist ganz einfach und sollte generell eingesetzt werden, wenn man Software auf SQL Servern betreibt, die man sich mit anderen Anwendungen teilt: Man muss bei allen Operationen mit Char/Varchar/nchar/nvarchar-Typen explizit angeben welche Collation für Vergleichsoperationen verwendet werden soll. Dann ist für den SQL Server klar, wann die Zeichenketten "gleich"/"größer"/"kleiner" sind. Wenn nicht, woher soll er wissen, anhand von welcher Collation er das festlegen soll?

Die Lösung im Falle von temporären Tabellen ist noch einfacher: Es reicht wenn man beim Anlegen der Tabellen von Char/Varchar/nchar/nvarchar-Typen explizit angibt, welche Collation verwendet werden soll. Wenn man hier die gleiche Collation wählt, wie in seiner Anwendungsdatenbank, dann kann nichts schiefgehen:

create table #MyTempTab
(id integer identity(1,1) primary key,
name varchar(200) COLLATE Latin1_General_CI_AS, ...)

Das gilt übrigens auch für Table-Variablen, weil auch sie in der TempDB gespeichert werden:

declare @MyTableVar table
(id integer identity (1,1),
name varchar(200) COLLATE SQL_Latin1_General_Pref_CP1_CI_AS)

Eine andere Möglichkeit für das Anlegen der temporären Tabelle ist einfach SELECT INTO zu verwenden, auch dann wird die Collation der Quell-Attribute beibehalten.

select id, name
into #mytemptable
from Me.MyTestTable

Weitere Hinweise stehen in der Online-Hilfe des SQL Servers unter "Transact-SQL Reference | Collate" und "Transact-SQL Reference |Collation Precedence".

3. Juli 2006 um 23:01

SQL Server Storage Engine

Gestern fand ich auf Euan Garden's BLOG einen sehr, sehr interessanten Hinweis: Paul Randal (Mr. DBCC) hat einen eigenen Weblog: SQL Server Storage Engine.

Dort stehen unglaublich fundierte Informationen zu wichtigen Interna des SQL Servers, z.B.

So viel Hochkarätiges auf einen Haufen habe ich schon lange nicht mehr gesehen. Ich hoffe, ich komme dazu die alle mal in Ruhe zu lesen… 🙂

2. Juli 2006 um 10:47

TempDB auf RamDisk

Ich bin heute über den Artikel "Microsoft SQL Server I/O subsystem requirements for the tempdb database" im Weblog von Bejamin Jones gestolpert. Wir gehen davon aus, dass unsere Kunden langsam aber sicher serverseitig auf 64-Bit-Server umsteigen. Das hat für sie den Vorteil, dass sie für vergleichsweise wenig Geld richtig viel Hauptspeicher nutzen können. Ich denke das dürfte ein genereller Trend werden.

Im kleineren bis mittleren Büros ist der 32-Bit SQL Server Standard Edition ziemlich verbreitet. Warum solte man auch viel Geld für die Enterprise Edition ausgeben. Die Standard Edition nutzt maximal 2 GBytes Hauptspeicher. Um einen Performance-Boost rauszuholen, könnte man jetzt hergehen und die TempDB auf eine RamDisk legen.

Dabei muss man allerdings ein paar Dinge beachten (weitere stehen in dem Whitepaper):

  • Die RamDisk muss schon vor dem Start des SQL Servers "online" sein. Da könnte es mit der Startreihenfolge der Dienste schwierig werden.
  • Es muss so viel RAM in dem Srever stecken, dass weder der SQL Server noch die RamDisk ausgelagert werden. Die dabei auftretenden sehr negativen Effekte kann man unter dem Stichwort "double page fault" in der klassischen DB-Literatur nachlesen.
  • Die RamDisk sollte genug Spielraum haben, damit die TempDB wachsen kann. Sonst kommt die Meldung, dass das Device voll ist. Die maximale Größe der TempDB ist nach meiner Erfahrung so gut wie nicht vorherzusagen, wenn die Anwender nicht einfach nur buchen. sondern auch Auswertungen fahren können.

Trotzdem glaube ich, dass sich das in vielen Fällen lohnen dürfte.