Vedlikehold av SQL Server: CHECKDB, statistikk og indekser

SQL Server er robust, men ikke vedlikeholdsfri. Uten jevnlig vedlikehold kan korrupsjon gå uoppdaget i måneder, utdatert statistikk gi plutselig trege spørringer, og diskene fylles opp av backuphistorikk og loggfiler. Denne guiden går gjennom hva som faktisk må gjøres, hvor ofte, og hvordan du automatiserer det – med gratisverktøy som har blitt de facto standard.

Kort fortalt
  • De fire faste oppgavene: backup, integritetssjekk (DBCC CHECKDB), statistikk og indeksvedlikehold.
  • Bruk Ola Hallengrens vedlikeholdsløsning eller dbatools fremfor å skrive alt selv.
  • Statistikk er viktigere enn fragmentering på moderne lagring.
  • Sett opp varsler for alvorlige feil og feilede jobber – vedlikehold som feiler i stillhet, er verre enn ingen.
  • Hold SQL Server oppdatert med kumulative oppdateringer.

Oversikt: hva og hvor ofte

OppgaveTypisk frekvensHvorfor
FullbackupDaglig eller ukentligGrunnlaget for gjenoppretting.
Differensiell backupDaglig (når full er ukentlig)Raskere gjenoppretting.
LoggbackupHvert 5.–15. minuttGjenoppretting til tidspunkt og kontroll på loggen.
DBCC CHECKDBUkentlig (minst)Oppdager korrupsjon før den sprer seg til backupene.
StatistikkoppdateringDaglig eller ukentligGode kjøreplaner forutsetter riktig statistikk.
IndeksvedlikeholdUkentligHolder sidetettheten oppe.
Opprydding i historikkUkentligBackup- og jobbhistorikk i msdb og gamle backupfiler.
Kumulative oppdateringerMånedlig til kvartalsvisFeilrettinger og sikkerhet.

Backup er beskrevet i detalj i guiden om backup og gjenoppretting. Resten av denne guiden handler om de andre oppgavene.

Integritetssjekk med DBCC CHECKDB

Korrupsjon skyldes nesten alltid feil under SQL Server – i diskkontrollere, lagringssystemer, drivere eller minne. SQL Server oppdager mange feil når en side leses, men sider som sjelden leses kan være skadet lenge uten at noen merker det. Til slutt er skaden med i alle backupene du har.

-- Full sjekk av logisk og fysisk integritet
DBCC CHECKDB (N'Salg') WITH NO_INFOMSGS, ALL_ERRORMSGS;

-- Raskere variant for store databaser: bare fysisk struktur og kontrollsummer
DBCC CHECKDB (N'Salg') WITH PHYSICAL_ONLY, NO_INFOMSGS;
  • CHECKDB er I/O- og CPU-krevende. Kjør den utenom de travleste periodene.
  • For svært store databaser kan du veksle mellom PHYSICAL_ONLY i hverdagen og full sjekk i helgene, eller kjøre full sjekk på en gjenopprettet kopi på en annen server. Det tester samtidig at backupene virker.
  • Sett databasens Page Verify til CHECKSUM (standard for nye databaser), slik at SQL Server kan oppdage skadde sider ved lesing.
Finner CHECKDB feil: Ikke kjør REPAIR_ALLOW_DATA_LOSS i panikk. Navnet betyr akkurat det det sier. Ta vare på feilmeldingene, sjekk maskinvare og lagring, og vurder om du kan gjenopprette fra en backup som er fri for feil. Reparasjon er siste utvei.

Statistikk

Optimalisereren bruker statistikk – histogrammer over verdifordelingen i kolonner og indekser – til å anslå hvor mange rader hvert steg i en spørring vil gi. Disse anslagene bestemmer om den velger indekssøk eller full lesing, nested loops eller hash join, og hvor mye minne spørringen får. Utdatert statistikk er en av de vanligste årsakene til at en spørring plutselig blir treg.

SQL Server oppdaterer statistikk automatisk (Auto Update Statistics) når en viss andel av radene er endret. For store tabeller kan det likevel ta lang tid før terskelen nås, og de automatiske oppdateringene bruker et lite utvalg av radene. Derfor er det vanlig å oppdatere statistikk som en planlagt jobb i tillegg:

-- Oppdater all statistikk i databasen som har endrede rader
EXEC sp_updatestats;

