MS SQL Server: BACKUP steroides

Oodake! Oodake! TĂ”si, see ei ole jĂ€rjekordne artikkel SQL Serveri varukoopia tĂŒĂŒpide kohta. Ma ei hakka isegi rÀÀkima taastemudelite erinevustest ja sellest, kuidas vĂ”idelda suurenenud 'logiga'.

VÔimalik (ainult vÔimalik), et pÀrast selle postituse lugemist suudate teha nii, et varukoopia, mida te teie standardsed vahendid teevad, toimub homme öösel umbes 1,5 korda kiiremini. Ja ainult seetÔttu, et kasutate veidi rohkem BACKUP DATABASE parameetreid.

Kui postituse sisu oli teile ilmne — vabandust. Lugesin kĂ”ike, millele Google 'habr sql server backup' fraasi tĂ€nu jĂ”udis, ja ĂŒkski artikkel ei maininud, et varukoopia ajal saab kuidagi parameetritega mĂ”jutada.

Tahan kohe tÀhelepanu juhtida Aleksandr Gladƥenko kommentaarile (@mssqlhelp):

Ärge kunagi muutke parameetreid BUFFERCOUNT, BLOCKSIZE, MAXTRANSFERSIZE tootmises. Need on loodud ainult sarnaste artiklite kirjutamiseks. Tegelikult kohtate mĂ€luprobleemidega vĂ”rreldes halbu aegu.

Muidugi oleks lahe olla kÔige targem ja jagada eksklusiivset sisu, kuid paraku pole see nii. On olemas nii inglise- kui ka venekeelseid artikleid/postitusi (ma alati segadusse jÀÀn, kuidas neid Ôigesti nimetada), mis kÀsitlevad seda teemat. Siin on mÔned, mis minu ette sattusid: kord, kaks, kolm (sql.ru-s).

Nii et alustuseks jagan mÔned kÀrbitud sintaksit BACKUP-ist MSDN-ilt (muide, seal ma juba kirjutasin BACKUP DATABASE-st, kuid kÔik see kehtib ka tehingute ajakirja varundamise ja erineva varukoopia kohta, ehkki vÀhem ilmsete mÔjude korral):

BACKUP DATABASE { database_name | @database_name_var }
  TO  [ ,...n ]
  
  [ WITH { 
           |  [ ,...n ] } ]
[;]

 [ ,...n ]::=

--Meedia komplekti valikud
 
 | BLOCKSIZE = { blocksize | @blocksize_variable }

--Andmete ĂŒlekande valikud
   BUFFERCOUNT = { buffercount | @buffercount_variable }
 | MAXTRANSFERSIZE = { maxtransfersize | @maxtransfersize_variable }

— tĂ€hendab, et seal oli midagi, aga ma eemaldasin selle, kuna see ei puuduta hetkel teemat.

Kuidas te tavaliselt varukoopiaid teete? Kuidas «Ôpetatakse» varukoopiaid tegema miljardites artiklites? Üldiselt, kui peaks olema vaja ĂŒhekordselt teha varukoopia mĂ”nest mitte eriti suurest andmebaasist, siis kirjutaksin automaatselt midagi sellist:

VARU TABEL smth
KETTLE = 'D:Backupsmth.bak'
KOOS STATS = 10, CHECKSUM, COMPRESSION, COPY_ONLY;
-- noh, CHECKSUM on kohe kirja pandud ainult selleks, et targem vÀlja nÀha

Ja tÔenÀoliselt on siin nimetatud umbes 75-90% kÔigist parameetritest, mida tavaliselt mainitakse varukoopiate artiklites. Seal on INIT, SKIP jne. Kas olete MSDN-is kÀinud? Kas te nÀgite, et seal on poolteist ekraani valikuid? Mina nÀgin ka


TĂ”enĂ€oliselt olete juba aru saanud, et edasi rÀÀgime kolmest parameetrist, mis jĂ€id esimesesse koodiplokki — BLOCKSIZE, BUFFERCOUNT ja MAXTRANSFERSIZE. Siin on nende kirjeldused MSDN-ist:

BLOCKSIZE = { blocksize | @ blocksize_variable } — nĂ€itab fĂŒĂŒsilise bloki suurust baitides. Toetatakse suurusi 512, 1024, 2048, 4096, 8192, 16 384, 32 768 ja 65 536 baiti (64 KB). VaikevÀÀrtus on 65 536 lintseadmest ja 512 muude seadmete jaoks. Tavaliselt ei ole selle parameetri seadmine vajalik, kuna BACKUP kĂ€sk automaatselt valib seadme jaoks sobiva ploki suuruse. Bloki suuruse selge seadmine ĂŒletab automaatse ploki suuruse valimise.

