Glorf.it

Glorf IT

Bedenkliches aus dem IT-Alltag

2. Juli 2008 um 00:10

SQL-Server: Liste der internen Systemtabellen

Mit der Version 2005 hat Microsoft ja bekanntlich die Systemtabellen im SQL-Server umgebaut und versteckt. Man kommt nun eigentlich gar nicht mehr dran.

Aber wenn man beim SQL-Server-2005 die Liste der internen Systemtabellen sehen will, dann geht das immerhin ganz einfach:

SELECT O.object_id
, SCHEMA_NAME(O.schema_id)
+'.'+[name] AS "internal system table"
FROM sys.objects AS O
WHERE O.type=N'S'
ORDER BY O.object_id;

Und so sieht das Ergebnis aus:

object_id internal system table
4 sys.sysrowsetcolumns
5 sys.sysrowsets
7 sys.sysallocunits
8 sys.sysfiles1
13 sys.syshobtcolumns
15 sys.syshobts
25 sys.sysftinds
26 sys.sysserefs
27 sys.sysowners
28 sys.sysdbreg
29 sys.sysprivs
34 sys.sysschobjs
39 sys.syslogshippers
41 sys.syscolpars
42 sys.sysxlgns
43 sys.sysxsrvs
44 sys.sysnsobjs
45 sys.sysusermsgs
46 sys.syscerts
47 sys.sysrmtlgns
48 sys.syslnklgns
49 sys.sysxprops
50 sys.sysscalartypes
51 sys.systypedsubobjs
54 sys.sysidxstats
55 sys.sysiscols
56 sys.sysendpts
57 sys.syswebmethods
58 sys.sysbinobjs
60 sys.sysobjvalues
64 sys.sysclsobjs
65 sys.sysrowsetrefs
67 sys.sysremsvcbinds
68 sys.sysxmitqueue
69 sys.sysrts
71 sys.sysconvgroup
72 sys.sysdesend
73 sys.sysdercv
74 sys.syssingleobjrefs
75 sys.sysmultiobjrefs
76 sys.sysdbfiles
78 sys.sysguidrefs
80 sys.syschildinsts
90 sys.sysqnames
91 sys.sysxmlcomponent
92 sys.sysxmlfacet
93 sys.sysxmlplacement
94 sys.sysobjkeycrypts
95 sys.sysasymkeys
96 sys.syssqlguides
97 sys.sysbinsubobjs

Und was man damit machen kann, beschrieb ich neulich ja schon… 😉

1. Juli 2008 um 18:56

SQL-Server mag keine VIA- and Transmeta-CPUs

Microsoft gibt zu, dass der SQL-Server Probleme mit "VIA Eden CPUs and Transmeta CPUs" hat:

The computer on which you try to install SQL Server Express or SQL Server Express with Advanced Services is equipped with a CPU that does not support cache prefetching.

The affected CPUs include VIA Eden CPUs and Transmeta CPUs. Typically, these CPUs are used in devices when low power consumption, low heat, or low noise is important.

Aber wie mir mein Kollege Robert sagte, trifft das wohl auch auf modernen VIA-CPUs zu. Die CPU muss schon Cache-Prefetching unterstützen, damit man dort eine SQL-Server-Express-Edition einsetzen kann. Das ist ziemlich schade, weil ja gerade wieder die ganz kleinen Laptops auf dem Vormarsch sind. Mein Kollege erzählte mir das bestimmt schon vor einem Jahr. Aber erst jetzt, nachdem im Fahrwasser des Eee-PC mehrere Hersteller Mini-Laptops mit solchen CPUs raus bringen, wird es wieder für uns relevant. Ein Beispiel ist HPs 2133, dass sich mit seiner vergleichsweise guten Ausstattung offenbar gerade an Geschäftskunden wendet. Die deutschen One-Mini-Laptops haben auch eine VIA-CPU und werden – wenn ich es richtig in Erinnerung habe – in der aktuellen c't beschrieben.
VIA selber bietet ja sogar ein Referenzdesign an, mit dem Laptophersteller recht einfach solche Mini-Laptops entwerfen können.

Damit eignet sich diese Art der Mini-Laptops möglicherweise nicht für (professionelle) Anwendungen, die den SQL-Server als Datenhaltung einsetzen. Das wäre echt schade. Hat jemand schon Erfahrungen mit so einem Netbook und dem SQL-Server gesammelt?

