WSUS Assistent für die Serverbereinigung bricht mit Datenbankfehler ab „Serverknoten zurücksetzen“

Problem

assistent-wsus-serverbereinigungDie Update-Bereinigung des 2008er WSUS Serverdienstes bricht nach langer Laufzeit ab. Der Assistent läuft bei hoher CPU-Auslastung sehr lange, tut aber augenscheinlich nichts. Es werden keine Updates entfernt und der Asistent bleubt nach einer Weile mit einem Timeout-Fehler stehen.

Fehlermeldung:

Beim ausführen eines Datenbankvorganges ist ein Fehler aufgetreten. Dies kann geschehen, wenn die Datenbank sehr ausgelastet, der Datenbankdienst beendet wurde oder die Verbindung mit der Datenbank getrennt wurde.

 

Lösung

Wenn die Windows-eigene SQL-Instanz (WSSEE) aus dem Lieferumfangt genutzt wird, muss hier erst der pipe-Zugriff erlaubt werden („piped pipes“). Per Default ist der Zugriff abgeschaltet.

  1. Den „SQL Server Configuration Manager“ (im Lieferumfang vom SQL Management Studio) installieren, starten
  2. Protokolle für „MICROSOFT##SSEE“ auswählen in den Eigenschaften das „Instanz verstecken“-Feld auf „nein“ stellen.
  3. Dienst neu Starten
  4. SQL Server Configuration Manager >  SQL Native Client Konfiguration > Aliase >  Rechtsklick auf den Alias „<servername>\Microsoft##SSEE“ > Eigenschaften
  5. Den Aliasnamen ändern, von „<servername>\Microsoft##SSEE“ zu „<servername>\##SSEE“

Dann kann man sich mit dem SQL Server Management Studio (oder einem anderen SQL-Client) zu der Instanz verbinden. Wer einen ausgewachsenen SQL-Server nutzt, kann dies selbstverständlich auch sofort tun.

  1. Mit dem SQL Management Studio zur entsprechenden SQL-Instanz verbinden
    1. Die SQL-Express Instanz aus dem WSSEE heisst „\\.\pipe\MSSQL$MICROSOFT##SSEE\sql\query“ (einfach in das ‚Servername‘ Feld eingeben). Unter Windows Server 2012: „\\.\pipe\MICROSOFT##WID\tsql\query“
    2. Für die WSSEE die „Named Pipes“ unter den Netzwerkprotokollen > Verbindungseinstellungen auswählen
  2. Diese Query ausführen:
    USE SUSDB;
    exec spGetObsoleteUpdatesToCleanup;
    
  3. Das Ergebnis ist in der Regel eine lange Liste von obsoleten Update-ID-Nummern. In den meisten Fällen „klemmt“ nur ein Update (i.d.R. die erste oder letzte ID in der Liste), nach dessen Entfernung der Assistent wieder problemlos funktioniert. Updates entfernen:
    exec spDeleteUpdate @localUpdateID=<ID-Nummer des Updates>

Update: Seit Windows Server 2012 sieht der Verbindungsalias etwas anders aus.

Microsoft SQL Server (MSSQL) model, tempdb, msdb und master Datenbank verschieben

Kann man die Systemdatenbanken (master, model, msdb, tempdb) im Dateisystem verschieben, zum Beispiel auf ein anderes Laufwerk ?Ja. Im laufenden Betrieb? Nein.

So verschiebt man die Systemdatenbanken MODEL, MASTER und MSDB

Wo befinden sich die Datenbankdateien im Moment?

sql-systemdatenbanken-verschieben

SELECT name, physical_name FROM sys.master_files WHERE database_id = DB_ID(N’model’);
  1. Neuen physikalischen Pfad für model, msdb und tempdb festlegen:
    USE master;
    -- model Datenbank verschieben
    ALTER DATABASE model MODIFY FILE (NAME = modeldev, FILENAME = "E:\SQL-DB\model.mdf");
    ALTER DATABASE model MODIFY FILE (NAME = modellog, FILENAME = "E:\SQL-DB\modellog.ldf");
    -- msdb Datenbank verschieben
    ALTER DATABASE msdb MODIFY FILE (NAME = MSDBData, FILENAME = "E:\SQL-DB\MSDBData.mdf");
    ALTER DATABASE msdb MODIFY FILE (NAME = MSDBLog, FILENAME =  "E:\SQL-DB\MSDBLog.ldf");
    -- tempdb Datenbank verschieben
    ALTER DATABASE TempDB MODIFY FILE (NAME = Tempdev, FILENAME = "E:\SQL-DB\tempdb.mdf");
    ALTER DATABASE TempDB MODIFY FILE (NAME = Templog, FILENAME = "E:\SQL-DB\templog.ldf");
    
  2. SQL Server Dienst beenden
  3. Dateien im Dateisystem verschieben
  4. SQL Server Dienst starten

So verschiebt man die Systemdatenbank MASTER

  1. SQL Konfigurationsmanager öffnen
  2. Links in der Baumansicht auf „SQL Server Dienste“
  3. Rechts die Eigenschaften von „SQL Server (INSTANZNAME)“ öffnen
  4. Auf dem Tab „Startparameter“ die Pfade auf die neuen Zielpfade ändern
    1. ACHTUNG, BUG in SQL 2012/2014: Der „Aktualisieren“ Knopf lässt keine Pfade zu, die ein Minuszeichen enthalten („Ungültiger Parameter“).
    2. Wenn der Pfad ein Minuszeichen enthält, muss man den Pfad in der Registry direkt bearbeiten:
      HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQLServer\Parameters
  5. SQL-Server Dienst beenden
  6. Dateien im Dateisystem verschieben
  7. SQL-Server Dienst startensql-masterdatenbank-verschieben

Microsoft SQL Server alle Datenbanken (Datenbankdateien) verkleinern

Problem

Einige Datenbanken (=Datenbankdateien) in einem SQL-Server sind extrem gewachsen und belegen nach Leerung nun immernoch viel physikalischen Speicher. Man kann natürlich jede Datenbank im Management Studio einzeln anklicken und unter „Tasks“ auf „Verkleinern“ klicken oder ein DBCC-Kommando in jeder Datenbanka ausführen, bei vielen Datenbänken in einer Instanz dauert das aber extrem lange.

Lösung

EXEC sp_MSForEachDB 'DBCC SHRINKDATABASE (''?'' , 0)'

Achtung! Es ist fast nie sinnvoll, Datenbankdateien einfach-mal-so zu verkleinern. Indizes und die Datenbank selber werden dann bei Aktivität in der Regel stark fragmentiert, was wahnsinnig auf die Performance durchschlägt. Für eine Virtualisierung, verschieben, eine Sicherungskalkulation oder bei Vorgängen die geplant viele Daten entsorgen, kann das aber auch durchaus hilfreich sein. Im Zweifel vorher einen (fähigen) DBA fragen.

SQL Server Management Studio „.NET Framework Error“ (Unable to read the list of previously registered servers on this system)

Problem

Das SQL Management Studio (alle Versionen ab 2008) startet nicht nur noch mit einer Fehlermeldung:

Microsoft.SqlServer.Management.RegisteredServers.RegisteredServerException: Unable to read the list of previously registered servers on this system.
Re-register your servers in the 'Registered Servers' window.
Microsoft.SqlServer.Management.Sdk.Sfc.SfcSerializationException:
Deserialization operation on /RegisteredServersStore/ServerGroup/CentralManagementServerGroup has failed.

Wenn das SQL Server Management Studio dann aber gestartet ist, kann man sich zwar verbinden, sieht aber keine Inhalte. Stattdessen erscheint der Fehler

Value cannot be null.

Oder auf Deutschen Systemen:

Wert darf nicht null sein.

Lösung

Das Temp-Verzeichnis der %TEMP% Variable ist nicht gesetzt, der Paf existiert nicht oder ist nicht beschreibbar. Auf dem System auf dem ich mich grade herumtreibe konnte ich den Fehler daher schnell beheben:

mkdir %TEMP%

SQL Server 2008/2012/2014 „Es kann nicht festgestellt werden, ob der Besitzer () von Auftrag für Serverzugriff hat.

Problem

Ein oder mehrere Wartungspläne schlagen fehl und erzeugen unangenehme Fehler im Ablaufplanb, die diesen oder einen ähnlichen Wortlauf haben. Die Sicherungen werden aber korrekt erstellt.

Ereignistyp:       Warnung
 Ereignisquelle:    SQLSERVERAGENT
 Ereigniskategorie: Job Engine
 Ereigniskennung:   208
 Benutzer:          Nicht zutreffend
 Computer:          STACKEXCH1
 Beschreibung:
 SQL Server Scheduled Job ‘<foo>’ (0xLONGID) – Status: Fehler – Invoked on: <date> – Message: Auftragsfehler  Es kann nicht bestimmt werden, ob der Besitzer (‘<foo>\<bar>’) von Auftrag ‘<name>’ Serverzugriff aufweist. (Ursache: Die Informationen über Windows NT-Gruppe oder -Benutzer ‘<foo>\<bar>’ konnten nicht abgerufen werden, Fehlercode 0x5. [SQLSTATE 42000] (Fehler 15404)  Die Anweisung wurde beendet. [SQLSTATE 01000] (Fehler 3621)).

Lösung

Der Benutzer kann tatsächlich nicht aufgelört werden. Das kann am Design der AD-Infrastrutur liegen, wenn die Windows-Authentifizierung benutzt wird. Wir haben gute Erfahrungen gemacht, die Wartungspläne jeweils im lokalen SQL-Server kontext mit der SQL-Authentifizierung laufen zu lassen (z.B. ’sa‘).

Das geht in den Eigenschaften des betroffenen Wartungsplanes (oder Subplanes) in dem Feld „Besitzer“. In TSQL sieht das für den ’sa‘ dann so aus:

UPDATE msdb.dbo.sysssispackages 
SET [ownersid] = SUSER_SID('sa') 
WHERE [name] = 'Meinwartungsplan.Subplan'  

Alternativ ändert man im Management Studio, wärend man als das passende Zielkonto angemeldet ist, einfach den Namen. der aktuelle User wird dann als neue Besitzer übernommen. Einen via GUI erreichbaren Weg kennen wir spontan nicht.