Drücke "Enter", um den Text zu überspringen.

Kategorie: SQL Server

Slides meiner Sessions der sqlDays 2021 in Erding

In den letzten beiden Tagen war ich als Speaker auf den sqlDays in Erding. Die Sessions hatten die Titel

„Whats new with Databases on Azure?“ und

„Hochverfügbarkeit für Azure SQL Server VMs“

Die Slides dazu findet ihr jetzt auf meinem GitHub Repo:

slides/sqlDays2021 at master · HaikoHertes/slides (github.com)

Sobald die Aufzeichnungen verfügbar sind, verlinke ich diese dann hier.

Schreibe einen Kommentar...

Azure / PowerShell – Azure SQL Performance Empfehlungen per PowerShell abholen und verteilen

Azure und insbesondere Azure SQL ist klasse – es nimmt einem viele Dinge der täglichen Verwaltung ab, einiges davon sogar automatisch. Klar, das hat seinen Preis, immerhin ist Azure SQL nicht ganz billig, aber wenn man es schon bezahlt, dann kann man auch seine Fähigkeiten nutzen. Eine davon ist, automatisch anhand der Nutzung einer Datenbank Empfehlungen für die Leistungsoptimierung zu geben. Diese kann man sich im UI bzw. dem Azure Portal anschauen. Dazu öffnet man entweder links im Blade den Punkt „Recommondations“ unterhalb von „Intelligent Performance“ oder den Punkt „Performance“ auf der Main-Page bei den Notifications:

Dort sieht man dann einige Empfehlungen aufgeführt (vorausgesetzt, Azure hat etwas gefunden, was wiederum eine regelmäßige Nutzung der Datenbank voraussetzt):

Diese Daten kann man sich auch automatisch abrufen und auf Wunsch dann z.B. an die Entwickler verteilen. Dazu bediene ich mich einfach der PowerShell:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
$ErrorActionPreference = "Stop"
$SubscriptionId = "YOUR_SUBSCRIPTION_ID"
 
function Get-SQLServerRecommendations()
{
    # Define the resource types
    $resourceTypes = ("Microsoft.Sql/servers/databases")
    $advisors = ("CreateIndex", "DropIndex","DbParameterization","SchemaIssue");
    $results = @()
 
    # Loop through all subscriptions
 
    $rgs = Get-AzureRmResourceGroup
 
    # Loop through all resource groups
    foreach($rg in $rgs) {
        $rgname = $rg.ResourceGroupName;
 
        # Loop through all resource types
        foreach($resourceType in $resourceTypes) {
            $resources = Get-AzureRmResource -ResourceGroupName $rgname -ResourceType $resourceType
 
            # Loop through all databases
            # Extract resource groups, servers and databases
            foreach ($resource in $resources) {
                $resourceId = $resource.ResourceId
                if ($resourceId -match ".*RESOURCEGROUPS/(?<content>.*)/PROVIDERS.*") {
                    $ResourceGroupName = $matches['content']
                } else {
                    continue
                }
                if ($resourceId -match ".*SERVERS/(?<content>.*)/DATABASES.*") {
                    $ServerName = $matches['content']
                } else {
                    continue
                }
                if ($resourceId -match ".*/DATABASES/(?<content>.*)") {
                    $DatabaseName = $matches['content']
                } else {
                    continue
                }
 
                # Skip if master
                if ($DatabaseName -eq "master") {
                    continue
                }
 
                # Loop through all Automatic tuning recommendation types
                foreach ($advisor in ($advisors -notmatch "SchemaIssue")) {
                    $recs = Get-AzureRmSqlDatabaseRecommendedAction -ResourceGroupName $ResourceGroupName -ServerName $ServerName  -DatabaseName $DatabaseName -AdvisorName $advisor
                    foreach ($r in $recs) {
                        if ($r.State.CurrentValue -eq "Active") {
                            $object = New-Object -TypeName PSObject
                            $object | Add-Member -Name 'SubscriptionId' -MemberType Noteproperty -Value $subscriptionId
                            $object | Add-Member -Name 'ResourceGroupName' -MemberType Noteproperty -Value $r.ResourceGroupName
                            $object | Add-Member -Name 'ServerName' -MemberType Noteproperty -Value $r.ServerName
                            $object | Add-Member -Name 'DatabaseName' -MemberType Noteproperty -Value $r.DatabaseName
                            $object | Add-Member -Name 'Advisor' -MemberType Noteproperty -Value $advisor
                            $object | Add-Member -Name 'Script' -MemberType Noteproperty -Value $r.ImplementationDetails.Script
                            $results += $object
                        }
                    }
                }
            }
        }
    }
    Return $results
}
 