BUFFERCOUNT = { buffercount | @ buffercount_variable } — mÀÀrab sisendi ja vĂ€ljundi puhverfailide koguarvu, mida kasutatakse varundamisoperatsiooni jaoks. VĂ”ib mĂ€rkida mis tahes tĂ€isarvu positiivset vÀÀrtust, kuid liiga suur puhverfailide arv vĂ”ib pĂ”hjustada mĂ€lu puudumise tĂ”rke, kuna Sqlservr.exe protsessis vĂ”ib tekkida liigne virtuaalne aadressiruum.

Puhvri kasutatud kogus ruumi mÀÀratakse jÀrgmise valemi jÀrgi: BUFFERCOUNT * MAXTRANSFERSIZE.

MAXTRANSFERSIZE = { maxtransfersize | @ maxtransfersize_variable } nÀitab maksimaalset andmepaketi suurust baitides andmete vahetamiseks SQL Serveri ja varundusmedia vahel. Toetatakse vÀÀrtusi, mis on jagatavad 65 536 baitiga (64 KB), kuni 4 194 304 baitini (4 MB).

Ma ĂŒtlen ausalt, et ma olen seda juba varem lugenud, aga ma ei arvanud kunagi, millist mĂ”ju nad jĂ”udlusele avaldada vĂ”ivad. Veelgi enam, ilmselt tuleb mul teha omamoodi 'vĂ€lja tulek' ja tunnistada, et isegi praegu ei saa ma tĂ€ielikult aru, mida tĂ€pselt nad teevad. TĂ”enĂ€oliselt peaksin natuke rohkem lugema puhverdatud sisend-vĂ€ljundi ja kĂ”vaketta töö kohta. Kunagi teen seda, kuid praegu vĂ”in lihtsalt kirjutada skripti, mis testib, kuidas need vÀÀrtused mĂ”jutavad varukoopia tegemise kiirus.

Loodud on vÀike andmebaas, mille suurus on umbes 10 GB, mis on salvestatud SSD-le, ja varukoopiate kataloog on HDD-l.

Loon ajutise tabeli tulemuste salvestamiseks (kuigi mul on see mitte ajutine, et saaksin tulemusi lÀhemalt uurida, aga te otsustage ise):

DROP TABLE IF EXISTS ##bt_results; 

CREATE TABLE ##bt_results (
    id              int IDENTITY (1, 1) PRIMARY KEY,
    start_date      datetime NOT NULL,
    finish_date     datetime NOT NULL,
    backup_size     bigint NOT NULL,
    compressed_size bigint,
    block_size      int,
    buffer_count    int,
    transfer_size   int
);

Skripti tööpĂ”himĂ”te on lihtne — pesas tsĂŒklid, millest igaĂŒks muudab ĂŒhe parameetri vÀÀrtust, edastan need parameetrid BACKUP kĂ€sule, salvestan viimase kirje ajaloost msdb.dbo.backupset, kustutan varukoopia faili ja jĂ€rgmine iteratsioon. Kuna varukoopia teostamise andmed saadakse backupset'ist, kaotame natuke tĂ€psust (seal ei ole sekundimurde), kuid me saame hakkama.

Esiteks tuleb lubada xp_cmdshelli kasutamine, et varukoopiaid kustutada (Ă€rge unustage hiljem seda vĂ€lja lĂŒlitada, kui see teile ei ole vajalik):

EXEC sp_configure 'show advanced options', 1;  
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
EXEC sp_configure 'show advanced options', 0;  
GO

Noh ja, tegelikult:

DEKLARE @tmplt AS nvarchar(max) = N'
BACKUP DATABASE [bt]
TO DISK = ''D:SQLServerbackupbt.bak''
WITH 
    COMPRESSION,
    BLOCKSIZE = {bs},
    BUFFERCOUNT = {bc},
    MAXTRANSFERSIZE = {ts}';

DEKLARE @sql AS nvarchar(max);

/* BLOCKSIZE vÀÀrtused */
DEKLARE @bs     int = 4096, 
        @max_bs int = 65536;

/* BUFFERCOUNT vÀÀrtused */
DEKLARE @bc     int = 7,
        @min_bc int = 7,
        @max_bc int = 800;

/* MAXTRANSFERSIZE vÀÀrtused */
DEKLARE @ts     int = 524288,   --512KB, vaikimisi = 1024KB
        @min_ts int = 524288,
        @max_ts int = 4194304;  --4MB

SELECT TOP 1 
    @bs = COALESCE (block_size, 4096), 
    @bc = COALESCE (buffer_count, 7), 
    @ts = COALESCE (transfer_size, 524288)
