
Immer wieder kommt das Szenario auf, dass eine oder mehrere Benutzerdatenbanken von einem auf den anderen Server migriert werden sollen. Dieser Prozess birgt die ein oder andere Falle, in die unerfahrene Datenbankentwickler:innen tappen können. Wir möchten Ihnen mit diesem Artikel eine Art Checkliste an die Hand geben, in der die wichtigsten Schritte, Maßnahmen und Eigenschaften festgehalten sind. Denn wie Sie vermutlich wissen, können kleinste Fehler schwerwiegende Leistungseinbrüche nach sich ziehen und Ausfallzeiten verursachen. Folgen Sie unseren Schritten und halten sich an die Checkliste, können Sie zumindest das Gröbste vermeiden.
Was ist vor der Migration zu beachten?
- Analysieren Sie den verfügbaren Speicherplatz des Zielservers, auf den die neue Datenbank migriert werden soll. Reicht der Speicherplatz nicht aus, müssen Sie entsprechend weiteren Speicherplatz hinzufügen.
- Wählen Sie den Speicherort der Daten und der Protokolldatei auf dem Zielserver.
- Analysieren und sammeln Sie Infos zu den Datenbankeigenschaften. Dazu zählen z.B. Eigenschaften wie Auto Stats, DB Owner, Recovery Model, Compatibility Level, Trustworthy Option…
- Berücksichtigen Sie Informationen zu abhängigen Anwendungen. Sie sollten dafür sorgen, dass entsprechende Anwendungen im worst case auch gestoppt werden können.
- Stellen Sie Informationen zu Datenbankanmeldungen, Usern und deren Berechtigungen zusammen.
- Überprüfen Sie die Datenbank auf Karteileichen und verwaiste Nutzer.
- Überprüfen Sie den SQL Server auf abhängige Objekte, wie SQL Agent Jobs oder Verbindungsserver.
- Checken Sie, ob die Datenbank Teil eines Wartungsplans ist.
Folgend stellen wir Ihnen die Skripts zusammen, die Sie zum Überprüfen der obenstehenden Fakten verwenden können:
Überprüfen der Festplatten- & Datenbankgröße
exec master..xp_fixeddrives
-- To Check database size
exec sp_helpdb [dbName]
--or
use [dbName]
select str(sum(convert(dec(17,2),size)) / 128,10,2) + 'MB'
from dbo.sysfiles
GO
Überprüfen der Datenbankeigenschaften
Use [dbName]
select
sysDB.database_id,
sysDB.Name AS "Database Name",
syslogin.Name AS "DB Owner",
sysDB.state_desc,
sysDB.recovery_model_desc,
sysDB.collation_name,
sysDB.user_access_desc,
sysDB.compatibility_level,
sysDB.is_read_only,
sysDB.is_auto_close_on ,
sysDB.is_auto_shrink_on,
sysDB.is_auto_create_stats_on,
sysDB.is_auto_update_stats_on,
sysDB.is_fulltext_enabled,
sysDB.is_trustworthy_on
from sys.databases sysDB
INNER JOIN sys.syslogins syslogin ON sysDB.owner_sid = syslogin.sid
oder alternativ:
declare @dbdesc varchar(max)
declare @name varchar(10)
set @name='Master'
SELECT @dbdesc = 'Status=' + convert(sysname,DatabasePropertyEx(@name,'Status'))
SELECT @dbdesc = @dbdesc + ', Updateability=' + convert(sysname,DatabasePropertyEx(@name,'Updateability'))
SELECT @dbdesc = @dbdesc + ', UserAccess=' + convert(sysname,DatabasePropertyEx(@name,'UserAccess'))
SELECT @dbdesc = @dbdesc + ', Recovery=' + convert(sysname,DatabasePropertyEx(@name,'Recovery'))
SELECT @dbdesc = @dbdesc + ', Version=' + convert(sysname,DatabasePropertyEx(@name,'Version'))
-- These props only available if db not shutdown
IF DatabaseProperty(@name, 'IsShutdown') = 0
BEGIN
SELECT @dbdesc = @dbdesc + ', Collation=' + convert(sysname,DatabasePropertyEx(@name,'Collation'))
SELECT @dbdesc = @dbdesc + ', SQLSortOrder=' + convert(sysname,DatabasePropertyEx(@name,'SQLSortOrder'))
END
-- These are the boolean properties
IF DatabasePropertyEx(@name,'IsAutoClose') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsAutoClose'
IF DatabasePropertyEx(@name,'IsAutoShrink') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsAutoShrink'
IF DatabasePropertyEx(@name,'IsInStandby') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsInStandby'
IF DatabasePropertyEx(@name,'IsTornPageDetectionEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsTornPageDetectionEnabled'
IF DatabasePropertyEx(@name,'IsAnsiNullDefault') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsAnsiNullDefault'
IF DatabasePropertyEx(@name,'IsAnsiNullsEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsAnsiNullsEnabled'
IF DatabasePropertyEx(@name,'IsAnsiPaddingEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsAnsiPaddingEnabled'
IF DatabasePropertyEx(@name,'IsAnsiWarningsEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsAnsiWarningsEnabled'
IF DatabasePropertyEx(@name,'IsArithmeticAbortEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsArithmeticAbortEnabled'
IF DatabasePropertyEx(@name,'IsAutoCreateStatistics') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsAutoCreateStatistics'
IF DatabasePropertyEx(@name,'IsAutoUpdateStatistics') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsAutoUpdateStatistics'
IF DatabasePropertyEx(@name,'IsCloseCursorsOnCommitEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsCloseCursorsOnCommitEnabled'
IF DatabasePropertyEx(@name,'IsFullTextEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsFullTextEnabled'
IF DatabasePropertyEx(@name,'IsLocalCursorsDefault') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsLocalCursorsDefault'
IF DatabasePropertyEx(@name,'IsNullConcat') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsNullConcat'
IF DatabasePropertyEx(@name,'IsNumericRoundAbortEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsNumericRoundAbortEnabled'
IF DatabasePropertyEx(@name,'IsQuotedIdentifiersEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsQuotedIdentifiersEnabled'
IF DatabasePropertyEx(@name,'IsRecursiveTriggersEnabled') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsRecursiveTriggersEnabled'
IF DatabasePropertyEx(@name,'IsMergePublished') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsMergePublished'
IF DatabasePropertyEx(@name,'IsPublished') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsPublished'
IF DatabasePropertyEx(@name,'IsSubscribed') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsSubscribed'
IF DatabasePropertyEx(@name,'IsSyncWithBackup') = 1
SELECT @dbdesc = @dbdesc + ', ' + 'IsSyncWithBackup'
SELECT @dbdesc
Suche nach verwaisten Benutzern:
sp_change_users_login 'report'
GO
Suche nach Verbindungsservern:
select *
from sys.sysservers
Auflistung der datenbankabhängigen Jobs:
USE [msdb]
select
distinct
name,
database_name
from sysjobs sj
INNER JOIN sysjobsteps sjt on sj.job_id = sjt.job_id
Durchführung der Datenbankmigration
- Stoppen Sie laufende Anwendungsdienste
- Änderung der Datenbank in einen schreibgeschützten Modus mit folgendem Skript:
USE [master]
GO
ALTER DATABASE [DBName] SET READ_ONLY WITH NO_WAIT
GO
ALTER DATABASE [DBName] SET READ_ONLY
GO
- Erstellen Sie eine Sicherung aller an der Migration beteiligten Datenbanken
- Stellen Sie die besagten Datenbanken auf dem Zielserver in den entsprechenden Laufwerken wieder her
- Vergleichen Sie die Datenbankeigenschaften mit den Ergebnissen der zuvor ausgeführten Skripte und passen sie, falls notwendig, die Eigenschaften an.
Ändern des Datenbankbesitzers
Durch folgendes Skript ändern sie den Datenbank-Eigentümer in sa. Mit dem Skript können Sie auch andere User zum Eigentümer ernennen.
USE [DBName]
EXEC sp_changedbowner 'sa'
Aktivieren der vertrauenswürdigen Option
Mit der Datenbankeigenschaft TRUSTWORTHY
wird angegeben, ob die SQL Server-Instanz die Datenbank und ihre Inhalte als vertrauenswürdig einstuft. War diese Option zuvor gesetzt, können Sie sie mit diesem Statement wieder aktivieren.
ALTER DATABASE DBName SET TRUSTWORTHY ON
Ändern des Kompatibilitätsgrads
Dies ist vor allem notwendig bei einem Upgrade auf eine neuere Version. Es wird standardmäßig der vorhandene Kompatibilitätsgrad übernommen.
ALTER DATABASE DBName
SET SINGLE_USER
GO
EXEC sp_dbcmptlevel DBName, 150;
GO
ALTER DATABASE DBName
SET MULTI_USER
GO
Verwaiste User identifizieren
Führen Sie folgende Skripts auf dem Zielserver aus um nach verwaisten Benutzern zu suchen und dieses Problem auch direkt zu beheben.
EXEC sp_change_users_login 'Report'
--Use below code to fix the Orphan User issue
DECLARE @username varchar(25)
DECLARE fixusers CURSOR
FOR
SELECT UserName = name FROM sysusers
WHERE issqluser = 1 and (sid is not null and sid <> 0x0)
and suser_sname(sid) is null
ORDER BY name
OPEN fixusers
FETCH NEXT FROM fixusers
INTO @username
WHILE @@FETCH_STATUS = 0
BEGIN
EXEC sp_change_users_login 'update_one', @username, @username
FETCH NEXT FROM fixusers
INTO @username
END
CLOSE fixusers
DEALLOCATE fixusers
DBCC CHECKDB bei SQL Server Versionsupdate
Wenn Sie auf eine neuere SQL Server Version wechseln, führen Sie danach DBCC UPDATEUSAGE
für die wiederhergestellte Datenbank aus. Nutzen Sie dafür den folgenden Code:
DBCC UPDATEUSAGE('database_name') WITH COUNT_ROWS
DBCC CHECKDB
ODER
DBCC CHECKDB('database_name') WITH ALL_ERRORMSGS
Index-Neuaufbau oder Reorganisation
Je nach Bedarf wird ein Neuaufbau oder reine Reorganisation vorhandener Indizes benötigt. Der Neuaufbau löscht den vorhandenen Index und erstellt einen neuen.
GO
ALTER INDEX ALL ON [ObjectName] REBUILD
GO
Die Reorganisation organisiert den Blattknoten des Index physikalisch.
USE AdventureWorks;
GO
ALTER INDEX ALL ON [Objektname] REORGANIZE
GO
Aktualisieren Sie im Nachgang ihre Indexstatistik mit folgendem Code:
sp_updatestats
Prozeduren kompilieren
Kompilieren Sie die gespeicherten Prozeduren neu.
sp_recompile 'procedureName'
Applikationsdienste & Windows Event Log
Testen Sie im Nachgang die Anwendungsfunktionalität durch einen Neustart der Anwendungsdienste. Checken Sie unbedingt die Windows-Ereignisprotokolle auf Auffälligkeiten.
Fehlerprotokoll überprüfen
Überprüfen Sie das SQL Server Fehlerprotokoll auf Auffälligkeiten und Fehler jeglicher Art wie z.B. Login-Fehler.
EXEC xp_readerrorlog 0,1,"Error",Null
Quellsystem offline nehmen
Laufen alle Anwendungen einwandfrei und so, wie Sie es sich vorgestellt haben, können Sie die Datenbanken auf dem Quellserver offline schalten. Alternativ können Sie die Datenbanken auch einfach schreibgeschützt machen.
USE [master]
GO
ALTER DATABASE [DBName] SET READ_ONLY WITH NO_WAIT
GO
ALTER DATABASE [DBName] SET READ_ONLY
GO
oder alternativ:
EXEC sp_dboption N'DBName', N'offline', N'true'
OR
ALTER DATABASE [DBName] SET OFFLINE WITH
ROLLBACK IMMEDIATE
Nächste Schritte
Mit den obigen Checklisten für die Vorbereitung und Durchführung der Migration, sollten Sie auf die allermeisten Fallen vorbereitet sein. Weiterhin sollten Sie den Prozess testen und im Auge behalten. Es gibt vielerlei Optimierungen, die Sie individuell vornehmen können und sollten. Dazu gehört beispielsweise die Überwachung wie viel Zeit und Speicherplatz benötigt werden. Hierbei ist ein Sicherungs- & Wiederherstellungsprozess hilfreich. Auch ist es hilfreich, einen Rollback-Plan zu erstellen, sollte die Anwendung nicht Ihren Anforderungen nach optimal laufen. Fügen Sie der Checkliste weitere Migrationsfälle und Auffälligkeiten hinzu, die Ihnen auffallen und in Zukunft helfen können.
Gerne helfen wir Ihnen bei Ihrer Datenbankmigration weiter. Als zertifizierte Experten auf diesem Gebiet können wir Ihnen individuelle Pläne und Skripte zusammenstellen, die Ihnen die Migration deutlich erleichtern werden. Kontaktieren Sie uns gerne für ein unverbindliches Beratungsgespräch und lassen Sie uns gemeinsam Ihren Bedarf ermitteln. Über unser Kontaktformular erreichen Sie uns am Besten!