Glorf.it

Glorf IT

Bedenkliches aus dem IT-Alltag

8. November 2006 um 20:57

Indexes am SQL-Server-2005: nicht alles geht "online"

Durch die aktuelle Ausgabe des SQL-Server-Magazine wurde ich auf ein Problem aufmerksam: Wenn man LOBs (Large Objects) in einem Index speichert, dann kann man verschiedene Dinge nicht tun. Dazu reicht es schon, wenn das LOB-Feld nur auf der Index-Seite gespeichert ist, bspw. beim Clustered-Index.

online operations

Dazu steht in den "Guidelines for Performing Online Index Operations":

When you perform online index operations, the following guidelines apply:
Clustered indexes must be created, rebuilt, or dropped offline when the underlying table contains large object (LOB) data types: image, ntext, text, varchar(max), nvarchar(max), varbinary(max), and xml.

Kimberly L. Tripp beschreibt es in dem SQL-Server-Magazine-Artikel "Database Design for Performance" noch etwas genauer:

SQL Server 2005 allows any column to be in the leaf level of an index—including LOB types. If a LOB type is in the leaf level of an index, the index won't support online operations.

Das gilt also auch für Clustered-Indexes und betrifft im Wesentlichen "ALTER INDEX REBUILD". Wenn es rechtzeitig vorher weiß, dann sollte das kein Problem sein. Dann kann man nötigenfalls die Tabelle auf zwei aufteilen…

unerwartete Fehlermeldung

Meines Erachtens besteht aber auch ein Zusammenhang zu folgendem Phänomen: In bestimmten Fällen erscheint bei einem Update eine unerwartete Fehlermeldung:

The query processor could not produce a query plan from the optimizer because a query cannot update a text, ntext, or image column and a clustering key at the same time.

bzw.

Msg 8629, Level 16, State 3, Line 1 – Warnung: Der Abfrageprozessor konnte aus dem Optimierer keinen Abfrageplan erzeugen, da eine Abfrage nicht gleichzeitig eine text-, ntext- oder image-Spalte und einen Gruppierungsschlüssel aktualisieren kann.

Um bei einem UPDATE in das Problem zu laufen, müssen folgende Bedingungen erfüllt sein:

  • Die Tabelle hat einen Clustered Index.
  • Die Tabelle hat wenigstens ein Feld vom Typ IMAGE, NTEXT, TEXT, NVarchar(max), Varchar(max), Binary(max) oder XML.
  • Der Inhalt des Feldes wird nicht in dem Datensatz gespeichert.
  • Der Zugriffsplan ist so ausgelegt, dass mehrere Datensätze geändert werden (selbst wenn tatsächlich nur einer da ist).

-- ggf. Testtabelle löschen
if object_id('tempdb..#t1') is not null
drop table #t1
go
– Testtabelle anlegen
create table #t1 (
c1 int not null,
c2 int not null,
primary key clustered (c1,c2),
c3 text null,
c4 int identity)
go
– Tabelle mit Testdaten füllen
insert #t1 values (1,7,'test')
go
– Das geht problemlos:
update #t1 set c2=10, c3='test again' where c2=7
go
– Die Fehlermeldung verursachen:
update #t1 set c2=10, c3=replicate('x',8000)+replicate('y',8000) where c2=7

go
– ggf. Testtabelle löschen (aufräumen)
if object_id('tempdb..#t1') is not null
drop table #t1

Als Abhilfe kann ich zwei Möglichkeiten anbieten:

  1. Den Custered Index entfernen oder in einen "normalen" Index ändern.
  2. Das Statement wird in zwei Einzelteile zerlegt: einen auf die LOB-Spalten und einen auf die anderen.

7. November 2006 um 23:54

Microsoft SQL Server 2005 Compact Edition

Mein heutiges Aha-Erlebnis war eindeutig die "Microsoft SQL Server 2005 Compact Edition" (Version 3.1), die bei TheDailyGrind erwähnt wurde…

Die Lösung ist ganz einfach: der ehemalige Name war "SQL Server 2005 Everywhere Edition" (Version 3.1 Beta und CTP) und davor "SQL Server 2005 Mobile Edition" (Version 3.0) und davor "SQL Server CE" (Version 1.0 und 2.0).

SQL Server 2005 Compact Edition, was previously named SQL Server 2005 Everywhere Edition during the product development phase. Customers have communicated to Microsoft through the pre-release community technology preview (CTP) program and other channels that this product name may cause potential confusion with other database product names in the industry. Microsoft has taken this feedback seriously and has accordingly changed the official product name.

Da ich mal ein großer Fan des Sybase SQL Anywhere war, gebe ich das als Tipp ab für die Aussage "this product name may cause potential confusion with other database product names".

Hier geht es zum Download der Microsoft SQL Server 2005 Compact Edition (RC1).

Wer mal testweise damit rumspielen will, der sollte sich das Dokument "Prepare for SQL Server Everywhere Edition" ansehen. Wirklich gut.

7. November 2006 um 20:43

Backup-Song

Yesterday (nach der Melodie von den Beatles)

Yesterday,
All those backups seemed a waste of pay.
Now my database has gone away.
Oh I believe in yesterday.

Suddenly,
There's not half the files there used to be,
And there's a milestone hanging over me
The system crashed so suddenly.

I pushed something wrong
What it was I could not say.
Now all my data's gone
And I long for yesterday-ay-ay-ay.

Yesterday,
The need for backups seemed so far away.
I knew my data was all here to stay,
Now I believe in yesterday.

Diesen Song habe ich mal Anfang der 90er aus irgendeiner PC-Zeitschrift kopiert, habe leider vergessen aus welcher…

6. November 2006 um 21:30

übersichtlicher Feature-Vergleich der Editionen des SQL-Server-2005

Weil ich den Feature-Vergleich der Editionen des SQL-Server-2005 in letzter Zeit immer wieder benötige, poste ich den Link an dieser Stelle einfach mal. Vielleicht haben ja einige von Euch den Link bei Steffen seinerzeit verpasst:

Die Seite in den BOLs ist Features Supported by the Editions of SQL Server 2005
erheblich übersichtlicher als unter der Produkt-Übersicht (SQL Server 2005 Features Comparison).

6. November 2006 um 21:12

Umfrage zum Thema Datensicherung

Es gibt Neuigkeiten zu meinem heimlichen Lieblingsthema "Datensicherung": eine Umfrage von Kroll Ontrack unter 1400 Anwendern in den USA kommt zu frapierenden Ergebnissen…

Obwohl die Anwender ihren Daten einen hohen Wert zuschreiben, geht ein großer Teil recht sorglos mit seinen Daten um und unterschätzt das Risiko von Fehlfunktionen. Auf die Frage, wie lange sie ihren aktuellen Rechner nutzen wollen, gaben 58 Prozent der Befragten zum Beispiel an, "so lange, bis er kaputt geht" oder "bis er die ersten Ausfallserscheinungen zeigt". Diese Gleichgültigkeit belegen auch die Ergebnisse, dass 63 Prozent der Anwender ihre kritischen Daten weniger als einmal monatlich sichern und 23 Prozent keinerlei Backups vornehmen.

Natürlich ist es wichtig zu schauen, wer so eine Umfrage in Auftrag gegeben und formuliert hat. Ontrack verdient sein Geld mit Datenrettungsaktionen und möchte auf seine Dienste aufmerksam machen. Dennoch decken sich die Ergebnisse durchaus mit meinen Erfahrungen.

Und was kann man da machen? Meines Erachtens gar nichts. Man kann nur bei sich selber anfangen. Diejenigen, die sich nicht für Datensicherungen interessieren, lesen weder solche Studien noch meinen Blog…
Die IT-Fachleute müssen ihre Kunden natürlich anhalten Datensicherungen zu machen, aber da auch ihnen vorrangig kommerzielle Interessen unterstellt werden, reicht deren Einfluss leider nicht so weit, wie es nötig wäre. Hinzu kommt die Grundeinstellung, die auch im obigen Zitat rauskommt: "Solange alles gut läuft, muss ich mich doch um nichts kümmern."

gefunden bei TecChannel.de

29. Oktober 2006 um 17:05

Vorschläge zur Datensicherung mit SQL-Server – Teil 3: Online-Vollsicherung

Im ersten Teil der Serie “Vorschläge zur Datensicherung mit SQL-Server” habe ich ein paar Dinge zum Umfeld und zum Verständnis geschrieben. Im zweiten Teil beschrieb ich das Vorgehen beim Offline-Backup. In diesem Teil gehe ich auf die Online-Vollsicherung ein. Dabei wird im laufenden Betrieb der Inhalt der Datenbank mit Bordmitteln des SQL-Servers gesichert.

Ablauf

  • Datenbank-Prüfung
  • Datenbank-Sicherung
  • Archivierung der Sicherungsdateien

Datenbank-Prüfung

Wenn man die Datenbanken überprüft, dann muss man auch recht zeitnah (also am besten am nächsten Morgen) kontrollieren, ob die Prüfung Fehler entdeckte und ggf. die vorherige Sicherung besonders gut aufheben. Es wäre denkbar in dem SQL-Sicherungsskript pro Datenbank abzufragen, ob die Prüfung Fehler ergab und die Datenbank ggf. nicht zu sichern. Das erscheint mir aber unnötig mühsam. Außerdem sollte man sowieso mehrere Generationen an Sicherungen haben. Dann ist es durchaus sinnvoll auch eine defekte DB zu sichern solange die letzte korrekte Datenbanksicherung nicht überschrieben wird.

Deswegen will ich auch hier noch kurz auf das Generationenprinzip bei den wiederverwendtbaren Sicherungsmedien hinweisen: Bitte immer mehrere Sicherungsbänder verwenden und die Sicherungen von bestimmten Stichtagen generell aufheben. Beispielsweise könnte man 10 Generationen verwahren: Mo, Di, Mi, Do, Fr, Mo, Di, Mi, Do, Fr. Die Wochenendsicherungen werden dann dauerhaft archiviert: KW23, KW24, KW25, …
Dann kann man bei versehentlichem Löschen die Daten der letzten zwei Wochen tagesaktuell restaurieren und ältere Daten wochengenau.

Die Datenbank-Prüfung kann durchaus im laufenden Betrieb erfolgen. Allerdings wird die Performance dadurch deutlich gedückt. Man sollte sich dazu also keine Spitzenzeiten aussuchen. Außerdem kann es bei parallelem Arbeiten vorkommen, dass ein Allokierungsfehler gemeldet wird, der keiner ist: Wenn für eine Seite die Verkettungen geprüft werden und zufällig diese verkettete Seite gleichzeitig geändert wird (z.B. aufgesplittet), dann wird das als Fehler erkannt. In so einem Fall sollte man die Prüfung einfach nochmal durchführen und schauen, ob der gleiche Fehler erneut angezeigt wird.

Datenbank-Sicherung

Mit dem Backup-Befehl wird der Inhalt der Datenbank komplett gesichert. Dazu wird der Inhalt von benutzten Seiten in die Sicherungsdatei rausgeschrieben. Weil in einer Datenbank immer etliche Seiten leer sind, ist die Sicherungsdatei erheblich kleiner als die Datenbank-Dateien. Tipp: Wenn man sie dann noch zippt, erreicht man erstaunliche Kompressionsraten.
Diese Sicherung kann im laufenden Betrieb durchgeführt werden. Dabei wird genau der Stand gesichert, der zu dem Ende der Sicherung konsistent ist. Um das hinzubekommen, muss der SQL-Server etwas in die Trickkiste greifen: einige Sperren werden aufrechterhalten, andere Seiten werden im Tranlog gesichert. Um hier die Performance zu verbessern hat Microsoft im SQL-Server-2005 den neuen Snapshot-Modus verwendet. Damit ist die Performance deutlich besser. Hier wird dann allerdings der konsistente Zustand zum Beginn der Sicherung gespeichert.

In diesem Szenario wird eine Vollsicherung durchgeführt: Es werden alle Datenseiten gesichert. Das ist besonders einfach in der Rücksicherung, kann aber schon ein Weilchen dauern. Die Performance ist ganz gut: Meiner Erfahrung nach geht das fast so schnell, wie die Kopie der Dateien auf der Platte.

Tipp: Bitte ein Passwort für die Sicherungsdateien vergeben, sonst haben es Datendiebe unnötig leicht. Andererseits sollte das Passwort nicht nur einer kennen, der jeden Morgen mit überhöhter Geschwindigkeit (und womöglich noch mit dem Motorrad) zur Arbeit rast. 🙁

Archivierung der Sicherungsdateien