FROM ##bt_results
ORDER BY id DESC;

WHILE (@bs <= @max_bs)
BEGIN
    WHILE (@bc <= @max_bc)
    BEGIN       
        WHILE (@ts <= @max_ts)
        BEGIN
            SET @sql = REPLACE (REPLACE (REPLACE(@tmplt, N'{bs}', CAST(@bs AS nvarchar(50))), N'{bc}', CAST (@bc AS nvarchar(50))), N'{ts}', CAST (@ts AS nvarchar(50)));

            EXEC (@sql);

            INSERT INTO ##bt_results (start_date, finish_date, backup_size, compressed_size, block_size, buffer_count, transfer_size)
            SELECT TOP 1 backup_start_date, backup_finish_date, backup_size, compressed_backup_size,  @bs, @bc, @ts 
            FROM msdb.dbo.backupset
            ORDER BY backup_set_id DESC;

            EXEC xp_cmdshell 'del "D:SQLServerbackupbt.bak"', no_output;

            SET @ts += @ts;
        END
        
        SET @bc += @bc;
        SET @ts = @min_ts;

        WAITFOR DELAY '00:00:05';
    END

    SET @bs += @bs;
    SET @bc = @min_bc;
    SET @ts = @min_ts;
END

Kui teil on kĂŒsimusi selle kohta, mis siin toimub, kirjutage kommentaaridesse vĂ”i isiklikult. Praegu rÀÀgin ainult parameetritest, mida lisan BACKUP DATABASE-i.

BLOCKSIZE jaoks on meil 'suletud' vÀÀrtuste loetelu, ning minul ei olnud varukoopiat BLOCKSIZE < 4KB. MAXTRANSFERSIZE vĂ”ib olla ĂŒkskĂ”ik milline arv, mis on korrutis 64KB — alates 64KB kuni 4MB. Minu sĂŒsteemis on vaikimisi 1024KB, mina kasutasin 512 — 1024 — 2048 — 4096.

Raskem oli BUFFERCOUNT'iga — see vĂ”ib olla ĂŒkskĂ”ik positiivne number, kuid lingil on kirjas kuidas seda arvutatakse BACKUP DATABASE'is ja millised on suured vÀÀrtused ohtlikud. Seal on kirjas, kuidas saada teavet selle kohta, millise BUFFERCOUNT'iga varukoopia tegelikult tehakse — minul on see 7. Seda ei olnud mĂ”tet vĂ€hendada, kuna ĂŒlemine piir leiti katse-eksituse meetodil — BUFFERCOUNT = 896 ja MAXTRANSFERSIZE = 4194304 korral kukkus varukoopia tĂ”rkega (millest on juttu ĂŒlaltoodud lingil):

Msg 3013, Level 16, State 1, Line 7 BACKUP DATABASE lÔpetab tavapÀrase töö.

Msg 701, Level 17, State 123, Line 7 Ressursside paigutuses 'default' ei ole piisavalt sĂŒsteemi mĂ€lu, et seda pĂ€ringut kĂ€ivitada.

VĂ”rdluseks, kĂ”igepealt nĂ€itan tulemusi varukoopia tegemisel, ilma parameetreid ĂŒldse nĂ€itamata:

BACKUP DATABASE [bt]
TO DISK = 'D:SQLServerbackupbt.bak'
WITH COMPRESSION;

Noh, varukoopia ja varukoopia:

Töötles 1070072 lehte andmebaasi 'bt' jaoks, fail 'bt' failil 1.

Töötles 2 lehte andmebaasi 'bt', fail 'bt_log' failil 1.

BACKUP DATABASE töötles edukalt 1070074 lehte 53.171 sekundiga (157.227 MB/sec).

Kogu skript, mis testib parameetreid, töötas paar tunni jooksul, kÔik mÔÔtmised on Google'i tabelis. Kuid siin on valik kolme parima tööaja tulemuste kohta (ma proovisin teha kena graafiku, kuid postituses tuleb leppida tabeliga, ja kommentaarides) @mixsture lisatud vÀga Àgedad graafikud).

SELECT TOP 7 WITH TIES 
    compressed_size, 
    block_size, 
    buffer_count, 
    transfer_size,
    DATEDIFF(SECOND, start_date, finish_date) AS backup_time_sec
FROM ##bt_results
ORDER BY backup_time_sec ASC;

MS SQL Server: BACKUP steroides

TÀhtis mÀrkusele, kohe vÀga oluline mÀrkus @mixsture kohast kommentaarist:

saab kindlalt öelda, et seos parameetrite ja varukoopia kiirus vahel nende vÀÀrtuste juures on juhuslik, mingit mustrit ei ole. Kuid kÔrvalejÀÀmine vaikimisi parameetritest on ilmselt tulemust hÀsti mÔjutanud

St. ainult standardsete BACKUP parameetrite juhtimise tĂ”ttu saavutati varukoopia tegemise ajal kokkuhoid 2 korda: 26 sekundit, vĂ”rreldes 53-ga alguses. Ja see pole ju halb, eks? Kuid tuleks vaatama, mis taastamisega juhtub. Ja Ă€kki nĂŒĂŒd taastub see 4 korda kauem?

Alustuseks mÔÔdame, kui kaua varukoopia taastamine toimub vaikimisi seadistustega:

RESTORE DATABASE [bt]
FROM DISK = 'D:SQLServerbackupbt.bak'
WITH REPLACE, RECOVERY;

Noh, selle teate te ise, seal on tee, replace- ei replace, recovery - ei recovery. Ja minul kÀib see nii:

Töötles 1070072 lehte andmebaasi 'bt' jaoks, fail 'bt' failil 1.

Töötles 2 lehte andmebaasi 'bt', fail 'bt_log' failil 1.

ANDMEBAASI TAASLOOMINE töötas edukalt 1070074 lehe taastamisega 40,752 sekundiga (205,141 MB/sec).

NĂŒĂŒd proovin taastada varukoopiaid, mille BLOCKSIZE, BUFFERCOUNT ja MAXTRANSFERSIZE on muudetud.

BLOCKSIZE = 16384, BUFFERCOUNT = 224, MAXTRANSFERSIZE = 4194304

ANDMEBAASI TAASLOOMINE töötas edukalt 1070074 lehe taastamisega 32,283 sekundiga (258,958 MB/sec).

BLOCKSIZE = 4096, BUFFERCOUNT = 448, MAXTRANSFERSIZE = 4194304

ANDMEBAASI TAASLOOMINE töötas edukalt 1070074 lehe taastamisega 32,682 sekundiga (255,796 MB/sec).

BLOCKSIZE = 16384, BUFFERCOUNT = 448, MAXTRANSFERSIZE = 2097152

ANDMEBAASI TAASLOOMINE töötas edukalt 1070074 lehe taastamisega 32,091 sekundiga (260,507 MB/sec).

BLOCKSIZE = 4096, BUFFERCOUNT = 56, MAXTRANSFERSIZE = 4194304

ANDMEBAASI TAASLOOMINE töötas edukalt 1070074 lehe taastamisega 32,401 sekundiga (258,015 MB/sec).

ANDMEBAASI TAASLOOMISE juhised ei muutu taastamisel, neid parameetreid ei tĂ€psustata, SQL Server mÀÀrab need ise varukoopia pĂ”hjal. Ja on nĂ€ha, et isegi taastamise korral vĂ”ib olla kasu — praktiliselt 20% kiiremini (ausalt öeldes, ei pööranud taastamiseks palju aega, proovisin lihtsalt mĂ”nda kĂ”ige "kiiremat" varukoopiat ja veendusin, et halvenemist ei ole.).

Kuna see kohta on kirjas, siis selgitan, et siin ei ole kirjeldatud kÔigile sobivaid optimaalsete parameetreid. Oma parimad parameetrid saate te ainult testimisega. Mina sain sellised tulemused, te saate teised. Aga te nÀete, et oma varukoopiad vÔib "hÀÀlestada" ja need vÔivad tÔeliselt kiiremini tekkida ja taastuda.

Soovitan tungivalt lugeda kogu dokumentatsiooni, sest just teie sĂŒsteemile vĂ”ivad olla erilised nĂŒansid.

Kuna alustasin varukoopiate kirjutamist, soovin kohe rÀÀkida veel ĂŒhest „optimeerimisest”, mis on sagedamini esinev kui parameetrite „hÀÀlestamine” (nii nagu ma aru saan, kasutab seda vĂ€hemalt osa varundusutiliitidest, vĂ”ib-olla koos varasemalt kirjeldatud parameetritega), kuid HabrĂ© pole sellest veel juttu olnud.

Kui vaadata dokumentatsiooni teist rida, kohe BACKUP DATABASE'i all, nÀeme me:

TO  [, ...n]

Kuidas arvatakse, et juhtub, kui mÀÀrata mitu backup_device'i? SĂŒntees lubab seda. Ja tulemuseks on vĂ€ga huvitav asi - varukoopia lihtsalt «jagunen» mitme seadme vahel. See tĂ€hendab, et iga «seade» eraldi on kasutult, kui kaotame ĂŒhe, kaotame kogu varukoopia. Aga kuidas selline jagunemine mĂ”jutab varundamise kiirus?

