# Analyse af tidsrum Hvad skete der på en instans mellem fx kl. 03 og 04 den 20. september? Siden **Analyse af tidsrum** viser det ud fra det, agenten har gemt, på samme måde som Statspack/AWR i Oracle. Åbn en instans i webbrugerfladen, og vælg **Analysér et tidsrum**. Tidspunkterne i listerne over blocking og deadlocks på instansens side er også links: de åbner tidsrummet en halv time før og efter hændelsen. Angiv fra og til (i webbrugerfladens tidszone, `SQLInsight:Web:TimeZone`), eller vælg *Seneste time*, *I nat 00–06* eller *I går*. Højst 31 dage ad gangen. **Hent som PDF** giver det samme som rapport. ## Indhold | Afsnit | Hvad | |---|---| | Belastning | Forløb af CPU (SQL Server og andre processer), batch requests og compilations pr. sekund, page life expectancy, brugerforbindelser, memory grants pending og blokerede processer | | Største ventetider | Ventetid pr. minut i tidsrummet, sammenlignet med normalen. Harmløse baggrundsventetider er udeladt | | Tungeste forespørgsler | De forespørgsler, der brugte mest CPU, tid, læsninger eller blev kørt flest gange i tidsrummet, med tekst og database | | Diskhastighed pr. drev | Læse- og skrive-IOPS, MB/s og gennemsnitlig latens pr. drev, sammenlignet med normalen (se nedenfor) | | I/O-latens pr. fil | Læsninger, skrivninger og gennemsnitlig latens pr. databasefil | | Blocking og deadlocks | Blocking-kæder over 5 sekunder (head blocker, antal blokerede, længste ventetid) og deadlocks med graf (.xdl) | | Fund | Fund, der var aktive på et tidspunkt i tidsrummet | **Normalen** er samme klokkeslæt og ugedag de 4 foregående uger (timeværdier). En ventetid markeres med rødt, når den er mindst dobbelt så høj som normalt og udgør mindst 5 % af ventetiden i tidsrummet. En måling markeres, når gennemsnittet er mindst 50 % værre end normalt (for page life expectancy: halvt så højt). Uden historik vises normalen som "–". ## Hvor langt tilbage Kun tidsrum, hvor agenten kørte og data stadig er gemt: | Data | Opbevaring (standard, `SQLInsight:Retention`) | |---|---| | Målinger hvert 5. minut: belastning, ventetider, I/O, forespørgsler | 14 dage (`RawDays`) | | Timeværdier: belastning, ventetider og diskhastighed pr. drev | 400 dage (`HourlyDays`) | | Blocking og deadlocks | 90 dage (`EventDays`) | Ligger tidsrummet længere tilbage end `RawDays`, bruges timeværdier. Det står på siden. Så er der ingen I/O pr. fil og ingen forespørgsler, men belastning og ventetider kan stadig sammenlignes. ## Diskhastighed pr. drev Agenten læser hvert 5. minut, hvor meget hver databasefil har læst og skrevet (`sys.dm_io_virtual_file_stats`: antal I/O'er, bytes og ventetid), og lægger filerne sammen pr. drev: - **IOPS** = læsninger eller skrivninger pr. sekund, **MB/s** = data pr. sekund, **latens** = gennemsnitlig ventetid pr. læsning eller skrivning, vægtet efter antal I/O'er. - Drevet kommer fra `sys.dm_os_volume_stats` (SQL Server 2008 R2 SP1 og nyere), så mount points vises rigtigt. På ældre versioner udledes det af filens sti (`D:\…` → `D:\`), og et mount point under et drevbogstav tælles da med drevet. - Det er tal set fra SQL Server: kun SQL Servers egne filer, ikke andre programmer på samme drev. - Instanssiden viser de seneste 24 timer med graf over MB/s og latens pr. drev. Fundene SQLI-IO-001 (læselatens på datafiler) og SQLI-IO-002 (skrivelatens på logfiler) gælder pr. drev, med de langsomste filer som målinger. Et drev markeres med rødt, når datafiler har over 20 ms pr. læsning, logfiler over 5 ms pr. skrivning, eller latensen er mindst dobbelt så høj som normalt. ## Tungeste forespørgsler Agenten læser `sys.dm_exec_query_stats` hvert 5. minut (collector `query-stats`, kan ændres med `SQLInsight:CollectorIntervals`) og gemmer, hvad hver forespørgsel brugte siden sidst: - Forespørgsler med samme struktur men forskellige værdier tælles som én (`query_hash`). På SQL Server 2005 er en forespørgsel en sætning i en batch. - Kun de forespørgsler, der har kørt siden sidst, og blandt dem de 50 tungeste efter CPU, tid, læsninger og antal kørsler. Teksten gemmes én gang, højst 4.000 tegn. Ingen planer. - En plan, der er kompileret om eller smidt ud af plan cache, starter forfra. Der tælles aldrig negativt. Efter en genstart af SQL Server går der én måling, før der er tal igen. - Tal er kun så præcise som plan cache: forespørgsler med `OPTION (RECOMPILE)` eller planer, der smides ud mellem to målinger, kan mangle. Rettigheden er `VIEW SERVER STATE` fra `grant-least-privilege.sql`. SQL Server 2000 har ikke DMV'en, så her er der ingen forespørgselsstatistik. **Forespørgselstekst er kundedata.** Den gemmes kun i kundens eget repository, vises kun i webbrugerfladen og i PDF'en hos kunden, og sendes aldrig til SQLInsight Hub. Se [databehandling.md](databehandling.md). ## Ventetyper: hvad venter på hvad Klik på en ventetype på instanssiden eller i analysen for at åbne `/instanser/{navn}/ventetyper/{ventetype}?fra=&til=`. Siden viser: - **Hvad betyder det?** En dansk forklaring: hvad ventetypen betyder, hvornår den er normal, typiske årsager og hvad man kan gøre, med noter for Dynamics AX hvor det er relevant (fx MAXDOP 1 ved CXPACKET). Teksterne er de samme som i ventetidsreglerne (SQLI-WAIT-*). Ventetyper uden dansk forklaring får en generel tekst med kategorien og et link til Microsofts liste. - **Udvikling**: ventetid pr. minut over tid (hvert 5. minut inden for `RawDays`, ellers timeværdier). - **Hvilke sætninger venter**: de sætninger, sessionerne ventede i, med antal stikprøver, andel, anslået ventetid (stikprøver × 15 s), gennemsnitlig ventet tid, database, et uddrag af teksten og et link til hele teksten. - For låseventetider (LCK_M_*) et link til blocking i samme tidsrum. ### Stikprøver hvert 15. sekund Ventetidsstatistikken (`sys.dm_os_wait_stats`) siger hvor meget der ventes, men ikke på hvad. Derfor tager agenten hvert 15. sekund en stikprøve af `sys.dm_exec_requests` (som Oracles ASH): for hver brugersession, der venter, gemmes ventetype, ventet tid, database, sætningens nøgle (den samme som for tungeste forespørgsler, så teksten deles) og om den er blokeret. Agentens egne sessioner (program "SQLInsight Pro…") og systemsessioner tages ikke med, og det samme gælder harmløse baggrundsventetider. - Stikprøverne summeres pr. ventetype, database og sætning og gemmes i `insight.ActiveWaitSamples` i `RawDays` (standard 14 dage). - En stikprøve er én let forespørgsel; agenten genkender instansen fra seneste fulde gennemløb og evaluerer ikke regler for stikprøverne alene. - Ventetider, der varer under 15 sekunder i alt, kan falde mellem to stikprøver. Tallene er et billede af, hvor ventetiden ligger, ikke en præcis måling. - Virker fra SQL Server 2005 (her er nøglen batch og position, fordi `query_hash` først kom i 2008). Intervallet kan ændres med `SQLInsight:CollectorIntervals:wait-sampling`. - Sætningernes tekst er kundens data og sendes aldrig til SQLInsight Hub. ## Hvad betyder målingerne? Under hver graf på instanssiden og i analysen står en vurdering i farve – **OK** (grøn), **Bemærk** (gul) eller **Reagér** (rød) – med et konkret næste skridt og et link, og en fold-ud "Hvad betyder det?" med en forklaring i almindeligt sprog. Samme vurdering står i PDF'en. Reglerne: | Måling | Bemærk | Reagér | |---|---|---| | CPU (SQL Server + andre) | Gns. over 60 % | Over 80 % i mindst 3 målinger i træk; peger på andre processer, hvis de bruger over 20 % eller mere end SQL Server | | CPU brugt af andre processer | Gns. 10 % eller mere | Over 30 % vedvarende, eller gns. 20 % og mere end SQL Server | | Page life expectancy | Laveste værdi under grænsen, et fald på over 50 % undervejs, eller max server memory ikke sat | Gennemsnit under grænsen: 300 s pr. 4 GB buffer pool (max server memory, ellers serverens hukommelse) | | SQL compilations | Over 10 % af batch requests | Over 20 % af batch requests (kun ved mindst 5 batches/s) | | Memory grants pending, blokerede processer | Over 0 kortvarigt | Over 0 i mindst 3 målinger i træk | | Brugerforbindelser | Højeste over dobbelt gennemsnit | – | | Batch requests | Altid OK: et mål for travlhed | – | | Disk, læsning fra datafiler | Over 10 ms | Over 20 ms | | Disk, skrivning til datafiler | Over 10 ms | Over 20 ms | | Disk, skrivning til log (drev kun med logfiler) | Over 5 ms | Over 15 ms | Diske vurderes kun med mindst 100 læsninger/skrivninger i perioden. Logikken ligger ét sted (`MetricAssessment`), så siden og PDF'en siger det samme. ## Langvarige operationer Hvert minut læser agenten de operationer, SQL Server viser fremskridt for (`percent_complete` i `sys.dm_exec_requests`): BACKUP, RESTORE, DBCC CHECKDB, ALTER INDEX REORGANIZE, SHRINK, ROLLBACK m.fl. med kommando, database, start, % færdig, forventet sluttid og login. De vises under **Igangværende og nylige langvarige operationer** på instanssiden og i analysen af et tidsrum, og gemmes i `RawDays`. Login er følsomt og vises kun lokalt. Agenten husker varigheden af de seneste 10 kørsler af samme kommando på samme database (kørsler under et minut tæller ikke). Kører en backup eller restore mere end dobbelt så længe som medianen (og mindst 5 minutter længere), giver det fundet **SQLI-OPS-001** (Middel). ## Aktivitet: sætninger, der kører næsten uafbrudt Kolonnen **Aktivitet** under tungeste forespørgsler er sætningens CPU-tid som andel af tidsrummet: 100 % betyder, at den har holdt én CPU-kerne beskæftiget hele tiden (over 100 % er parallelt). Reglen **SQLI-CPU-002** (Middel) ser på sætninger, der har ligget i plan cache i mindst en time og stadig kører: er deres samlede CPU-tid over 50 % af tiden i cache, bruger de i praksis en CPU-kerne konstant. Grænsen sættes med `SQLInsight:TopSql:ActivityThresholdPercent` (standard 50). SQLInsight tømmer aldrig plan cache eller ændrer noget; fundet peger kun på sætningen. ## Åbne transaktioner og lange sætninger Hvert minut ser agenten på brugertransaktioner (`sys.dm_tran_*`) og kørende sætninger (`sys.dm_exec_requests`). Agentens egne sessioner og systemsessioner tages ikke med. - **Lige nu** på instanssiden viser åbne transaktioner (alder, database, log brugt og reserveret, session, ventetype og sætning) og sætninger, der har kørt over grænsen. - **Lange og store transaktioner** i analysen af et tidsrum (og PDF'en) viser transaktioner, der var åbne mindst et minut eller holdt over 100 MB log. De gemmes i `RawDays`. - Login, vært, program og sætning er kundens data: de vises lokalt og er `[udeladt]` i API'et (`GET /api/v1/instances/{navn}/activity` og analysen). | Regel | Alvor | Hvornår | |---|---|---| | SQLI-TRAN-001 | Middel, Høj ved 6 × grænsen | En transaktion har været åben over `SQLInsight:Activity:TransactionMinutes` (standard 10 minutter) | | SQLI-TRAN-002 | Middel | En transaktion holder over `TransactionLogMegabytes` (standard 1.024 MB) log | | SQLI-REQ-001 | Middel | En brugersætning har kørt over `RequestMinutes` (standard 15 minutter). BACKUP, RESTORE og DBCC (langvarige operationer) og sætninger, der venter med vilje (WAITFOR, Service Broker), tælles ikke | ## tempdb og version store Hvert 5. minut læser agenten tempdb's plads (`tempdb.sys.dm_db_file_space_usage`: fri plads, version store, brugerobjekter og interne objekter), om datafilerne kan vokse, tælleren `Version Store Size (KB)`, de sessioner der bruger mest tempdb (`sys.dm_db_session_space_usage` og `sys.dm_db_task_space_usage`), den ældste snapshot-transaktion (`sys.dm_tran_active_snapshot_database_transactions`) og – kun når version store er over halvdelen af grænsen, fordi det kræver en gennemgang af version store – hvilke databaser der laver versionerne (`sys.dm_tran_top_version_generators`). - **tempdb lige nu** på instanssiden, og graferne "tempdb i brug" og "Version store" med forklaring og vurdering (også i analysen af et tidsrum). - API: `GET /api/v1/instances/{navn}/tempdb` (login og program er `[udeladt]`). | Regel | Alvor | Hvornår | |---|---|---| | SQLI-TEMP-001 | Middel | Version store over `SQLInsight:Tempdb:VersionStoreMegabytes` (standard 1.024 MB), eller vokset i hver af de seneste 6 målinger med mindst 256 MB i alt | | SQLI-TEMP-002 | Høj | Under 10 % fri plads, og ingen datafil kan vokse | | SQLI-TEMP-003 | Middel | En session har brugt over `SessionMegabytes` (standard 1.024 MB) tempdb i mindst 15 minutter |