Anschließend müssen die Sicherungsdateien noch auf ein dauerhaftes Medium archiviert werden. Dabei muss unbedingt darauf geachtet werden, dass die Archivierung erst nach dem Ende der SQL-Server-Sicherung beginnt. Im Einzelfall ist das gar nicht so einfach. 100%ig kann man es nur dadurch erreichen, dass die SQL-Server-Sicherung als Batch in der Pre-Phase der Datensicherungssoftware läuft.
Für die Erstellung des Skriptes sind aber SQL-Kenntnisse erforderlich.

Vorteile

  • Diese Methode ist vergleichsweise schnell.
  • Die Rücksicherung ist auch für die meisten Laien noch machbar sofern sie eine sehr gute Anleitung bekommen.
  • Diese Methode ermöglicht einen 7x24-Stunden-Betrieb.

Risiken und Nebenwirkungen

  • Für diese Sicherungsmethode muss man gruendlegende Kenntnisse über Datenbanksystemen haben.
  • Man muss ein SQL-Server-Werkzeug verwenden oder SQL beherrschten und mit der "normalen" Sicherung koordinieren.
  • Die Dauer kann bei sehr großen Datenbanken recht lange werden. Mann muss also auf jeden FAll mal testen, wie lange das auf der eigenen Hardware dauert, bevor man sich dafür entscheidet.

Mein persönliches Resümee:

Ich finde diese Methode recht gut, aber würde die nur empfehlen, wenn jemand mit dem SQL-Server per "Du" ist oder man einen 24-Stunden-Betrieb benötigt. In diesem Fall sollte in dem Büro aber wenigstens ein Selfmade-Admin vorhanden sein, der bereit ist sich da reinzuarbeiten…

Im vierten Teil gehe ich auf die inkrementelle und die differentielle Online-Sicherung ein.

28. Oktober 2006 um 21:43

SQLIOSim: Ist die Hardware in Ordnung?

Leider habe ich es gerade eben erst entdeckt, aber die Freude ist u so größer.

DER Nachfolger für SQLIOStress ist da: SQLIOSim

typische Einsatzgebiete:

  • Jemand will im voraus wissen, ob mit seiner Hardware Probleme für den SQl-Server zu erwarten sind: defekte Datenbank aufgrund ungeeigneter Hardware.
  • Ein anderer möchte wissen, ob die neue systemnahe Software dem SQL-Server falsche oder defekte Seiten unterschiebt: bspw. Virenscanner, Verschlüsselungssoftware oder Backup-Software.
  • Ein anderer hat vielleicht schon eine defekte Datenbank und möchte die Gründe finden.

Das Werkzeug gibt es in einer GUI- und in einer CmdShell-Variante. Ich kann es fast nicht erwarten bis ich wieder ins Büro komme, um das auszuprobieren!

Hier etwas O-Ton von Jerome Halmans:

Wouldn’t you rather know there is a problem before you entrust your data to such a complex process?

SQLIOSim is designed to generate exactly the same type and patterns of IO requests at a disk subsystem as SQL Server would, and verify the written data exactly as SQL Server would.
[…]

Want to see how your system will behave when that scheduled a DBCC CHECKDB check runs? No problem, just add the AuditUser section to the config file.

Have bulk load jobs? Well just add the BulkUpdateUser section.

Quelle: SQL Server Storage Engine : SQLIOSim available for download

28. Oktober 2006 um 21:27

Unterschied zwischen VS Database Projects und Team System for Data Database Professionals

Mairead beschreibt in ihrem Blog knapp und prägnant die Unterschiede zwischen dem alten "Visual Studio Database Projects" und dem neuen "Visual Studio Team Editon for Database Professionals" (genannt "Data Dude"):

Im "Data Dude" wird der Datenbank-Erstellungs- und -Verwaltungsprozess viel stärker unterstützt. Hier können Entwickler und Admins im Team arbeiten.

Die Datenbank-Objekte können Offline erstellt, getestet (mit Testdaten und -fällen), archiviert und versioniert werden.

Der neue Entwurf kann mit einem anderen Stand der Datenbank verglichen werden. Als Output bekommt mal auslieferbare Skripte, die auf die Produktivsysteme losgelassen werden können, um sie auf den neuen Stand zu heben.

Das klingt so also sollten wir das so schnell wie möglich ausprobieren und dann großflächig einsetzen… 😉

Hier gibt mehr dazu: Difference between old VS Database Projects and Team System Data Database Project

14. Oktober 2006 um 20:08

SQL Server 2005: Definition von System-Objekten ansehen

Beim SQL Server 2005 kann bekanntlich die Systemtabellen nicht direkt Zugreifen und schon gar bearbeiten. Man sieht sie noch nicht mal. Die "echten" Systemtabellen stehen auch nicht mehr in der Master-Datenbank, sondern in der versteckten Datenbank MsSqlSystemResource. Man kann deren Dateien im Data-Verzeichnis sehen, das ist aber auch schon alles: mssqlsystemresource.mdf/ldf.

Stattdessen gibt es jede Menge Views, die man für den lesenden Zugriff nutzen kann:

  • Die guten alten "Systemtabellen" von früheren Versionen werden als Views abgebildet, z.B. sysobjects. Allerdings enthalten die Views keine Informationen über neue Features, einige Attribute, die nicht mehr zutreffende Infos enthalten würden enthalten immer NULL.
  • Die ANSI-Views gibt es weiterhin, z.B. INFORMATION_SCHEMA.TABLES. Hier hat sich meines Wissens nichts geändert.
  • Die neuen System Management Views, die die alten Systemtabellen ablösen sollen, z.B. sys.objects. Sie sind vergleichsweise sprechend und lehnen sich sehr stark an die alten Systemtabellen an. Sie gefallen mir ganz gut.
  • Die neuen Dynamic Management Views enthalten alle möglichen Laufzeitinformationen. So etwas gab es früher auch schon, z.B. die ehemaligen sysprocesses. Ein Beispiel für die Neuen ist sys.dm_exec_connections. Hier stehe ich noch am Anfang, aber das Konzept gefällt mir.

Bei meinem Bestreben die internen Abläufe des Systems zu verstehen waren mit beim SQL-Server immer die Quelltexte der Systemproceduren bzw. die View-Definitionen sehr hilfreich. Lange Zeit dachte ich, es gäbe keine Möglichkeit mir die Definitionen der Systemviews anzusehen. Aber im SQl-Server-Magazine las ich neulich, wie es geht: mit der Funktion "object_definition".

-- Definition von System-Objekten ansehen:
SELECT object_definition(object_id('dbo.sysobjects'))

Damit man im "SQL Server Management Studio" wirklich etwas sehen kann, sollte man die Ergebnisse als Text ansehen im Menü "Query | Results To | Results To Text" oder mit Strg+t und die maximal dargestellte Zeichenzahl pro Spalte auf 8192 setzen.
Dazu im Menü unter "Tools | Options" im Fenster "Options" links "Query Results | SQL Server | Results To Text" für den Wert "Maximum number of characters displayed in each column" den Wert "8192" wählen.

14. Oktober 2006 um 19:46

SQL Server 2005: Pivoting & Unpivoting

Dem Feature "Pivoting/Unpivoting" stehe ich etwas zwispältig gegenüber: Einerseits habe ich in der Vergangenheit schon mehrfach die Anfrage von Entwicklern bekommen, wie man sowas macht (meist noch in den späten 90ern als wir von Btrieve auf Sybase SQL-Anywhere umstellten). Andererseits sind die zugrundeliegenden Ursachen in der Regel eine "schlechte" Datenmodelierung: Wert-Tabellen, wie sie ein index-sequentiellen Systemen üblich waren. Ich bevorzuge echte relationale Datenmodelle.

In den letzten Jahren habe ich aber auch erlebt, dass es mindestens eine Situation gibt, bei der man um solche Tabellen nicht rumkommt: Wenn man mit relationalen Mitteln eine Art OLAP-System nachbilden will, dann ist es sinnvoll alle möglichen "Fakten" in der gleichen Tabelle unterzubringen und deren Werte im gleichen Feld zu speichern. Damit kann man dann sehr einfach, sehr flexible Auswertungsmöglichkeiten schaffen. Mein Kollege Michael brauchte ziemlich lange, um mich davon zu überzeugen… 😉

Pivoting
Die Werte aus einer Werte-Tabelle werden in eine echte Tabellen übertragen.
Dabei bekommen die einzelnen Attribute auch gleich sinnvolle Namen, z.B. wird "attr1" zu "Typ", "attr2" zu Datum" "attr3" zu "Anzahl" usw.

