sql >> Databáze >  >> RDS >> Sqlserver

Proaktivní kontroly stavu serveru SQL, část 1:Místo na disku

S koncem roku 2014 zahajuji sérii příspěvků o proaktivních kontrolách stavu SQL Serveru na základě jednoho, který jsem napsal na začátku tohoto roku – Problémy s výkonem:První setkání. V tomto příspěvku jsem diskutoval o tom, co hledám jako první, když řeším problém s výkonem v neznámém prostředí. V této sérii příspěvků chci mluvit o tom, co hledám, když se hlásím ke svým dlouhodobým zákazníkům. Poskytujeme službu Remote DBA a jedním z našich pravidelných úkolů je měsíční „mini“ zdravotní audit jejich prostředí. Máme zavedený monitoring a obvykle pracuji na projektech, takže jsem v prostředí pravidelně. Ale jako další krok, abychom se ujistili, že nám nic nechybí, jednou měsíčně procházíme stejná data, která shromažďujeme v našem standardním zdravotním auditu, a hledáme něco neobvyklého. To by mohlo být hodně věcí, ne? Ano! Začněme tedy prostorem.

Hej, vesmír? Ano, prostor. Nebojte, dostanu se k jiným tématům. ☺

Co zkontrolovat

Proč bych začínal vesmírem? Protože je to něco, co často vidím zanedbávané, a pokud vám dojde místo na disku pro soubory databáze, budete extrémně omezeni v tom, co můžete ve své databázi dělat. Potřebujete přidat data, ale nemůžete soubor zvětšit, protože disk je plný? Litujeme, uživatelé nyní nemohou přidávat data. Z nějakého důvodu neprovádíte zálohy protokolů, takže protokol transakcí zaplňuje disk? Litujeme, nyní nemůžete upravovat žádná data. Prostor je kritický. Máme úlohy, které monitorují volné místo na disku a v souborech, ale přesto u každého auditu ověřuji následující a porovnávám hodnoty s hodnotami z předchozího měsíce:

  • Velikost každého souboru protokolu
  • Velikost každého datového souboru
  • Uvolněte místo v každém datovém souboru
  • Uvolněte místo na každém disku s databázovými soubory
  • Uvolněte místo na každém disku se záložními soubory

Růst souboru protokolu

Většina problémů, které vidím v souvislosti s místem na disku, je způsobena nárůstem souboru protokolu. K růstu obvykle dochází z jednoho ze dvou důvodů:

  • Databáze je v ÚPLNÉ obnově a zálohy protokolu transakcí se z nějakého důvodu neprovádějí
  • Někdo spustí jednu velmi rozsáhlou transakci, která zabere veškerý stávající prostor protokolu, což nutí soubor růst

Také jsem viděl, jak se soubor protokolu zvětšuje jako součást údržby indexu. U znovu sestavení je každá alokace protokolována au velkých indexů, které mohou generovat značné množství protokolu. I při pravidelných zálohách protokolu transakcí může protokol stále narůstat rychleji, než mohou probíhat zálohy. Chcete-li spravovat protokol, musíte upravit frekvenci zálohování nebo upravit metodologii údržby indexu.

Musíte určit, proč se soubor protokolu zvětšil, což může být složité, pokud jej nesledujete. Mám úlohu, která se každou hodinu spouští za účelem pořízení snímku velikosti souboru protokolu a využití:

USE [Baselines];
GO
 
IF (NOT EXISTS (SELECT * 
                 FROM INFORMATION_SCHEMA.TABLES 
                 WHERE TABLE_SCHEMA = 'dbo' 
                 AND  TABLE_NAME = 'SQLskills_TrackLogSpace'))
 