Proovime varundada kahele «seadmest», mis asuvad ĂŒksteise kĂ”rval samas kaustas:

BACKUP DATABASE [bt]
TO 
    DISK = 'D:SQLServerbackupbt1.bak',
    DISK = 'D:SQLServerbackupbt2.bak'   
WITH COMPRESSION;

Issand jumal, mida see kĂŒll teeb?

Töötles 1070072 lehte andmebaasi 'bt' jaoks, fail 'bt' failil 1.

Töödeldud 2 lehte andmebaasist ‘bt’, fail ‘btlog’ failil 1.

BACKUP DATABASE successfully processed 1070074 pages in 40.092 seconds (208.519 MB/sec).

Varukoopia tehti 25% kiiremini lihtsalt tĂŒhja koha pealt? Mis juhtub, kui veel paar seadet lisada?

BACKUP DATABASE [bt]
TO 
    DISK = 'D:SQLServerbackupbt1.bak',
    DISK = 'D:SQLServerbackupbt2.bak',
    DISK = 'D:SQLServerbackupbt3.bak',
    DISK = 'D:SQLServerbackupbt4.bak'
WITH COMPRESSION;

BACKUP DATABASE successfully processed 1070074 pages in 34.234 seconds (244.200 MB/sec).

KokkuvĂ”ttes on kasum umbes 35% varukoopia tegemise ajast, kuna varukoopia kirjutatakse kohe nelja faili ĂŒhele kettale. Kontrollisin suuremat hulka — minu sĂŒlearvutis ei olnud kasu, optimaalne on neli seadet. Teie jaoks — ei tea, tuleb kontrollida. Ja muide, kui need seadmed on tĂ”epoolest erinevad kettad, siis Ă”nnitleme, kasu peaks olema veelgi suurem.

NĂŒĂŒd rÀÀgime, kuidas seda rÔÔmu taastada. Selleks peab taastamis kĂ€su muutma ja kĂ”ik seadmed loetlema:

RESTORE DATABASE [bt]
FROM 
    DISK = 'D:SQLServerbackupbt1.bak',
    DISK = 'D:SQLServerbackupbt2.bak',
    DISK = 'D:SQLServerbackupbt3.bak',
    DISK = 'D:SQLServerbackupbt4.bak'
WITH REPLACE, RECOVERY;

RESTORE DATABASE successfully processed 1070074 pages in 38.027 seconds (219.842 MB/sec).

Veidi kiiremini, kuid kuskil kĂ”rval, mitte oluliselt. Üldiselt, varukoopia tehakse kiiremini ja taastatakse samamoodi — kas see on edu? Minu arvates on see tĂ€iesti korralik edu. See on oluline, seega kordan veel kord — kui te kaotate vĂ€hemalt ĂŒhe neist failidest — kaotate kogu varukoopia.

Kui vaadata logis teavet varunduse kohta, mida vĂ€ljastatakse Trace Flag 3213 ja 3605 abil, siis vĂ”ib tĂ”deda, et mitme seadme varundamisel suureneb vĂ€hemalt BUFFERCOUNTi arv. Arvatavasti saab proovida leida optimaalsemad seaded ka BUFFERCOUNTi, BLOCKSIZE'i ja MAXTRANSFERSIZE'i jaoks, kuid mul ei Ă”nnestunud seda kohe teha, ja pĂ€rast katsetamist erinevate failide arvuga olin laisk. Ja kahju on ketastest. Kui soovite korraldada sellist testimist enda juures, pole skripti ĂŒmbertegemine keeruline.

LĂ”puks rÀÀgime hinnast. Kui varundus toimub paralleelselt kasutajate tööga, tuleb testimisele lĂ€heneda vĂ€ga vastutustundlikult, sest kui varundus toimub kiiremini, koormatakse kettaid rohkem, protsessori koormus suureneb (peab ju seda kĂ”ike veel ka jooksvalt kokku suruma), vastavalt vĂ€heneb sĂŒsteemi ĂŒldine reageerimisvĂ”ime.

Naerud-naerudeks, aga ma mĂ”istan hĂ€sti, et ma ei teinud mingeid ilmutusi. Ülaltoodud on lihtsalt nĂ€ide sellest, kuidas saab valida optimaalseid seadeid varunduste tegemiseks.

Pidage meeles, et kĂ”ik, mida te teete — on teie enda risk. Kontrollige oma varukoopiaid ja Ă€rge unustage DBCC CHECKDB-d.

Allikas: habr.com

Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid đŸ”„ Osta usaldusvÀÀrne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster