Wer hat die Datenbank geflutet?
Ein inzwischen gewohntes Bild bei vCenter Installationen auf Windows Basis mit der integrierten SQL Express Datenbank: der vCenter Dienst ist angehalten. Nach manuellem Start läuft dieser einige Sekunden und stoppt dann wieder. Ein Blick in die Ereignisprotokolle liefert Event ID 1105 und 1827.
Event 1105:
Could not allocate space for object ‘dbo.VPX_HIST_STAT1_222’.’PK_VPX_HIST_STAT1_222′ in database ‘VIM_VCDB’ 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.
Event 1827:
CREATE DATABASE or ALTER DATABASE failed because the resulting cumulative database size would exceed your licensed limit of 10240 MB per database.
Die Meldung erklärt den Grund der Störung. Das Größenlimit der Datenbank wurde erreicht. Im beschriebenen Fall wurde die Datenbank zuvor bereits von einer SQL-Express 2005 (max. 4GB) auf eine SQL-Express 2008 R2 (max. 10GB) migriert. Dennoch wurde das Limit erreicht.
Der Cluster aus 4 Hosts sollte damit zurecht kommen und die Haltezeiten der Ereignisse wurden bereits auf 21 Tage limitiert. Welche Tabellen sind also für den Anstieg des Datenaufkommens verantwortlich? Unter SQL Server Express 2008 R2 haben wir hier mehrere Möglichkeiten zur Analyse.
Report Tools
Einen sehr schnellen und komfortablen Überblick liefern die eingebauten Report Tools. Dazu verbindet man das Mangement Studio Express mit der Datenbank Instanz auf vCenter und markiert die vCenter Datenbank (VIM_VCDB). Über das Kontextmenü [Reports > Standard Reports > Disk Usage by Top Tables] erhält man einen Bericht der größten Tabellen.
T-SQL Skript
Ältere Versionen von SQL-Express verfügen unter Umständen nicht über die Report Funktionen. Hierfür muss man sich mit einem Skript behelfen, das z.B. bei Stackoverflow publiziert wurde.
SELECT t.NAME AS TableName, i.name as indexName, sum(p.rows) as RowCounts, sum(a.total_pages) as TotalPages, sum(a.used_pages) as UsedPages, sum(a.data_pages) as DataPages, (sum(a.total_pages) * 8) / 1024 as TotalSpaceMB, (sum(a.used_pages) * 8) / 1024 as UsedSpaceMB, (sum(a.data_pages) * 8) / 1024 as DataSpaceMB FROM sys.tables t INNER JOIN sys.indexes i ON t.OBJECT_ID = i.object_id INNER JOIN sys.partitions p ON i.object_id = p.OBJECT_ID AND i.index_id = p.index_id INNER JOIN sys.allocation_units a ON p.partition_id = a.container_id WHERE t.NAME NOT LIKE 'dt%' AND i.OBJECT_ID > 255 AND i.index_id <= 1 GROUP BY t.NAME, i.object_id, i.index_id, i.name ORDER BY SUM(a.total_pages) DESC
Das Resultat sieht ungefähr so aus:
Die Verursacher der vollen Datenbank sind schnell ausgemacht. Es handelt sich um Tabellen mit alten Leistungsdaten, die sich in vier Gruppen aufteilen:
- VPX_HIST_STAT1_n (Tag)
- VPX_HIST_STAT2_n (Woche)
- VPX_HIST_STAT3_n (Monat)
- VPX_HIST_STAT4_n (Jahr)
Im beschriebenen Fall sind die Leistungsdaten der Serie 2 (Wochenstatistiken) die Hauptursache.
Ablauf
- vCenter Server stoppen (falls es noch läuft)
- Im Management Studio die Tabellen VPX_HIST_STAT2_1 bis VPX_HIST_STAT2_n mit dem Befehl TRUNCATE TABLE leeren. Das kann unter Umständen mühsam sein, da man über 80 Tabellen zu leeren hat. Besser ist daher die Verwendung eines Skriptes.
- Korrespondierende Sample Time Tabelle leeren: TRUNCATE TABLE VPX_SAMPLE_TIME2
Truncate Script
Eleganter geht es mit einem Skript welches bei StopDoingITWrong publiziert wurde. Dieses löscht die gesamte Statistik Historie und auch die korrespondierenden Sampletime Tabellen.
Achtung! Benutzung auf eigenes Risiko. Vorher unbedingt einen Snapshot oder einen Datenbank Dump anlegen!
Declare @current_table varchar(100) declare @sqlstatement nvarchar(4000) --move declare cursor into sql to be executed set @sqlstatement = 'Declare table_cursor CURSOR FOR SELECT name FROM sys.tables where name like ''VPX_HI%'' or name like ''VPX_SAMPLE%''' exec sp_executesql @sqlstatement OPEN table_cursor FETCH NEXT FROM table_cursor INTO @current_table WHILE @@FETCH_STATUS = 0 BEGIN set @sqlstatement = 'truncate table ' + @current_table exec sp_executesql @sqlstatement FETCH NEXT FROM table_cursor INTO @current_table END CLOSE table_cursor DEALLOCATE table_cursor
Anschliessend die Datenbank verkleinern (Shrink). Dazu die Datenbank im Management Studio auswählen und im Kontextmenü [Tasks > Shrink > Database>] wählen.
Ergebnis nach Truncate und Shrink
Ein Blick auf die Datenbank Dateien zeigt das Ergebnis.
Start vCenter Service
Letztlich sollte man nicht vergessen, den vCenter Dienst neu zu starten. Die Anmeldung mit vSphere Client oder Webclient sollte danach wieder problemlos funktionieren.
Links
- Stackoverflow – How to find largest objects in a SQL Server database?
- VMware KB 1007453 – Reducing the size of the vCenter Server database…
- VMware KB 2038474 – Troubleshooting VPX_HIST_STAT table sizes…
- StopDoingITWrong – VMware vCenter Server 5.1 Database is Full