BEGIN
	CREATE TABLE [dbo].[SQLskills_TrackLogSpace](
		[DatabaseName] [VARCHAR](250) NULL,
		[LogSizeMB] [DECIMAL](38, 0) NULL,
		[LogSpaceUsed] [DECIMAL](38, 0) NULL,
		[LogStatus] [TINYINT] NULL,
		[CaptureDate] [DATETIME2](7) NULL
	) ON [PRIMARY];
 
	ALTER TABLE [dbo].[SQLskills_TrackLogSpace] ADD  DEFAULT (SYSDATETIME()) FOR [CaptureDate];
 
END
 
CREATE TABLE #LogSpace_Temp (
	DatabaseName VARCHAR(100),
	LogSizeMB DECIMAL(10,2),
	LogSpaceUsed DECIMAL(10,2),
	LogStatus VARCHAR(1)
	);
 
INSERT INTO #LogSpace_Temp EXEC('dbcc sqlperf(logspace)');
 
INSERT INTO Baselines.dbo.SQLskills_TrackLogSpace 
	(DatabaseName, LogSizeMB, LogSpaceUsed, LogStatus)
	SELECT DatabaseName, LogSizeMB, LogSpaceUsed, LogStatus
	FROM #LogSpace_Temp;
 
DROP TABLE #LogSpace_Temp;

Tyto informace používám k určení, kdy se soubor protokolu začal zvětšovat, a začnu procházet protokoly a historii úloh, abych zjistil, jaké další informace mohu najít. Růst protokolu by měl být statický – protokol by měl mít vhodnou velikost a měl by být spravován prostřednictvím záloh (pokud běží v režimu FULL recovery), a pokud soubor potřebuje být větší, musím pochopit proč a podle toho změnit jeho velikost.

Pokud řešíte tento problém a ještě jste proaktivně nesledovali události růstu souborů, možná budete stále schopni zjistit, co se stalo. Události automatického růstu zachycuje SQL Server; Aaron Bertrand z SQL Sentry o tom napsal v roce 2007 blog, kde ukazuje, jak zjistit, kdy se tyto události staly (pokud byly dostatečně nedávné, aby stále existovaly ve výchozím trasování).

Velikost a volné místo v datových souborech

Pravděpodobně jste již slyšeli, že vaše datové soubory by měly být předem dimenzovány, aby se nemusely automaticky zvětšovat. Pokud budete postupovat podle těchto pokynů, pravděpodobně jste nezažili událost, kdy datový soubor neočekávaně naroste. Pokud však své datové soubory nespravujete, pravděpodobně k růstu dochází pravidelně – ať už si to uvědomujete nebo ne (zvláště s výchozím nastavením růstu 10 % a 1 MB).

Existuje trik na předurčení velikosti datových souborů – nechcete mít příliš velkou velikost databáze, protože pamatujte, že pokud obnovujete, řekněme, prostředí dev nebo QA, soubory mají stejnou velikost, i když jsou nejsou plné dat. Ale stále chcete ručně řídit růst. Zjišťuji, že správci databází to mají s novými databázemi nejtěžší. Firemní uživatelé nemají ponětí o míře růstu a množství dat, které se přidává, a tato databáze je ve vašem prostředí trochu volné dělo. Těmto souborům musíte věnovat velkou pozornost, dokud nezjistíte velikost a očekávaný růst. Používám dotaz, který poskytuje informace o velikosti a volném místě:

SELECT 
    [file_id] AS [File ID],
    [type] AS [File Type],
    substring([physical_name],1,1) AS [Drive],
    [name] AS [Logical Name],
    [physical_name] AS [Physical Name],
    CAST([size] as DECIMAL(38,0))/128. AS [File Size MB], 
    CAST(FILEPROPERTY([name],'SpaceUsed') AS DECIMAL(38,0))/128. AS [Space Used MB], 
    (CAST([size] AS DECIMAL(38,0))/128) - (CAST(FILEPROPERTY([name],'SpaceUsed') AS DECIMAL(38,0))/128.) AS [Free Space],
    [max_size] AS [Max Size],
    [is_percent_growth] AS [Percent Growth Enabled],
    [growth] AS [Growth Rate],
    SYSDATETIME() AS [Current Date]
FROM sys.database_files;

Každý měsíc kontroluji velikost datových souborů a využitý prostor a poté se rozhodnu, zda je potřeba velikost zvětšit. Také sleduji výchozí trasování pro události růstu, protože to mi přesně říká, kdy k růstu dojde. S výjimkou nových databází mohu mít vždy náskok před automatickým růstem souborů a pracovat s ním ručně. Dobře, skoro vždy. Těsně před prázdninami v loňském roce jsem byl upozorněn IT oddělením zákazníka na nedostatek volného místa na disku (tu si ponechte pro další sekci). Nyní je oznámení založeno na prahu méně než 20 % zdarma. Tento disk měl více než 1 TB, takže při kontrole disku zbývalo asi 150 GB volného místa. Zatím to nebyla nouze, ale potřeboval jsem pochopit, kam se ten prostor poděl.

Při kontrole databázových souborů pro jednu databázi jsem viděl, že jsou plné – a předchozí měsíc měl každý soubor přes 50 GB volného místa. Poté jsem prošel velikostí tabulek a zjistil jsem, že do jedné tabulky bylo za posledních 16 dní přidáno přes 270 milionů řádků – celkem přes 100 GB dat. Ukázalo se, že došlo ke změně kódu a nový kód zaznamenával více informací, než bylo zamýšleno. Rychle jsme nastavili úlohu pro vyčištění řádků a obnovení volného místa v souborech (a opravili kód). Nemohl jsem však obnovit místo na disku – musel bych zmenšit soubory, a to nebyla možnost. Poté jsem musel určit, kolik místa na disku zbývá, a rozhodnout se, zda je to množství, které mi vyhovuje nebo ne. Moje úroveň pohodlí závisí na tom, kolik dat se za měsíc přidává – typické tempo růstu. A vím jen, kolik dat se přidává, protože sleduji využití souborů a dokážu odhadnout, kolik místa bude potřeba pro tento měsíc, pro tento rok a pro příští dva roky.

Prostor na disku

Již dříve jsem zmínil, že máme úlohy pro sledování volného místa na disku. To je založeno na procentech, nikoli na pevné částce. Mým obecným pravidlem bylo zasílat upozornění, když je volných méně než 10 % disku, ale u některých jednotek možná budete muset nastavit vyšší hodnotu. Například u disku 1 TB dostanu upozornění, když je volných méně než 100 GB. U 100GB disku dostanu upozornění, když je volných méně než 10 GB. S 20GB diskem... no, vidíte, kam tím mířím. Tento práh vás musí upozornit, než nastane problém. Pokud mám na disku, který je hostitelem souboru protokolu, pouze 10 GB volného místa, možná nebudu mít dostatek času na reakci, než se to uživatelům projeví jako problém – v závislosti na tom, jak často kontroluji volné místo a jaký je problém je.

Je velmi snadné použít xp_fixeddrives ke kontrole volného místa, ale nedoporučoval bych to, protože je to nezdokumentované a použití rozšířených uložených procedur obecně bylo zastaralé. Také neuvádí celkovou velikost každého disku a nemusí hlásit všechny typy disků, které vaše databáze mohou používat. Pokud používáte SQL Server 2008R2 SP1 nebo vyšší, můžete použít mnohem pohodlnější sys.dm_os_volume_stats k získání potřebných informací, alespoň o jednotkách, kde existují databázové soubory:

SELECT DISTINCT
  vs.volume_mount_point AS [Drive],
  vs.logical_volume_name AS [Drive Name],
  vs.total_bytes/1024/1024 AS [Drive Size MB],
  vs.available_bytes/1024/1024 AS [Drive Free Space MB]
FROM sys.master_files AS f
CROSS APPLY sys.dm_os_volume_stats(f.database_id, f.file_id) AS vs
ORDER BY vs.volume_mount_point;