29. Juni 2008 um 13:09

SQL-Server: Auf interne System-Tabellen direkt zugreifen

Neulich beschrieb ich, wie wir ein Problem in den seit SQL-Server-2005 versteckten Systemtabellen mittels dem Hex-Editor lösten. Mittlerweile las ich bei Paul Randal, wie man die Systemtabellen nicht nur mittels SELECT lesen, sondern auch ändern kann – echt krass.

Ursprünglich wurde das übrigens von Laurentiu Cristofor beschrieben. Ich nehme an, Paul muss jetzt – da er nicht mehr bei MS arbeitet – aufpassen, dass er nur Dinge ausplaudert, die schon irgendwo veröffentlicht wurden, sonst würde er nicht bei jedem Kikifitz eine öffentliche Quelle angeben… 😉

  1. Den SQL-Server im Single-User-Modus starten (-m).
    Meiner Ansicht nach am einfachsten mit dem "SQL Server Configuration Manager" (aus "Start | Alle Programme | Microsoft SQL Server 2005 | Configuration Tools"): SQL-Server-Dienst doppelklicken, "Eigenschaften", dritten Reiter ("Advanced") auswählen, in der Liste "Startup Parameters" doppelklicken und da am Ende ";-m" ergänzen. Jetzt den Dienst neu starten.
  2. Mittels Dedicated-Admin-Connection (DAC) zum SQL-Server verbinden ("-A" beim sqlcmd.exe).

Und schon kann man die internen versteckten Systemtabellen zugreifen und ändern… 😀
Danach muss man nur noch den Single-User-Modus für den SQL-Server wieder rausnehmen und den Dienst neu starten. Ist das gut?

Risiken und Nebenwirkungen

Microsoft hatte übrigens gute Gründe den Zugriff auf diese Tabellen zu verhindern. Wer also nicht genau weiß was er tut, der sollte es lassen. Man kann eine Datenbank damit sehr gründlich zerstören. 🙁

28. Juni 2008 um 12:41

SQL-Server-2005: interne Tabellen einzeln prüfen und reparieren

In den letzten Tagen untersuchten wir eine defekte Datenbank eines Kunden. DBCC CHECKDB bracht nur die vielsagende Meldung, dass eine der internen Verwaltungstabellen defekt sei und man deswegen eine Sicherung einspielen solle. Nun hatte der Kunde aber keine aktuelle Sicherung (die letzte war von April). Wir konnten dem SQL Server nicht auf dokumentierte Weise entlocken wo er Defekt nun war.

Mit einer gezielten Prüfung auf die versteckten Systemtabellen fanden wird schnell den Bösewicht. Wer sich auch mal mit dem Thema befassen will, findet im Folgenden eine Liste der internen Tabellen (mit DBCC CHECKTABLE), die Schritte die zur Reparatur führten und die Ursachenanalyse. Warnung: Nur wen das interessiert, sollte ab hier weiter lesen… 😉

DBCC CHECKTABLE('sys.sysallocunits') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysasymkeys') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysbinobjs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysbinsubobjs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.syscerts') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysclsobjs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.syscolpars') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysconvgroup') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysdbfiles') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysdercv') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysdesend') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysfiles1') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysftinds') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysguidrefs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.syshobtcolumns') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.syshobts') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysidxstats') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysiscols') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysmultiobjrefs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysnsobjs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysobjkeycrypts') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysobjvalues') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysowners') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysprivs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysqnames') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysremsvcbinds') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysrowsetcolumns') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysrowsetrefs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysrowsets') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysrts') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysscalartypes') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysschobjs') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysxmitqueue') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysxmlcomponent') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysxmlfacet') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysxmlplacement') WITH NO_INFOMSGS;
DBCC CHECKTABLE('sys.sysxprops') WITH NO_INFOMSGS;

Die Prüfung sagte uns nicht nur, welche Tabelle defekt war (sys.sysallocunits), sondern auch auf welcher Seite in welchem Slot (=Datensatz) das Problem sei. Mit DBCC PAGE oder dem SQL Server Internals Viewer konnten wir leicht sehen, dass ein Wert in dieser Slot völlig untypisch war. Tatsächlich war ein Bitkipper passiert, wir mussten uns nun lediglich den Offset des gekippten Bytes innerhalb der Seite merken und damit dann das Problem komplett beheben:

Mit einem Hex-Editor gingen wir an die Adresse des bösen Bytes (Formel = Seite*8192+Offset in der Seite) und korrigierten den Wert. Danach war die Datenbank wieder völlig in Ordnung. Nun hatten wir natürlich Glück, dass wir anhand eines Vergleichs des bösen Datensatzes mit Korrekten das Problem mit bloßem Auge erkennen konnten. Aber gerade deswegen hat mich das in Hochstimmung versetzt… 😀

Risiken und Nebenwirkungen
Ein Hinweis noch: Am SQL-Server-2005 muss man erst noch die Seiten-Checksummen ausschalten, sonst meckert der SQL-Server, wenn die DB nach der Änderung wieder angehängt wird.
ALTER DATABASE
SET PAGE_VERIFY NONE

Nach dem Eingriff kann man die Checksumme wieder einschalten:
ALTER DATABASE
SET PAGE_VERIFY CHECKSUM

Außerdem sollte man vor solchen Aktionen immer eine Kopie der Dateien machen. Wenn man das falsche Byte erwischt, dann ist die Datenbank erst recht defekt… 😉

Ursachenforschung

Die Checksummenprüfung des SQL-Server (seit 2005) erkennt, wenn Bitkipper aufgrund von Problemen im Speichersystem auftreten, nicht aber im Hauptspeicher auftretende Probleme. Das geht so: Der SQL-Server ändert die Datenseiten im Hauptspeicher ständig, deswegen wird da nicht jedesmal eine Checksumme berechnet, das würde einfach zu lange dauern.

Wird die geänderte Seite auf die Platte geschrieben, dann wird eine Checksumme berechnet und auf der betreffenden Seite mit gespeichert. Beim Lesen wird die Checksumme ebenfalls berechnet und auf Abweichungen kontrolliert. Bei Abweichungen muss ein Problem im Speichersystem aufgetreten sein (Treiber, defektes RAM im IO-Caching oder Festplattenproblem). Das war hier nicht der Fall.

Will man so eine Prüfung auch schon am SQL-Server-2000, dann muss man einen Hotfix einspielen und Trace-Flag 806 setzen.

So ein Bitkipper, wie oben beschrieben, muss daher im Hauptspeicher passiert sein. Deswegen wurde der Kunde darauf hingewiesen, dass sein RAM einen Schlag hat. Es wäre natürlich auch denkbar, dass der SQL-Server-Prozess selber dort Murks hingeschrieben hätte (das nennt man "Scribbler", z.B. die im Prozessraum laufenden Extended-Procedures), aber das ist in unserer Komstellation nicht wahrscheinlich.

Wenn man es ganeu wisse wollte, dann könnte man den SQL-Server eine Zeit lang mit dem Trace-Flag 806 laufen lassen. Damit wird auch im Hauptspeicher die Checksumme gelegentlich überprüft. Weil das aber die Performance ungeheuer beeinträchtigt, sollte man das nur für kurze Zeit machen…

Weiterführende Infos:

27. Juni 2008 um 21:35

SQL Server Internals Viewer

Durch den SQL-Server-Magazine-Artikel "SQL Server Internals Viewer " von Kevin Kline "entdeckte" ich für mich das Tool. Mit diesem Werkzeug kann man sich den Inhalt von Datenbanken seitenweise ansehen. Das klingt trocken, ist aber einfach genial.

Alleine durch das Ansehen habe ich mehr verstanden als durch die Lektüre von guten Büchern, die ich irgendwann abbrach, weil es einfach zu trocken wurde… Natürlich könne man sich das auch alles mit DBCC PAGE ansehen, aber das ist dann doch noch mal eine Spur härter.

Es ist einfach unglaublich, was man auf den Seiten alles erkennen kann. So habe ich heute beispielsweise mal geschaut, ob ich einer beliebigen vom Kunden geschickten MDF ansehen kann aus wie vielen Dateien die DB bestehen sollte und wo sie zuletzt lagen. Das geht und ist gar nicht so schwer. Ich konnte auch die komplette Liste der internen Systemtabellen sehen und studieren. Einfach genial!

Ideal ist es auch zur Analyse von Datenbank-Korruptionen, aber dazu schreibe ich demnächst noch mehr. Auf der Homepage steht ein kurzer, gelungener Überblick, deswegen schenke ich mir den an dieser Stelle… 😉

Hier geht es zum Download. Interessant ich auch noch der noch junge, aber schon lesenswerte Blog des Autors Danny Gould.

21. Juni 2008 um 16:06

Paul Randal antwortet

Bei Microsoft beantwortet Paul Randal im Artikel "SQL – Fragen und Antworten: E/A-Fehler, Datenbankspiegelung und mehr" drei Fragen zu sehr speziellen SQL-Server-Themen. Mich interessierten besonders seine Ausführungen dazu wie man an defekte Testdatenbanken ran kommt, damit man mal die Datenbankprüfung testen kann. Sehr lesenswert.

Er bietet übrigens auch defekte Datenbanken (mit ausführlicher Erklärung) zum Download an.

20. Juni 2008 um 16:59

Danke für die Unterstützung

Neulich beschrieb ich einen Bug im SQL-Server und bat um Unterstützung. Nachdem der deutsche MS-Support mich abgewimmelt hatte, gelang es Itzik Ben-Gan den Bug von MS anerkennen zu lassen und man konnte auf MS-Connect "gegen" den Bug stimmen. Das haben insgesamt 19 Leute gemacht, die Bewertung ist sehr, sehr hoch. Dafür bedanke ich mich ganz herzlich. Ich bin sicher, dass sowohl der Name des Einreichers (Itzik Ben-Gan) als auch diese ungewöhnlich zahlreiche Bewertung eine Rolle bei der Bearbeitung seitens MS spielten…

Das Problem rutschte in der MS-Hierarchie inzwischen bis zur endgültigen Station: Vom Microsoft-Mitarbeiter Jim wurde der Bug bewertet, kommentiert und an zur Bearbeitung an das "Query Optimizer Development Team" weitergeleitet. Das ist sehr erfreulich. 😀

Ich finde auch die Argumentation von Jim interessant. Sie ist hier nachzulesen: Er zieht eine Parallele zum Verhalten von Compilern. Wenn klar ist, in welcher Form und in welcher Version das behoben wird, melde ich mich dazu wieder.

20. Juni 2008 um 16:43

Die Datenbank ist voll – uh uh uh

Als ich noch ziemlich klein war, da sang Helga Feddersen das Lied "Die Wanne ist voll". Keine Ahnung warum ich da jetzt dran denken muss. Aber als ich gerade eine Seite des SQL-Server-Magazines aufrufen wollte, da bekam ich folgende Meldung:

Error Executing Database Query.
[Macromedia][SQLServer JDBC Driver][SQLServer]Could not allocate space for object 'dbo.ArticleViewCount'.'PK_articleViewCountArchive' in database 'NT_ContentDB' because the 'PRIMARY' filegroup is full. Create disk space by deleting unneeded files, dropping objects in the filegroup, adding additional files to the filegroup, or setting autogrowth on for existing files in the filegroup.

Solche Meldungen sind nicht nur mega-peinlich für die Betreiber der Seiten, sondern auch sehr informativ. Hier kann man eine ganze Menge über das CMS erfahren, dass hier betrieben wird (ich meine, außer das "Macromedia" verwendet wird). Ob denen das recht ist?

Offensichtlich ist in der Datenbank 'NT_ContentDB' – in der deren "Content" verwaltet wird – kein Platz mehr, um etwas einen Datensatz in der Tabelle "ArticleViewCount" reinzuschreiben. Genauer gesagt soll in einen vermutlich gruppierten Index, der zugleich Primärschlüssel ist, etwas eingefügt werden, aber das ist bei gruppierten Indexes ja die Tabelle. Da in die betreffende Tabelle offenbar bei jedem Datenzugriff etwas geschrieben wird, ist hier ein echter Hotspot. Weil diese Tabelle in der primären Datei, also der "*.MDF", liegt, wurde das nicht unbedingt für den "Hochleistungsbetrieb" ausgelegt. Insbesondere wurden die Daten nicht auf mehrere Dateien aufgeteilt, was den Datenzugriff parallelisieren könnte und damit den Durchsatz erhöhen würde. 😮

