SQL Server databases – informatie over de restore van een backup

Regelmatig krijg ik de vraag: “Weet jij wanneer de backup van [deze] en [deze] database is gemaakt en wanneer die is teruggezet?”. Het antwoord is ‘ja’… en met deze bijdrage weet u het nu ook. Draai op de SQL Server waar de teruggezette database staat onderstaande query:

SELECT 
   [rs].[destination_database_name], 
   [rs].[restore_date], 
   [bs].[backup_start_date], 
   [bs].[backup_finish_date], 
   [bs].[database_name] as [source_database_name], 
   [bmf].[physical_device_name] as [backup_file_used_for_restore]
FROM msdb..restorehistory rs
INNER JOIN msdb..backupset bs ON [rs].[backup_set_id] = [bs].[backup_set_id]
INNER JOIN msdb..backupmediafamily bmf ON [bs].[media_set_id] = [bmf].[media_set_id] 
ORDER BY [rs].[restore_date] DESC

Zo wordt de gevraagde informatie gevonden.

Met dank aan Thomas LaRock die deze informatie in het Engels in deze bijdrage heeft gedeeld.

Opstarten SQL Server onder ‘Local Service’ account; niet doen!

Bij de installatie van SQL Server wordt de SQL Service onder een zogenaamd local service account gestart. Heel af en toe valt het mij op dat het service account waaronder onderdelen van SQL Server worden gestart, niet naar een domein account wordt gewijzigd. Het is verstandig om de onderdelen van SQL Server onder aparte (!) domein accounts te laten starten; dus een apart domein account voor de database engine, een apart domein account voor de analysis server, één voor de SQL Agent, etc.

Waarom zo moeilijk als het ook makkelijk kan?
Het gebruik van een domein account zorgt ervoor dat op de onderdelen van SQL Server eenvoudiger wijzigingen kunnen worden gemaakt. Afgelopen week kwam ik tegen dat SSAS kubussolutions niet naar een analysis server konden worden uitgerold, omdat er geen gebruik van een domein account werd gemaakt. Bij gebruik van het ‘local service account’ weet het systeem niet of er voldoende rechten zijn bij o.a. het uitrollen van de kubussolutions vanaf een andere machine.

Ok… maar aparte domein accounts voor elk onderdeel van SQL Server?
Hoeft niet, maar het maakt de rechtenstructuur wél duidelijker. Een voorbeeld: om kubussen bij te werken onder het service account waaronder de analysis server wordt gestart, dient dat service account wél leesrechten te hebben op de brondatabase van de database engine; óók wanneer de database engine onder hetzelfde domein account wordt gestart. Het is dan overzichtelijker en duidelijker om de analysis server met een eigen service account te starten.

Kan het nóg scherper / beter?
Ja, door gebruik te maken van “(group) managed service accounts”. Het is wat meer werk, maar heeft als voordeel dat deze accounts uitsluitend kunnen worden gebruikt door de machines die hier rechten voor hebben gekregen. Daarnaast heeft dit account geen wachtwoord, waardoor het account ook niet voor andere doeleinden kan worden gebruikt / misbruikt. Met dank aan mijn collega voor deze mooie aanvulling.

Dus gebruik domein (group) managed service accounts bij het starten van onderdelen van SQL Server in een netwerk met Active Directory als basis.

** SQL Server database compatibility level? Wat is dat? **

Regelmatig komen we databases tegen die op de laatste versie van Microsoft SQL Server draaien en toch niet van de laatste technieken en inzichten gebruik kunnen maken. Met de verhuizing van een SQL Server database naar een nieuwe machine met de laatste SQL Server versie is het nog niet klaar! Dat geldt ook wanneer de SQL Server wordt bijgewerkt met de laatste versie van SQL Server. De betrokken database(s) moet(en) nog worden bijgewerkt!

Microsoft die zorgt ervoor dat een nieuwere versie van SQL Server niet direct impact heeft op de databases die op de SQL Server draaien. Elke database heeft op database niveau in het tabblad ‘Options’ de instelling ‘Compatibility Level’. Deze instelling zorgt ervoor dat de database zich gedraagt zoals die op de ‘oude’ versie van SQL Server is aangemaakt. Dit voorkomt dat de database opeens onder andere performance issues geeft of query plannen maakt, waar de database helemaal niet geschikt voor is.