-- Full gjennomlesing av én tabell når utvalg gir for dårlige anslag
UPDATE STATISTICS dbo.Ordre WITH FULLSCAN;

-- Når ble statistikken sist oppdatert, og hvor mye er endret siden?
SELECT OBJECT_NAME(s.object_id) AS Tabell,
       s.name                   AS Statistikk,
       sp.last_updated,
       sp.rows,
       sp.modification_counter
FROM sys.stats AS s
CROSS APPLY sys.dm_db_stats_properties(s.object_id, s.stats_id) AS sp
WHERE OBJECTPROPERTY(s.object_id, 'IsUserTable') = 1
ORDER BY sp.modification_counter DESC;

Indeksvedlikehold

SQL Server har to måter å rydde i indekser på:

  • REORGANIZE: Sorterer og komprimerer bladnivået på plass. Alltid online, kan avbrytes uten å miste arbeidet som er gjort, men oppdaterer ikke statistikk.
  • REBUILD: Bygger indeksen på nytt. Gir best resultat og oppdaterer statistikken med full gjennomlesing, men låser tabellen med mindre du har Enterprise og bruker ONLINE = ON. Genererer mye transaksjonslogg.

Den klassiske tommelfingerregelen er å reorganisere ved 5–30 prosent fragmentering og bygge om ved over 30 prosent, og å ignorere små indekser (under ca. 1 000 sider). Regelen stammer fra spinnende disker. På moderne SSD- og SAN-lagring er det mer nyttig å se på sidetetthet (avg_page_space_used_in_percent) enn på fragmentering, og mange erfarne DBA-er bygger om langt sjeldnere enn før – men oppdaterer statistikk oftere.

SELECT OBJECT_NAME(ips.object_id)             AS Tabell,
       i.name                                 AS Indeks,
       ips.page_count,
       ips.avg_fragmentation_in_percent,
       ips.avg_page_space_used_in_percent
FROM sys.dm_db_index_physical_stats(DB_ID(), NULL, NULL, NULL, 'SAMPLED') AS ips
JOIN sys.indexes AS i ON i.object_id = ips.object_id AND i.index_id = ips.index_id
WHERE ips.page_count > 1000
ORDER BY ips.avg_fragmentation_in_percent DESC;

Ola Hallengrens vedlikeholdsløsning

Den mest brukte vedlikeholdsløsningen for SQL Server er gratis og skrevet av den svenske DBA-en Ola Hallengren. Den består av tre lagrede prosedyrer – DatabaseBackup, DatabaseIntegrityCheck og IndexOptimize – og et skript som oppretter ferdige SQL Server Agent-jobber. Løsningen håndterer nye databaser automatisk, logger til en tabell og er godt dokumentert på ola.hallengren.com. Se også vår egen gjennomgang av Ola Hallengrens Maintenance Solution.

Den enkleste måten å installere den på er med dbatools:

Install-DbaMaintenanceSolution -SqlInstance PROD01 -Database DBA `
    -BackupLocation 'B:\Backup' -CleanupTime 168 -InstallJobs

Et vanlig oppsett for indeks- og statistikkjobben:

EXECUTE dbo.IndexOptimize
    @Databases = 'USER_DATABASES',
    @FragmentationLow = NULL,
    @FragmentationMedium = 'INDEX_REORGANIZE,INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
    @FragmentationHigh = 'INDEX_REBUILD_ONLINE,INDEX_REBUILD_OFFLINE',
    @FragmentationLevel1 = 5,
    @FragmentationLevel2 = 30,
    @UpdateStatistics = 'ALL',
    @OnlyModifiedStatistics = 'Y',
    @LogToTable = 'Y';

Jobbene opprettes uten tidsplan. Husk å legge inn tidsplaner – og varsling ved feil – etter installasjonen.

Og Maintenance Plans?

De innebygde vedlikeholdsplanene i SSMS er enkle å sette opp med musen, og bedre enn ingenting. Ulempene er at de har få valgmuligheter (for eksempel bygger de gjerne om alle indekser uansett tilstand), er vanskelige å versjonskontrollere og gir lite logging. For de fleste er Ola Hallengrens løsning et bedre valg.

Opprydding

msdb lagrer historikk for alle backuper, gjenopprettinger og jobbkjøringer. Uten opprydding kan den vokse til mange gigabyte og gjøre SSMS tregt. Hallengrens løsning har egne oppryddingsjobber; ellers kan du kjøre:

DECLARE @Grense datetime = DATEADD(DAY, -60, GETDATE());
EXEC msdb.dbo.sp_delete_backuphistory @oldest_date = @Grense;
EXEC msdb.dbo.sp_purge_jobhistory @oldest_date = @Grense;

-- Start en ny fil for SQL Server-feilloggen (gjør gjerne ukentlig)
EXEC sp_cycle_errorlog;

Oppdateringer

Microsoft gir ut feilrettinger som kumulative oppdateringer (CU), omtrent annenhver måned i hovedstøtteperioden, og sikkerhetsrettinger som GDR-er. Service packs finnes ikke lenger. Hver CU inneholder alle tidligere rettinger. Anbefalingen er å holde seg på en nyere CU, teste den i et testmiljø først og installere i et vedlikeholdsvindu. Med availability groups kan du oppdatere sekundæren først, bytte rolle, og deretter oppdatere den gamle primæren – med minimal nedetid.

Følg også med på livssyklusen: hver versjon har fem års hovedstøtte og fem års utvidet støtte (kun sikkerhetsrettinger). Etter det kommer det ingen sikkerhetsoppdateringer.

Overvåking og varsling

Vedlikehold som feiler i stillhet, gir falsk trygghet. Sett opp Database Mail, en operatør (gjerne en distribusjonsliste), varsling på alle Agent-jobber, og varsler for alvorlige feil:

EXEC msdb.dbo.sp_add_operator
     @name = N'DBA', @email_address = N'dba@example.com';

-- Varsel for alvorlighetsgrad 19–25 (alvorlige feil) og I/O-feilene 823, 824 og 825
EXEC msdb.dbo.sp_add_alert @name = N'Severity 024', @severity = 24,
     @delay_between_responses = 60, @include_event_description_in = 1;
EXEC msdb.dbo.sp_add_notification @alert_name = N'Severity 024',
     @operator_name = N'DBA', @notification_method = 1;

EXEC msdb.dbo.sp_add_alert @name = N'Error 825', @message_id = 825,
     @delay_between_responses = 60, @include_event_description_in = 1;
EXEC msdb.dbo.sp_add_notification @alert_name = N'Error 825',
     @operator_name = N'DBA', @notification_method = 1;

Gjenta for alvorlighetsgrad 19–25 og feilene 823 og 824. Feil 825 er spesielt viktig: den betyr at en lesing feilet, men lyktes ved nytt forsøk – et tidlig varsel om at lagringen er i ferd med å svikte.

I tillegg bør du overvåke ledig diskplass, og gjerne også ventetyper, blokkering og jobbstatus. Gratisverktøy som sp_Blitz (fra First Responder Kit) gir en rask helsesjekk av en ukjent server.

Sjekkliste for en sunn server

  • Alle databaser har vellykket fullbackup det siste døgnet eller uken, og loggbackup de siste minuttene (for Full-modell).
  • Gjenoppretting er testet den siste måneden.
  • DBCC CHECKDB har kjørt uten feil den siste uken.
  • Statistikk- og indeksjobben kjører uten feil.
  • Ingen databaser har prosentvis autogrowth eller automatisk krymping (Auto Shrink skal være av).
  • Varsler og operatør er satt opp, og testet.
  • SQL Server kjører en støttet versjon med en nyere CU.
  • Det er minst 20 prosent ledig plass på data-, logg- og backupdiskene.

Vanlige spørsmål

Bør jeg slå på Auto Shrink?

Nei. Automatisk krymping fragmenterer indeksene kraftig og bruker ressurser på å frigjøre plass databasen bare vil ta tilbake senere. Krymp bare manuelt, unntaksvis, etter at store mengder data er slettet permanent.

Hvor lang tid tar DBCC CHECKDB?

Det avhenger av databasens størrelse, lagringen og antall kjerner. Som grov pekepinn kan du regne med minutter for databaser på noen titalls gigabyte og timer for databaser på flere terabyte. Mål det i ditt eget miljø, og planlegg deretter.

Trenger jeg vedlikehold i Azure SQL Database?

Backup, oppdateringer og integritetssjekk håndteres av Microsoft. Statistikk og indekser er fortsatt ditt ansvar, selv om automatisk tuning kan hjelpe.

Les også