$AzurePasswordSecure = ConvertTo-SecureString "$($YOUR_AZURE_PASSWORD)" -AsPlainText -Force
$AzureCredentials = New-Object System.Management.Automation.PSCredential ("$YOUR_AZURE_USER", $AzurePasswordSecure)
Connect-AzureRmAccount -Credential $AzureCredentials | Out-Null
Select-AzureRmSubscription -Subscription $SubscriptionId | Out-Null
 
$Recommendations = Get-SQLServerRecommendations
$table = $Recommendations | Sort-Object DatabaseName,Advisor | Format-Table Databasename,Advisor,Script -AutoSize -Wrap
Write-Output $table
 
$head = "<style>
td {background-color:lightgrey;}
table {width:100%;}
th {font-size:14pt;background-color:lightblue;}
</style>
<title>SQL Server performance recommendations</title>"
 
[string]$html = $Recommendations | ConvertTo-Html -Property Databasename,Advisor,Script -Body "<h1>Azure SQL Server automatic tuning recommendations for $stage</h1>Auto-generated by PUT_SOMETHING_HERE<br><br>" -Head $head
 
Send-MailMessage -Body $html -SmtpServer YOUR.SMTPSERVER.COM -From sender@domain.com -To recipient@domain.com -Subject "MS SQL Recommendations - $(Get-Date -Format "yyyy-dd-MM HH:mm:ss")" -BodyAsHtml

Dieses Script wiederum kann man dann z.B. per Jenkins regelmäßig auslösen. Oder alternativ ein Azure Automation Runbook dafür anlegen… Viel Spaß beim Ausprobieren!

Die Mails sehen dann in etwa so aus:

Schreibe einen Kommentar...

SCOM: Probleme beim Setup von SCOM 2012 R2 – hier: Reporting Server

Die Installation von SCOM (System Center Operations Manager) 2012 R2 ist eigentlich nicht sehr schwer – jedoch gibt es einige potentielle “Stolpersteine”, wenn man die Reporting-Komponente nutzen möchte. Selbst bei installiertem SSRS (SQL Server Reporting Service) können diverse Fehler auftreten, die ich hier mit samt ihrer Lösung vorstellen möchte.

Zunächst einmal kann folgende Fehlermeldung auftauchen, die verschiedene Gründe haben könnte:

scom2012ssrs1

Mögliche Fehler:

  • SSRS sind nicht installiert (trivial)
  • Reporting Services Webdienst-URL ist nicht konfiguriert (Durchaus denkbar, direkt nach dem Setup)
  • Keine SSRS-Datenbank angelegt (kann nach dem Setup auch gut möglich sein)
  • Keine Berichts-Manager-URL konfiguriert (vor allem wenn noch keine Webdienst-URL gesetzt wurde normal)

Ob einer der Fehler vorliegt lässt sich recht einfach mit Hilfe des “Konfigurations-Manager für Reporting Services” prüfen:

Hier ist beispielsweise keine Webdienst-URL gesetzt (zweiter Fall):

scom2012ssrs2

Das Ganze sollte so aussehen (wenn dies erst gerade geschehen ist, sollte die rot markierte Meldung zu sehen sein):

scom2012ssrs3

Dritter Fall: Keine Datenbank. Das sieht dann so aus:

scom2012ssrs4

Durch einen Klick auf “Datenbank ändern” kann man mit Hilfe von “Neue Berichtsserver-Datenbank erstellen” und der Standardwerte eine neue DB samt TempDB anlegen. Das sollte am Ende so aussehen:

scom2012ssrs6

Vierter Fall: Berichts-Manager-URL ist noch nicht konfiguriert; sieht so aus:

scom2012ssrs7

Durch “Anwenden” lässt sich dies korrigieren und sieht danach so aus:

scom2012ssrs8

Zurück im Setup das SCOM2012R2 kann man nun erneut sein Glück versuchen, jedoch könnte nun folgender Fehler auftauchen, dessen Meldung man nur sieht, wenn man mit dem Mauszeiger über das rote Kreuz fährt:

scom2012ssrs9

Die Meldung ist zum Glück sehr aussagekräftig, so dass ein Blick in services.msc (Dienste) recht schnell Klarheit bringt:

scom2012ssrs10

Der SQL Agent Dienst sollte auf Autostart stehen und muss zum Zeitpunkt der Installation laufen, also so:

scom2012ssrs11

Das sind nun also die häufigsten Fehler und ihre eigentlich recht einfache Lösung; ich hoffe, das Ganze ist für die Problemlösung hilfreich.

Schreibe einen Kommentar...

SCCM2012: Durch SEDO dauerhaft gesperrte Tasksequenzen entsperren

SEDO (Serialized Editing of Distributed Objects) soll im SCCM2012-Umfeld möglich machen, dass mehrere Admins gleichzeitig arbeiten, ohne sich gegenseitig in die Quere zu kommen. Wenn unter SCCM2007 ein Admin eine Tasksequenz bearbeitet hat, die noch bei einem anderen Admin zur Bearbeitung geöffnet war, dann „gewann“ derjenige, der zuletzt gespeichert hat, was mitunter sehr ärgerlich war.

Unter SCCM 2012 werden nun Tasksequenzen, die zum Bearbeiten geöffnet sind, gesperrt. Diese an sich sehr nützlich Funktion kann aber auch zu einem Problem werden. Die Sperre sollte nach 30 Minuten „Inaktivität“ automatisch aufgehoben werden. Da dies aber ein Vorgang ist, den die SCCM-Konsole durchführt, kann es passieren, das eine gesperrte Tasksequenz dauerhaft gesperrt bleibt, wenn z.B. die Konsole abgestürzt ist.

Für die Sperrung ist die SQL-Tabelle SEDO_LockState zuständig.

Gesperrte Tasksequenzen kann man z.B. mit folgendem SQL-Statement abfragen:

1
SELECT * FROM SEDO_LockState WHERE LockStateID != 0

TS_Screen2

Das eine Tasksequenz gesperrt ist, wird auch beim Versuch, diese zu bearbeiten angezeigt:

TS_Error

Um nun eine Entsperrung zu erzwingen, ist folgendes SQL-Statement geeignet:

1
2
3
4
5
6
7
8
9
UPDATE [CM_LPZ].[dbo].[SEDO_LockState]
SET [LockStateID] = 0
,[AssignedUser] = NULL
,[AssignedObjectLockContext] = NULL
,[AssignedMachine] = NULL
,[AssignmentTime] = NULL
 
WHERE [LockStateID] = '1'
GO

(das „LPZ“ in „CM_LPZ“ ist durch den Sitecode zu ersetzen)

Aber Achtung: Microsoft unterstützt das manuelle Ändern der SQL-Datenbank nicht – ihr solltet also genau wissen, was ihr da tut!

TS_Lösung

2 Comments

Speicherhunger der WSUS-Datenbank (WID) begrenzen

Insbesondere in kleinen und mittleren Unternehmen läuft der Windows Server Update Service (WSUS) nicht auf einem vollwertigen SQL-Server, sondern auf einer Windows Internal Database, welche bereits Bestandteil des Windows Server 2008 (R2) ist, und somit direkt bei der Installation von WSUS mitinstalliert werden kann.

Das Problem: Wenn es um Arbeitsspeicher geht, verhält sich die WID wie ein „großer“ SQL-Server – sie nimmt was sie bekommen kann.

Dieses Verhalten lässt sich beim regulären SQL-Server u.a. mit dem SQL Server Management Studio beeinflussen. Dieses Programm ist allerdings nicht Bestandteil der WID-Installation.

Die Lösung: Das frei erhältliche SQL Management Studio Express bietet genau diese Möglichkeiten.

Vorgehensweise:

1. SQL Management Studio Express downoaden

http://www.microsoft.com/de-de/download/details.aspx?id=8961

2. SQL Management Studio Express installieren

Ist nicht weiter schwer, einfach den Setup-Assistenten benutzen…

3. Verbindung zur WID aufbauen

Dazu muss das Management Studio u.U. als Administrator ausgeführt werden. Als Verbindungsziel wird

\\.\pipe\mssql$microsoft##ssee\sql\query

verwendet.

4a. Konfiguration mittels T-SQL

Nun müssen folgende beiden T-SQL Abfragen ausgeführt werden:

sp_configure ’show advanced options‘, 1;
reconfigure;
go

„Ausführen“ anklicken

sp_configure ‚max server memory‘, 256;
reconfigure;
go

(Den Wert 256 durch das gewünschte Maximum ersetzen )

„Ausführen“ anklicken

4b. Konfiguration mittels GUI

Rechtsklick auf den obersten Eintrag im Objekt-Explorer, im Kontextmenü „Eigenschaften“ auswählen

Im neu geöffneten Fenster den Bereich „Arbeitsspeicher“ wählen und dort den minimalen und den maximalen Speicherwert eintragen.

Das war es schon gewesen. Evtl. muss die Datenbank neu gestartet werden…

7 Comments

SQL-Server auf System Center Configuration Manager 2012 (SCCM) Server startet nach SYSPREP nicht mehr

Auf einem Test-Server für eine System Center Configuration Manager 2012 Umgebung lief auch der dazu notwendige SQL-Server. Da die Hardware einen Defekt aufwies, musste ich das System auf eine neue Hardware umziehen. Problematisch: Alte und neue Hardware waren derart verschieden, dass hier Probleme zu erwarten gewesen wären, wenn ich die Platten einfach nur umgesteckt hätte. Also habe ich vorher einen Sysprep inkl. /generalize laufen lassen. Nach dem Umbau der Festplatten in den neuen Server startete dieser Anstandslos. Das Problem: Die SQL-Server-Dienste starteten nicht!

Problem:

Durch den SYSPREP sind die privaten Schlüssel für die SSL-Kommunikation verloren gegangen, da der alte User-Account ja danach nicht mehr vorhanden war. Dies war u.a. im Logfile „C:\Program Files\Microsoft SQL Server\MSSQL10_50.MSSQLSERVER\MSSQL\Log\ERRORLOG“ nachzulesen:

"The server could not load the certificate it needs to initiate an SSL connection. It returned the following error: 0x8009030d [...]"

Lösung:

Im „SQL Server Configuration Manager“ die Zuordnung zum alten Zertifikat löschen:

 

 

 

 

 

 

 

 

Nach einem Reboot des Servers generiert dieser ein neues Zertifikat und trägt dieses hier entsprechend ein (Es existieren dann 2 Zertifikate mit gleichem Namen, man kann sie aber u.a. am Ausstellungsdatum unterscheiden).

Dieses neue Zertifikat muss nun noch zu den „Vertrauenswürdigen Stammzertifizierungsstellen“ hinzugefügt werden bzw. evtl. den Clients als vertrauenswürdig bekanntgegeben werden. Danach sollte alles wieder funktionieren, im Logfile steht dann:

"A self-generaterd certificate was successfully loaded for encryption. [...]"
Schreibe einen Kommentar...