Wanneer wordt de instelling “Compatibility Level” dan gewijzigd?
Na uitgebreide tests! De best-practice is om een kopie van de database op een testmachine te plaatsen en eerst daar deze instelling naar de hoogste versie te brengen om vervolgens alle relevante query’s en andere processen op de database te testen. Vervolgens kunnen op deze database dan de nodige wijzigingen worden gemaakt (en opnieuw worden getest) om de wijzigingen vervolgens op een geschikt moment in productie te brengen en dan pas in productie de instelling ‘Compatibility Level’ te wijzigen.

Moet de instelling worden gewijzigd?
Nee, het moet niet, voor zolang Microsoft de huidige compatibility level ondersteunt. Of het verstandig is om het niet te doen, is een tweede. Ik kan mij voorstellen dat ook uw organisatie met de laatste inzichten en technieken wilt werken. Dan is het echt noodzakelijk om de tests uit te voeren en uiteindelijk de productie-database naar het juiste niveau te brengen.

SQL Server tabel hernoemen (sp_rename)

Denk goed na over de gevolgen van het hernoemen van tabellen in een SQL Server database!

Problemen waar ik regelmatig tegen aan loop, is dat objecten (vaak primary keys) niet in de nieuwe naamconventie zijn meegenomen. Bijvoorbeeld de tabel dbo.tblIndex wordt hernoemd naar dbo.tblIndexArchive. Echter op deze tabel staat een primary key met de naam PK_tblIndex_IndexId. Vervolgens wordt de tabel dbo.tblIndex opnieuw aangemaakt en geeft het aanmaken van de primary key een foutmelding, omdat die naam al binnen de tabel dbo.tblIndexArchive is gebruikt. Onderstaand TestLab iillustreert en verduidelijkt het probleem.

/*

Datum			: 5 januari 2024
Ontwikkelaar	: Mickel Reemer

Doel van het script:
--------------------
Inzage geven in gevolgen van het hernoemen van een tabel
zonder voldoende rekening te houden met de naamconventie
van objecten (zoals indexen) binnen die tabel.
*/

-- Verwijder de testtabellen wanneer ze aanwezig zijn
DROP TABLE IF EXISTS dbo.tblIndex;
DROP TABLE IF EXISTS dbo.tblIndexArchive;

-- Maak de tabel dbo.tblIndex aan en plaats een primary key op de tabel
CREATE TABLE dbo.tblIndex (
	IndexId		INT IDENTITY (1,1),
	IndexName	NVARCHAR(100),
	Remarks		NVARCHAR(200),
	CONSTRAINT PK_tblIndex_IndexId PRIMARY KEY CLUSTERED (IndexId)
);

-- Maak een index op de tabel dbo.tblIndex aan
CREATE INDEX tblIndex_IndexName ON dbo.tblIndex (IndexName);

-- Vul de tabel dbo.tblIndex met testrecords
INSERT INTO dbo.tblIndex (
	IndexName,
	Remarks
)
VALUES	('Index 1','Remark 1'),
		('Index 2','Remark 2'),
		('Index 3','Remark 3'),
		('Index 4','Remark 4'),
		('Index 5','Remark 5'),
		('Index 6','Remark 6'),
		('Index 7','Remark 7');

-- Hernoem de tabel dbo.tblIndex naar dbo.tblIndexArchive
EXEC sp_rename 'dbo.tblIndex', 'tblIndexArchive';

-- Maak de tabel dbo.tblIndex opnieuw aan met een primary key
CREATE TABLE dbo.tblIndex (
	IndexId		INT IDENTITY (1,1),
	IndexName	NVARCHAR(100),
	Remarks		NVARCHAR(200),
	CONSTRAINT PK_tblIndex_IndexId PRIMARY KEY CLUSTERED (IndexId)
);

/*
Het opnieuw aanmaken van de tabel geeft dus een foutmelding
omdat de naam van de primary key al in de tabel dbo.tblIndexArchive
bestaat.

Mijn advies zou zijn om eerst alle objecten binnen de tabel
dbo.tblIndexArchive te wijzigen naar de juiste naamconventie
en vervolgens pas de nieuwe tabel aan te maken.
*/

Belangrijk
Vergeet de naamconventie van de statistics niet te bekijken!