Diese Meldung kommt beim SQL-Server übrigens nicht besonders häufig:

  • Entweder wurde für die betreffende Datenbankdatei eine feste Größe eingestellt, dann ist darin einfach der Platz voll. In diesen Fällen sollte der Admin regelmäßig den freien Platz überprüfen – am besten automatisiert.
  • Oder die Datenbank-Datei wächst automatisch. Das ist der Normalfall. Davon gehe ich daher auch hier aus. Dann ist einfach die Partition voll. Und sowas sollte einem Admin auch nicht so durchgehen… 😉

Wie schön, dass anderen auch peinliche Pannen passieren… 😀

12. Juni 2008 um 21:10

Wen interessiert der SQL-Server-2008?

Das fragte ich mich heute und fand über Google-Trends heraus, dass immer noch erheblich mehr Leute bei Google Infos zum SQL-Server-2000 abrufen als zum SQL-Server-2008. Das sollte Microsoft zu denken geben…

9. Juni 2008 um 20:43

Nürnberg: Aktuelle Infos zum SQL-Server-2008

Morgen am 10.6.2008 gibt es in Nürnberg aktuelle Infos zum SQL-Server-2008. Auf dem Vortrag, der von der SQL-Pass Franken veranstaltet wird, der örtlichen SQL-Server-Anwendergruppe, wird Steffen Krause aus seinem breiten Portfolio plaudern.

Wie immer ist der Eintritt kostenlos und hat auch sonst keine unangenehmen Nebenwirkungen. Ich bin schon sehr gespannt und kann diese Abende nur wärmstens empfehlen!

Weitere Infos gibt es hier.

8. Juni 2008 um 22:12

SQL-Server: Datenbank-Snapshots leicht gemacht

Kaum rückt der Freigabetemin des SQL-Server-2008 näher, habe ich auch schon langsam alle neuen Features des SQL-Servers-2005 angeschaut…

In dem Zusammenhang möchte ich auf ein Add-In für das SQL-Server-Management-Studio hinweisen mit dem man einfach per Kontextmenü Datenbank-Snapshots erstellen kann: SQL Management Studio Snapshot Add-In

4. Juni 2008 um 22:17

TSQL: Wo bin ich, auf 64- oder 32-Bit?

Wir haben das Problem, dass unsere SQL-Prozeduren auf ganz unterschiedlichen SQL-Servern laufen müssen. Und je nach Edition oder Windows-Version leicht anders reagieren soll. Um herauszufinden, ob das Skript auf einem 64-Bit- oder einem 32-Bit-SQL-Server läuft, kann man so vorgehen:

-- Laufe ich auf einem 64-Bit- oder 32-Bit-SQL-Server?
SELECT CASE WHEN @@version LIKE N'%(X64)%'
THEN '64-Bit'
ELSE '32-Bit'
END AS "SQL Server"

Ist es ein 32-Bit-SQL-Server, dann ist noch spannend, ob der unter 64-Bit (im Windows-on-Windows, WoW) oder unter 32-Bit-Windows ausgeführt wird. Wie das geht verriet mit mein Kollege Vladimir:

-- Laufe ich unter 64-Bit-Windows odr unter 32-Bit?
DECLARE @output TABLE (txt NVARCHAR(1000) NULL);

EXEC sp_configure 'show ad', 1;
RECONFIGURE WITH OVERRIDE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE WITH OVERRIDE;

INSERT INTO @output (txt)
EXEC xp_cmdshell 'systeminfo /FO LIST';

SELECT CASE WHEN EXISTS(SELECT *
FROM @output
WHERE txt LIKE 'Systemtyp: % X86-based PC'
OR txt LIKE 'System type: % X86-based PC')
THEN '32-Bit'
ELSE '64-Bit'
END AS "Windows"

EXEC sp_configure 'xp_cmdshell', 0;
RECONFIGURE WITH OVERRIDE;
EXEC sp_configure 'show ad', 0;
RECONFIGURE WITH OVERRIDE;

Auf die Aussagen aus xp_msvers kann man sich nicht verlassen, weil der 32-Bit-SQL-Server immer denkt er liefe unter Windows-32 (auch wenn er in Wirklichkeit im WoW eines Win64 läuft)…
Kennt jemand einen besseren Trick?