Der entsprechende PIVOT-Befehl geht so:

SELECT ObjectID, attr1 as Typ,
attr2 as Datum, attr3 as Anzahl,
attr4 as Dings, attr5 as Bums
FROM OpenSchema
PIVOT( Max("Value")
FOR Attribute IN ("attr1", "attr2", "attr3", "attr4", "attr5")
) AS pvt
ORDER BY ObjectID

Wenn man das Bedürfnis hat genau den umgekehrten Weg zu gehen: aus einer normalisierten Tabelle die Ergebnisse in Form einer Wert-Tabelle zu bekommen, dann geht das mit UNPIVOT:

SELECT ObjectID, Attribute, "Value"
FROM ( SELECT ObjectID, cast(Typ as sql_variant) as attr1, cast(Datum as sql_variant) as attr2, cast(Anzahl as sql_variant) as attr3, cast(Dings as sql_variant) as attr4, cast(Bums as sql_variant) as attr5
FROM FixSchema) as "Value"
UNPIVOT
(
"Value"
FOR Attribute IN ("attr1", "attr2", "attr3", "attr4", "attr5")
) AS pvt
ORDER BY ObjectID

Wer noch genug hat: Eine besonders gute Darstellung des Pivotierens liefert wieder mal Itzik Ben-Gan. Die Folien von seinem Vortrag "Advanced T-SQL Techniques" zur TechEd 2006 in Israel stehen bei microsoft.com (siehe "Advanced T-SQL Techniques"). Ich glaube, sie sind auch ohne seinen Text verständlich. Als ich ihn 2005 in London persönlich erleben durfte, zeigte er ganz ähnliche Folien. Deswegen bin ich da nicht repräsentativ.

13. Oktober 2006 um 21:23

Index-Covering und Included-Columns

Gestern gab mir ein Kollege die Ausgabe 9/2005 vom SQL Server Magazine (ich stehe auf dem Umlauf). Er hatte sie in seinem Schrank entdeckt. Seitdem wir eine Clean-Desk-Philosophie haben, müssen wir alles in den Schrank räumen, wo er sie vergessen hat…

Dennoch bin ich dafür dankbar, das er die Ausgabe weitergegeben hat, denn sie enthält mehrere für mich wichtige Artikel. Eine ganz interessante Sache hätte ich in der Feature-Flut des SQL-Servers-2005 sonst glatt übersehen: Included-Columns.

Wer schon mal erlebt hat, wie man eine Abfrage durch Index-Covering beschleunigen kann, der wird meine Begeisterung teilen. Index-Covering beschreibt den selten auftretenden Fakt, dass in der Abfrage sowohl im WHERE- als auch im SELECT-Teil (und überhaupt im gesamten SELECT-Statement) ausschließelich Attribute zugegriffen werden, die in einem (zusammengesetzten) Index verwendet werden. In diesem Fall muss der SQL-Server gar nicht erst die Datenseiten der Tabelle lesen, es reicht den Index auszuwerten. Damit kann locker die Performance verdoppelt werden, meist noch mehr.

Für Non-Clustered-Indexes können am SQL Server 2005 zusätzlich zu den Attributen, die Bestandteil des Index sind, weitere rein beschreibende Attribute beigegeben werden. Deren Werte werden dann nicht im Index-Baum/-Pfad gespeichert, sondern nur in der Leaf-Page. Sie werden bei Index-Covering aber gezielt verwendet.

Risiken und Nebenwirkungen:

  • Speicherplatz
  • Performance bei ändernden Operationen
  • positiv: Umgehung der "900-byte maximum key column size limitation"

Heute habe ich bei awprofessional.com auch noch einen Artikel zu dem Thema entdeckt: SQL Server 2005: Two Little Known Features That Matter Big! Including Non-Key Columns in Non-Clustered Indexes. Dort stehen auch ein paar sehr gute Beispiele, ebenso in den Books-Online weshalb ich sie mir an dieser Stelle spare.

13. Oktober 2006 um 21:13

Sammlung mit Beispielkapiteln zum SQL Server 2005

Bei yukonxml.com gibt es eine nette Sammlung mit Werbe-Kapiteln aus Büchern zum SQL Server 2005. Dabei findet sich etwas für jeden Geschmack.