Často vidím problém s místem na disku na svazcích, které hostují tempdb. Ztratil jsem počet případů, kdy jsem měl klienty s nevysvětlitelným růstem tempdb. Někdy je to jen několik GB; naposledy to bylo 200 GB. Tempdb je ošemetné zvíře – při jeho dimenzování neexistuje žádný vzorec, který by se dal dodržovat, a příliš často je umístěn na disku s malým volným místem, který nezvládne šílenou událost způsobenou začínajícím vývojářem nebo DBA. Změna velikosti datových souborů tempdb vyžaduje, abyste své pracovní vytížení provozovali v „normálním“ obchodním cyklu, abyste zjistili, jak moc využívá databázi tempdb, a podle toho ji upravte na velikost.

Nedávno jsem slyšel návrh na způsob, jak se vyhnout nedostatku místa na disku:vytvořte databázi bez dat a nastavte velikost souborů tak, aby zabíraly tolik místa, kolik chcete „vyhradit“. Pak, pokud narazíte na problém, stačí zahodit databázi a violu, máte opět volné místo. Osobně si myslím, že to vytváří všechny druhy dalších problémů a nedoporučuji to. Ale pokud máte správce úložiště, kteří neradi vidí stovky nevyužitých GB na disku, byl by to jeden způsob, jak zajistit, aby disk „vypadal“ plný. Připomíná mi to něco, co jsem slyšel od svého dobrého přítele říkat:„Když nemůžu pracovat s tebou, budu pracovat kolem tebe.“

Zálohy

Jedním z primárních úkolů DBA je ochrana dat. Zálohy jsou jednou z metod používaných k jeho ochraně, a jako takové jsou jednotky, které tyto zálohy uchovávají, nedílnou součástí života DBA. Pravděpodobně udržujete jednu nebo více záloh online, abyste je v případě potřeby okamžitě obnovili. Vaše příručka SLA a DR vám pomáhá určovat, kolik záloh máte online, a musíte zajistit, abyste měli k dispozici tento prostor. Doporučuji také nemazat staré zálohy, dokud nebude aktuální záloha úspěšně dokončena. Je příliš snadné spadnout do pasti mazání starých záloh a následného spuštění aktuální zálohy. Co se ale stane, když aktuální záloha selže? A co se stane, když použijete kompresi? Počkejte chvíli… komprimované zálohy jsou menší, že? Jsou nakonec menší. Ale věděli jste, že velikost souboru .bak obvykle začíná větší než konečná velikost? Ke změně tohoto chování můžete použít příznak trasování 3042, ale měli byste si myslet, že se zálohami potřebujete dostatek místa. Pokud má vaše záloha 100 GB a máte 3 dny online, potřebujete 300 GB na 3 dny zálohování a pak pravděpodobně zdravou částku (2x aktuální velikost databáze) zdarma pro další zálohu. Ano, to znamená, že v daný okamžik budete mít na tomto disku mnohem více než 100 GB volného místa. To je v pořádku. Je to lepší, než když úloha mazání uspěje a úloha zálohování selže a o tři dny později zjistíte, že nemáte žádné zálohy (stalo se mi to u zákazníka v předchozí práci).

Většina databází se postupem času zvětšuje, což znamená, že se zvětšují i ​​zálohy. Nezapomeňte pravidelně kontrolovat velikost záložních souborů a podle potřeby přidělovat další místo – zásada „200 GB zdarma“ pro databázi, která se rozrostla na 350 GB, nebude příliš užitečné. Pokud se požadavky na prostor změní, nezapomeňte změnit také všechna související upozornění.

Použití Poradce pro výkon

V tomto příspěvku je zahrnuto několik dotazů, které můžete použít pro monitorování prostoru, pokud potřebujete spustit svůj vlastní proces. Ale pokud náhodou máte ve svém prostředí SQL Sentry Performance Advisor, je to mnohem snazší s uživatelskými podmínkami. Ve výchozím nastavení je zahrnuto několik podmínek akcií, ale můžete si také vytvořit své vlastní.

V rámci klienta SQL Sentry otevřete Navigátor, klepněte pravým tlačítkem myši na Sdílené skupiny (globální) a vyberte Přidat vlastní podmínku → SQL Sentry. Zadejte název a popis podmínky, poté přidejte číselné srovnání a změňte typ na Dotaz úložiště. Zadejte dotaz:

SELECT MIN(FreeSpace*100.0/Size)
  FROM SQLSentry.dbo.PerformanceAnalysisDeviceLogicalDisk;

Změnit se rovná Je menší než a nastavte Explicitní hodnotu 10. Nakonec změňte Výchozí frekvenci vyhodnocování na něco méně častého než každých 10 sekund. Jednou denně nebo jednou za 12 hodin je pravděpodobně dobrá hodnota – volné místo byste neměli kontrolovat častěji než jednou denně, ale můžete jej kontrolovat, jak často chcete. Snímek obrazovky níže ukazuje konečnou konfiguraci:

Jakmile pro podmínku kliknete na uložit, budete dotázáni, zda chcete přiřadit akce pro vlastní podmínku. Možnost Odeslat do varovných kanálů je vybrána ve výchozím nastavení, ale možná budete chtít provést jiné úlohy, jako je provedení úlohy – řekněme zkopírovat staré zálohy na jiné místo (pokud je to disk s nedostatkem místa).

Jak jsem již zmínil, výchozí 10% volného místa pro všechny disky pravděpodobně není vhodné pro každý disk ve vašem prostředí. Dotaz můžete přizpůsobit pro různé instance a jednotky, například:

SELECT Alert = MAX(CASE 
  WHEN Name = N'C:' AND [FreeSpace%] < 10 THEN 1
  WHEN Name = N'S:' AND [FreeSpace%] < 25 THEN 1
  WHEN Name = N'T:' AND [FreeSpace%] < 20 THEN 1
  ELSE 0 END)
FROM 
(
  SELECT 
	d.Name, 
	d.FreeSpace * 100.0/d.Size AS [FreeSpace%]
  FROM SQLSentry.dbo.PerformanceAnalysisDeviceLogicalDisk AS d
  INNER JOIN SQLSentry.dbo.EventSourceConnection AS c
  ON d.DeviceID = c.DeviceID
  WHERE c.ObjectName = N'HANK\SQL2012' -- replace with your server/instance
) AS s;

Tento dotaz můžete upravit a rozšířit podle potřeby pro vaše prostředí a poté odpovídajícím způsobem změnit srovnání v podmínce (v zásadě vyhodnocením na hodnotu true, pokud je výsledek někdy 1):

Pokud chcete vidět Performance Advisor v akci, stáhněte si zkušební verzi.

Pamatujte, že pro obě tyto podmínky budete upozorněni pouze jednou, a to i v případě, že více jednotek klesne pod vaši prahovou hodnotu. Ve složitých prostředích se možná budete chtít přiklonit k většímu počtu specifičtějších podmínek, abyste zajistili flexibilnější a přizpůsobené upozornění, spíše než méně „chytlavých“ podmínek.

Shrnutí

V prostředí SQL Server je mnoho kritických součástí a místo na disku je třeba proaktivně monitorovat a udržovat. S trochou plánování je to snadné a zmírňuje to mnoho neznámých a reaktivní řešení problémů. Ať už používáte vlastní skripty nebo nástroj třetí strany, zajistit dostatek volného místa pro databázové soubory a zálohy je problém, který je snadno řešitelný a stojí za námahu.


  1. MySQL Workbench:Jak udržet připojení naživu

  2. Analyzujte datum v MySQL

  3. 5 velmi častých chyb návrhu SQL dotazů, kterým se za každou cenu vyhnout

  4. JSON_REPLACE() – Nahradí hodnoty v dokumentu JSON v MySQL